@kongyo2/cards-css 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -3
- package/dist/dom.js +105 -12
- package/dist/dom.js.map +1 -1
- package/dist/holo-card.js +265 -42
- package/dist/holo-card.js.map +1 -1
- package/dist/holo-cards.css +94 -17
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/spring.js +20 -6
- package/dist/spring.js.map +1 -1
- package/dist-types/dom.d.ts +17 -1
- package/dist-types/dom.d.ts.map +1 -1
- package/dist-types/holo-card.d.ts +33 -2
- package/dist-types/holo-card.d.ts.map +1 -1
- package/dist-types/index.d.ts +3 -3
- package/dist-types/index.d.ts.map +1 -1
- package/dist-types/spring.d.ts +10 -1
- package/dist-types/spring.d.ts.map +1 -1
- package/dist-types/types.d.ts +147 -4
- package/dist-types/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/dom.ts +127 -13
- package/src/holo-card.ts +326 -47
- package/src/index.ts +15 -3
- package/src/spring.ts +47 -10
- package/src/styles/base.css +93 -4
- package/src/styles/effects/cosmos.css +9 -6
- package/src/styles/effects/glitter.css +4 -2
- package/src/styles/effects/holo.css +3 -2
- package/src/styles/effects/reverse.css +4 -3
- package/src/types.ts +152 -4
package/dist-types/types.d.ts
CHANGED
|
@@ -1,21 +1,164 @@
|
|
|
1
|
+
import type { SpringOpts } from "./spring.js";
|
|
1
2
|
export type HoloEffect = "none" | "holo" | "reverse" | "cosmos" | "glitter";
|
|
3
|
+
/**
|
|
4
|
+
* Arbitrary card content: a DOM node, or a factory that builds one from the
|
|
5
|
+
* owning document (handy for SSR / custom-element setups where `document` is
|
|
6
|
+
* only safe to touch lazily).
|
|
7
|
+
*/
|
|
8
|
+
export type HoloContent = Node | ((doc: Document) => Node);
|
|
9
|
+
/** A map of CSS custom properties to apply to an element; numbers are stringified. */
|
|
10
|
+
export type CssVars = Record<string, string | number>;
|
|
11
|
+
/**
|
|
12
|
+
* Spring tuning for a single motion target. `axes` carries independent,
|
|
13
|
+
* asymmetric dynamics per component (`x` / `y` / `o`).
|
|
14
|
+
*/
|
|
15
|
+
export type SpringTuning = SpringOpts;
|
|
16
|
+
/** Interaction & physics adjustment surface. */
|
|
17
|
+
export interface PhysicsOptions {
|
|
18
|
+
/** Tilt in degrees reached at the card edge (default ≈ 14.29). */
|
|
19
|
+
maxTilt?: number;
|
|
20
|
+
/** Independent horizontal tilt; overrides `maxTilt` for the X axis. */
|
|
21
|
+
maxTiltX?: number;
|
|
22
|
+
/** Independent vertical tilt; overrides `maxTilt` for the Y axis. */
|
|
23
|
+
maxTiltY?: number;
|
|
24
|
+
/** Multiplier on the foil/background parallax shift (default 1; 0 disables). */
|
|
25
|
+
parallax?: number;
|
|
26
|
+
/** Multiplier on the glare travel away from centre (default 1). */
|
|
27
|
+
glareRange?: number;
|
|
28
|
+
/** ms to wait after the pointer leaves before the relaxed snap-back (default 500). */
|
|
29
|
+
returnDelay?: number;
|
|
30
|
+
/** Tuning shared by the live pointer springs (rotate / glare / background). */
|
|
31
|
+
interactSpring?: SpringTuning;
|
|
32
|
+
/** Tuning shared by the popover springs (scale / translate / flip). */
|
|
33
|
+
popoverSpring?: SpringTuning;
|
|
34
|
+
/** Tuning for the relaxed snap-back applied when the pointer leaves. */
|
|
35
|
+
snapSpring?: SpringTuning;
|
|
36
|
+
/** Per-target overrides layered on top of the group tuning above. */
|
|
37
|
+
springs?: {
|
|
38
|
+
rotate?: SpringTuning;
|
|
39
|
+
glare?: SpringTuning;
|
|
40
|
+
background?: SpringTuning;
|
|
41
|
+
rotateDelta?: SpringTuning;
|
|
42
|
+
translate?: SpringTuning;
|
|
43
|
+
scale?: SpringTuning;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** Showcase (auto-animation) customisation. `true` keeps the legacy defaults. */
|
|
47
|
+
export interface ShowcaseOptions {
|
|
48
|
+
/** ms before the sweep begins (default 2000). */
|
|
49
|
+
delay?: number;
|
|
50
|
+
/** ms the sweep runs before relaxing; ignored when `loop` is set (default 4000). */
|
|
51
|
+
duration?: number;
|
|
52
|
+
/** Keep sweeping until the user interacts instead of running once (default false). */
|
|
53
|
+
loop?: boolean;
|
|
54
|
+
/** Angular step per tick — higher is faster (default 0.05). */
|
|
55
|
+
speed?: number;
|
|
56
|
+
/** Tilt amplitude in degrees (default 25). */
|
|
57
|
+
intensity?: number;
|
|
58
|
+
/** Spring tuning while the showcase runs. */
|
|
59
|
+
spring?: SpringTuning;
|
|
60
|
+
}
|
|
61
|
+
/** Fine-grained visual / effect control. Numeric fields are multipliers (1 = unchanged). */
|
|
62
|
+
export interface VisualOptions {
|
|
63
|
+
/** Foil brightness multiplier. */
|
|
64
|
+
brightness?: number;
|
|
65
|
+
/** Foil contrast multiplier. */
|
|
66
|
+
contrast?: number;
|
|
67
|
+
/** Foil saturation multiplier. */
|
|
68
|
+
saturate?: number;
|
|
69
|
+
/** Glare layer opacity multiplier. */
|
|
70
|
+
glareOpacity?: number;
|
|
71
|
+
/** Shine/foil layer opacity multiplier. */
|
|
72
|
+
shineOpacity?: number;
|
|
73
|
+
/** Foil line spacing for the glitter/cosmos foils (`--space`); a number is read as a percentage. */
|
|
74
|
+
lineSpace?: string | number;
|
|
75
|
+
/** Foil sweep angle for the glitter/cosmos foils (`--angle`); a number is read as degrees. */
|
|
76
|
+
lineAngle?: string | number;
|
|
77
|
+
/** Glitter cell size (`--glittersize`); a number is read as a percentage. */
|
|
78
|
+
glitterSize?: string | number;
|
|
79
|
+
/** Artwork object-fit (`--imgsize`, default `cover`). */
|
|
80
|
+
imageFit?: string;
|
|
81
|
+
}
|
|
82
|
+
/** Advanced mask processing. A bare string is shorthand for `{ image }`. */
|
|
83
|
+
export interface MaskOptions {
|
|
84
|
+
/** Mask image URL. */
|
|
85
|
+
image?: string;
|
|
86
|
+
/** `mask-size` (default `cover`). */
|
|
87
|
+
size?: string;
|
|
88
|
+
/** `mask-position` (default `center center`). */
|
|
89
|
+
position?: string;
|
|
90
|
+
/** `mask-repeat` (default `no-repeat`). */
|
|
91
|
+
repeat?: string;
|
|
92
|
+
/**
|
|
93
|
+
* What the mask clips:
|
|
94
|
+
* - `shine` (default) clips only the foil, as before;
|
|
95
|
+
* - `card` clips the whole card into the mask silhouette (artwork included).
|
|
96
|
+
*/
|
|
97
|
+
mode?: "shine" | "card";
|
|
98
|
+
}
|
|
99
|
+
/** An extra stacked layer between the artwork and the foil. */
|
|
100
|
+
export interface HoloLayerOptions {
|
|
101
|
+
/** Image URL painted into the layer. */
|
|
102
|
+
image?: string;
|
|
103
|
+
/** Arbitrary content for the layer (overrides `image`). */
|
|
104
|
+
content?: HoloContent;
|
|
105
|
+
/** `mix-blend-mode` for the layer (default `normal`). */
|
|
106
|
+
blend?: string;
|
|
107
|
+
/** Layer opacity 0–1 (default 1). */
|
|
108
|
+
opacity?: number;
|
|
109
|
+
/** Pointer-driven parallax depth in px; the layer drifts with the tilt (default 0). */
|
|
110
|
+
parallax?: number;
|
|
111
|
+
/** Per-layer mask image URL. */
|
|
112
|
+
mask?: string;
|
|
113
|
+
/** `background-size` when an `image` is used (default `cover`). */
|
|
114
|
+
size?: string;
|
|
115
|
+
/** `background-position` when an `image` is used (default `center`). */
|
|
116
|
+
position?: string;
|
|
117
|
+
/** Extra class names for the layer element. */
|
|
118
|
+
className?: string;
|
|
119
|
+
/** Extra CSS custom properties for the layer element. */
|
|
120
|
+
vars?: CssVars;
|
|
121
|
+
}
|
|
2
122
|
export interface HoloCardOptions {
|
|
3
123
|
effect?: HoloEffect;
|
|
4
124
|
interactive?: boolean;
|
|
5
125
|
activateOnClick?: boolean;
|
|
6
126
|
gyroscope?: boolean;
|
|
7
|
-
showcase?: boolean;
|
|
127
|
+
showcase?: boolean | ShowcaseOptions;
|
|
8
128
|
glow?: string;
|
|
9
129
|
aspectRatio?: number;
|
|
10
130
|
textureSeed?: number;
|
|
11
|
-
mask?: string;
|
|
131
|
+
mask?: string | MaskOptions;
|
|
12
132
|
foil?: string;
|
|
133
|
+
/** Interaction & physics adjustments. */
|
|
134
|
+
physics?: PhysicsOptions;
|
|
135
|
+
/** Fine-grained visual control. */
|
|
136
|
+
visual?: VisualOptions;
|
|
137
|
+
/** Extra stacked layers between the artwork and the foil. */
|
|
138
|
+
layers?: HoloLayerOptions[];
|
|
139
|
+
/** Arbitrary CSS custom properties applied to the root (for content linkage). */
|
|
140
|
+
vars?: CssVars;
|
|
13
141
|
}
|
|
14
|
-
export interface
|
|
15
|
-
image: string;
|
|
142
|
+
export interface CreateHoloCardFields extends HoloCardOptions {
|
|
16
143
|
imageAlt?: string;
|
|
17
144
|
back?: string;
|
|
18
145
|
backAlt?: string;
|
|
146
|
+
/** Foreground content above the foil — name plates, badges, live data, etc. */
|
|
147
|
+
overlay?: HoloContent;
|
|
148
|
+
/** Let the overlay receive pointer events (default false: purely decorative). */
|
|
149
|
+
overlayInteractive?: boolean;
|
|
19
150
|
className?: string;
|
|
20
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Options for `createHoloCard`. Either `image` (front artwork) or `content`
|
|
154
|
+
* (custom front content) must be supplied — both may be combined — so the card
|
|
155
|
+
* is never built blank.
|
|
156
|
+
*/
|
|
157
|
+
export type CreateHoloCardOptions = CreateHoloCardFields & ({
|
|
158
|
+
image: string;
|
|
159
|
+
content?: HoloContent;
|
|
160
|
+
} | {
|
|
161
|
+
image?: string;
|
|
162
|
+
content: HoloContent;
|
|
163
|
+
});
|
|
21
164
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE5E,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE5E;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC;AAE3D,sFAAsF;AACtF,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAEtD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC;AAEtC,gDAAgD;AAChD,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,YAAY,CAAC;IAC9B,uEAAuE;IACvE,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,wEAAwE;IACxE,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,qEAAqE;IACrE,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,YAAY,CAAC;QACtB,KAAK,CAAC,EAAE,YAAY,CAAC;QACrB,UAAU,CAAC,EAAE,YAAY,CAAC;QAC1B,WAAW,CAAC,EAAE,YAAY,CAAC;QAC3B,SAAS,CAAC,EAAE,YAAY,CAAC;QACzB,KAAK,CAAC,EAAE,YAAY,CAAC;KACtB,CAAC;CACH;AAED,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC5B,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oGAAoG;IACpG,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACzB;AAED,+DAA+D;AAC/D,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,GAAG,eAAe,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,mCAAmC;IACnC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC5B,iFAAiF;IACjF,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,oBAAoB,GACtD,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kongyo2/cards-css",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Framework-agnostic holographic trading-card effect (tilt, shine, glare, holo / reverse / cosmos / glitter) with procedurally code-generated textures.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/dom.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CreateHoloCardOptions } from "./types.js";
|
|
1
|
+
import type { CreateHoloCardOptions, CssVars, HoloContent, HoloLayerOptions, MaskOptions } from "./types.js";
|
|
2
2
|
|
|
3
3
|
export const CLASS = {
|
|
4
4
|
root: "holo-card",
|
|
@@ -7,6 +7,10 @@ export const CLASS = {
|
|
|
7
7
|
front: "holo-card__front",
|
|
8
8
|
back: "holo-card__back",
|
|
9
9
|
image: "holo-card__image",
|
|
10
|
+
content: "holo-card__content",
|
|
11
|
+
layers: "holo-card__layers",
|
|
12
|
+
layer: "holo-card__layer",
|
|
13
|
+
overlay: "holo-card__overlay",
|
|
10
14
|
shine: "holo-card__shine",
|
|
11
15
|
glare: "holo-card__glare",
|
|
12
16
|
interactive: "holo-card--interactive",
|
|
@@ -14,6 +18,8 @@ export const CLASS = {
|
|
|
14
18
|
interacting: "holo-card--interacting",
|
|
15
19
|
loading: "holo-card--loading",
|
|
16
20
|
masked: "holo-card--masked",
|
|
21
|
+
maskCard: "holo-card--mask-card",
|
|
22
|
+
overlayInteractive: "holo-card__overlay--interactive",
|
|
17
23
|
} as const;
|
|
18
24
|
|
|
19
25
|
const requireDocument = (): Document => {
|
|
@@ -23,19 +29,98 @@ const requireDocument = (): Document => {
|
|
|
23
29
|
return document;
|
|
24
30
|
};
|
|
25
31
|
|
|
32
|
+
export const applyVars = (element: HTMLElement, vars: CssVars | undefined): void => {
|
|
33
|
+
if (!vars) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
for (const [name, value] of Object.entries(vars)) {
|
|
37
|
+
const property = name.startsWith("--") ? name : `--${name}`;
|
|
38
|
+
element.style.setProperty(property, typeof value === "number" ? String(value) : value);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export interface ResolvedMask {
|
|
43
|
+
image: string | undefined;
|
|
44
|
+
size: string | undefined;
|
|
45
|
+
position: string | undefined;
|
|
46
|
+
repeat: string | undefined;
|
|
47
|
+
mode: NonNullable<MaskOptions["mode"]>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const normalizeMask = (mask: string | MaskOptions | undefined): ResolvedMask | null => {
|
|
51
|
+
if (!mask) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const opts: MaskOptions = typeof mask === "string" ? { image: mask } : mask;
|
|
55
|
+
if (!opts.image) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
image: opts.image,
|
|
60
|
+
size: opts.size,
|
|
61
|
+
position: opts.position,
|
|
62
|
+
repeat: opts.repeat,
|
|
63
|
+
mode: opts.mode ?? "shine",
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const addClasses = (element: HTMLElement, className: string | undefined): void => {
|
|
68
|
+
if (!className) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
for (const name of className.split(/\s+/).filter(Boolean)) {
|
|
72
|
+
element.classList.add(name);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const resolveContent = (doc: Document, content: HoloContent): Node =>
|
|
77
|
+
typeof content === "function" ? content(doc) : content;
|
|
78
|
+
|
|
79
|
+
export const buildLayerElement = (doc: Document, layer: HoloLayerOptions): HTMLElement => {
|
|
80
|
+
const el = doc.createElement("div");
|
|
81
|
+
el.className = CLASS.layer;
|
|
82
|
+
addClasses(el, layer.className);
|
|
83
|
+
|
|
84
|
+
if (typeof layer.blend === "string") {
|
|
85
|
+
el.style.setProperty("--layer-blend", layer.blend);
|
|
86
|
+
}
|
|
87
|
+
if (typeof layer.opacity === "number") {
|
|
88
|
+
el.style.setProperty("--layer-opacity", String(layer.opacity));
|
|
89
|
+
}
|
|
90
|
+
if (typeof layer.parallax === "number") {
|
|
91
|
+
el.style.setProperty("--layer-parallax", String(layer.parallax));
|
|
92
|
+
}
|
|
93
|
+
if (layer.mask) {
|
|
94
|
+
el.style.setProperty("--layer-mask", `url(${layer.mask})`);
|
|
95
|
+
el.classList.add(`${CLASS.layer}--masked`);
|
|
96
|
+
}
|
|
97
|
+
if (layer.image) {
|
|
98
|
+
el.style.setProperty("--layer-image", `url(${layer.image})`);
|
|
99
|
+
el.style.setProperty("--layer-size", layer.size ?? "cover");
|
|
100
|
+
el.style.setProperty("--layer-position", layer.position ?? "center");
|
|
101
|
+
}
|
|
102
|
+
applyVars(el, layer.vars);
|
|
103
|
+
|
|
104
|
+
if (layer.content) {
|
|
105
|
+
el.appendChild(resolveContent(doc, layer.content));
|
|
106
|
+
}
|
|
107
|
+
return el;
|
|
108
|
+
};
|
|
109
|
+
|
|
26
110
|
export const buildHoloCardElement = (options: CreateHoloCardOptions): HTMLElement => {
|
|
27
111
|
const doc = requireDocument();
|
|
28
112
|
|
|
29
113
|
const root = doc.createElement("div");
|
|
30
114
|
root.className = CLASS.root;
|
|
31
|
-
|
|
32
|
-
for (const name of options.className.split(/\s+/).filter(Boolean)) {
|
|
33
|
-
root.classList.add(name);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
115
|
+
addClasses(root, options.className);
|
|
36
116
|
root.dataset.effect = options.effect ?? "none";
|
|
37
|
-
|
|
117
|
+
|
|
118
|
+
const mask = normalizeMask(options.mask);
|
|
119
|
+
if (mask) {
|
|
38
120
|
root.classList.add(CLASS.masked);
|
|
121
|
+
if (mask.mode === "card") {
|
|
122
|
+
root.classList.add(CLASS.maskCard);
|
|
123
|
+
}
|
|
39
124
|
}
|
|
40
125
|
|
|
41
126
|
const translater = doc.createElement("div");
|
|
@@ -56,12 +141,30 @@ export const buildHoloCardElement = (options: CreateHoloCardOptions): HTMLElemen
|
|
|
56
141
|
const front = doc.createElement("div");
|
|
57
142
|
front.className = CLASS.front;
|
|
58
143
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
144
|
+
if (options.image) {
|
|
145
|
+
const image = doc.createElement("img");
|
|
146
|
+
image.className = CLASS.image;
|
|
147
|
+
image.src = options.image;
|
|
148
|
+
image.alt = options.imageAlt ?? "";
|
|
149
|
+
image.loading = "lazy";
|
|
150
|
+
front.appendChild(image);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (options.content) {
|
|
154
|
+
const content = doc.createElement("div");
|
|
155
|
+
content.className = CLASS.content;
|
|
156
|
+
content.appendChild(resolveContent(doc, options.content));
|
|
157
|
+
front.appendChild(content);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (options.layers?.length) {
|
|
161
|
+
const layers = doc.createElement("div");
|
|
162
|
+
layers.className = CLASS.layers;
|
|
163
|
+
for (const layer of options.layers) {
|
|
164
|
+
layers.appendChild(buildLayerElement(doc, layer));
|
|
165
|
+
}
|
|
166
|
+
front.appendChild(layers);
|
|
167
|
+
}
|
|
65
168
|
|
|
66
169
|
const shine = doc.createElement("div");
|
|
67
170
|
shine.className = CLASS.shine;
|
|
@@ -71,6 +174,17 @@ export const buildHoloCardElement = (options: CreateHoloCardOptions): HTMLElemen
|
|
|
71
174
|
|
|
72
175
|
front.appendChild(shine);
|
|
73
176
|
front.appendChild(glare);
|
|
177
|
+
|
|
178
|
+
if (options.overlay) {
|
|
179
|
+
const overlay = doc.createElement("div");
|
|
180
|
+
overlay.className = CLASS.overlay;
|
|
181
|
+
if (options.overlayInteractive) {
|
|
182
|
+
overlay.classList.add(CLASS.overlayInteractive);
|
|
183
|
+
}
|
|
184
|
+
overlay.appendChild(resolveContent(doc, options.overlay));
|
|
185
|
+
front.appendChild(overlay);
|
|
186
|
+
}
|
|
187
|
+
|
|
74
188
|
rotator.appendChild(front);
|
|
75
189
|
translater.appendChild(rotator);
|
|
76
190
|
root.appendChild(translater);
|