@kongyo2/cards-css 0.2.0 → 0.3.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.
@@ -58,6 +58,88 @@ export interface ShowcaseOptions {
58
58
  /** Spring tuning while the showcase runs. */
59
59
  spring?: SpringTuning;
60
60
  }
61
+ /** Built-in foil colour schemes for {@link PaletteOptions.preset}. */
62
+ export type PalettePreset = "rainbow" | "gold" | "aurora" | "ruby" | "sapphire" | "mono";
63
+ /**
64
+ * Foil colour-palette / theming. Every field maps onto the foil CSS custom
65
+ * properties, so a palette can be supplied up front or swapped at runtime with
66
+ * `card.setPalette(...)`. Colours accept any CSS colour string.
67
+ */
68
+ export interface PaletteOptions {
69
+ /** A built-in scheme used as the base; the explicit fields below override it. */
70
+ preset?: PalettePreset;
71
+ /** Holographic spectrum stops (`--sunpillar-1…6`). 1–6 colours; fewer are cycled to fill the ramp. */
72
+ sunpillars?: string[];
73
+ /** Rainbow stops for the `holo` foil sweep (`--red` / `--yellow` / `--green` / `--blue` / `--violet`). 1–5 colours, cycled. */
74
+ spectrum?: string[];
75
+ /** Ramp stops for the `cosmos` foil (`--cosmos-clr-1…6`). 1–6 colours, cycled. */
76
+ cosmos?: string[];
77
+ /** Card edge highlight colour (`--card-edge`). */
78
+ edge?: string;
79
+ /** Card back fill colour (`--card-back`). */
80
+ back?: string;
81
+ /** Card glow colour (`--card-glow`); equivalent to the top-level `glow` option. */
82
+ glow?: string;
83
+ }
84
+ /**
85
+ * Custom dynamic glare (reflected light). Supply a full `image` for total
86
+ * control, or compose the built-in pointer-tracking radial gradient from
87
+ * `shape` / `extent` / `size` / `stops`. Applies across every effect and can be
88
+ * updated at runtime with `card.setGlare(...)`.
89
+ */
90
+ export interface GlareOptions {
91
+ /**
92
+ * Full `background-image` for the glare layer, overriding the built-in
93
+ * gradient on every effect. `var(--pointer-x)` / `var(--pointer-y)` are
94
+ * available for pointer tracking.
95
+ */
96
+ image?: string;
97
+ /** Radial-gradient shape when composing the gradient (default `circle`). */
98
+ shape?: "circle" | "ellipse";
99
+ /** Radial-gradient extent keyword, e.g. `farthest-corner` / `closest-side` (default `farthest-corner`). */
100
+ extent?: string;
101
+ /** Explicit gradient size — two values imply an ellipse (e.g. `60% 40%`), a single value a circle radius (e.g. `120px`); overrides `extent` when set. */
102
+ size?: string;
103
+ /** Colour stops, e.g. `["hsla(0,0%,100%,.8) 10%", "hsla(0,0%,0%,.5) 90%"]`. */
104
+ stops?: string[];
105
+ /** `mix-blend-mode` for the glare layer. */
106
+ blend?: string;
107
+ /** Glare opacity multiplier (mirrors `visual.glareOpacity`). */
108
+ opacity?: number;
109
+ }
110
+ /**
111
+ * Physical-behaviour tuning for the device-orientation (gyroscope) response.
112
+ * Passing `true` keeps the defaults; `false` disables gyroscope tilt.
113
+ */
114
+ export interface GyroscopeOptions {
115
+ /** Master switch (default true); `false` matches `gyroscope: false`. */
116
+ enabled?: boolean;
117
+ /** Device tilt (deg) on the X axis (gamma) that reaches the full effect (default 16). Lower is more sensitive. */
118
+ rangeX?: number;
119
+ /** Device tilt (deg) on the Y axis (beta) that reaches the full effect (default 18). */
120
+ rangeY?: number;
121
+ /** Sensitivity multiplier applied to the raw tilt before clamping (default 1). */
122
+ sensitivity?: number;
123
+ /** Flip the horizontal response. */
124
+ invertX?: boolean;
125
+ /** Flip the vertical response. */
126
+ invertY?: boolean;
127
+ }
128
+ /**
129
+ * Foil 3D depth / extrusion simulation. Lifts the foil stack above the artwork
130
+ * in true 3D so it parallaxes as the card tilts, with a tilt-reactive contact
131
+ * shadow. Passing `true` enables it with the defaults.
132
+ */
133
+ export interface DepthOptions {
134
+ /** Foil extrusion height in px — how far the foil floats above the artwork (default 14). */
135
+ strength?: number;
136
+ /** Perspective in px for the card's 3D space; lower exaggerates the depth (default 600). */
137
+ perspective?: number;
138
+ /** Contact-shadow opacity beneath the lifted card, 0–1 (default 0.35). */
139
+ shadow?: number;
140
+ /** Multiplier turning each extra layer's `parallax` into Z-lift, so stacked layers extrude in depth (default 1). */
141
+ layerScale?: number;
142
+ }
61
143
  /** Fine-grained visual / effect control. Numeric fields are multipliers (1 = unchanged). */
62
144
  export interface VisualOptions {
63
145
  /** Foil brightness multiplier. */
@@ -123,13 +205,20 @@ export interface HoloCardOptions {
123
205
  effect?: HoloEffect;
124
206
  interactive?: boolean;
125
207
  activateOnClick?: boolean;
126
- gyroscope?: boolean;
208
+ /** Device-orientation tilt: `true`/`false`, or an object for physical-behaviour tuning. */
209
+ gyroscope?: boolean | GyroscopeOptions;
127
210
  showcase?: boolean | ShowcaseOptions;
128
211
  glow?: string;
129
212
  aspectRatio?: number;
130
213
  textureSeed?: number;
131
214
  mask?: string | MaskOptions;
132
215
  foil?: string;
216
+ /** Foil colour palette / theming. */
217
+ palette?: PaletteOptions;
218
+ /** Custom dynamic glare (reflected light). */
219
+ glare?: GlareOptions;
220
+ /** Foil 3D depth / extrusion: `true` for the defaults, or an object to tune it. */
221
+ depth?: boolean | DepthOptions;
133
222
  /** Interaction & physics adjustments. */
134
223
  physics?: PhysicsOptions;
135
224
  /** Fine-grained visual control. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kongyo2/cards-css",
3
- "version": "0.2.0",
3
+ "version": "0.3.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
@@ -19,6 +19,8 @@ export const CLASS = {
19
19
  loading: "holo-card--loading",
20
20
  masked: "holo-card--masked",
21
21
  maskCard: "holo-card--mask-card",
22
+ depth: "holo-card--depth",
23
+ customGlare: "holo-card--custom-glare",
22
24
  overlayInteractive: "holo-card__overlay--interactive",
23
25
  } as const;
24
26
 
@@ -39,6 +41,10 @@ export const applyVars = (element: HTMLElement, vars: CssVars | undefined): void
39
41
  }
40
42
  };
41
43
 
44
+ const CSS_STRING_UNSAFE = /[\\"\n\r\f]/g;
45
+
46
+ export const cssUrl = (value: string): string => `url("${value.replace(CSS_STRING_UNSAFE, (char) => `\\${char}`)}")`;
47
+
42
48
  export interface ResolvedMask {
43
49
  image: string | undefined;
44
50
  size: string | undefined;
@@ -91,11 +97,11 @@ export const buildLayerElement = (doc: Document, layer: HoloLayerOptions): HTMLE
91
97
  el.style.setProperty("--layer-parallax", String(layer.parallax));
92
98
  }
93
99
  if (layer.mask) {
94
- el.style.setProperty("--layer-mask", `url(${layer.mask})`);
100
+ el.style.setProperty("--layer-mask", cssUrl(layer.mask));
95
101
  el.classList.add(`${CLASS.layer}--masked`);
96
102
  }
97
103
  if (layer.image) {
98
- el.style.setProperty("--layer-image", `url(${layer.image})`);
104
+ el.style.setProperty("--layer-image", cssUrl(layer.image));
99
105
  el.style.setProperty("--layer-size", layer.size ?? "cover");
100
106
  el.style.setProperty("--layer-position", layer.position ?? "center");
101
107
  }
package/src/holo-card.ts CHANGED
@@ -1,10 +1,21 @@
1
1
  import { adjust, clamp, round } from "./math.js";
2
2
  import { Spring, type SpringSetOpts, type SpringOpts, type SpringDynamics } from "./spring.js";
3
- import { CLASS, applyVars, buildLayerElement, normalizeMask } from "./dom.js";
3
+ import { CLASS, applyVars, buildLayerElement, cssUrl, normalizeMask } from "./dom.js";
4
4
  import { getActiveCard, setActiveCard, subscribeActiveCard } from "./active-registry.js";
5
5
  import { resetBaseOrientation, subscribeOrientation, type RelativeOrientation } from "./orientation.js";
6
6
  import { generateTextures, texturesToCssVariables } from "./textures.js";
7
- import type { CssVars, HoloCardOptions, HoloLayerOptions, ShowcaseOptions, VisualOptions } from "./types.js";
7
+ import { paletteToCssVariables, PALETTE_VARIABLES } from "./palette.js";
8
+ import type {
9
+ CssVars,
10
+ DepthOptions,
11
+ GlareOptions,
12
+ GyroscopeOptions,
13
+ HoloCardOptions,
14
+ HoloLayerOptions,
15
+ PaletteOptions,
16
+ ShowcaseOptions,
17
+ VisualOptions,
18
+ } from "./types.js";
8
19
 
9
20
  const requestFrame = (cb: () => void): number =>
10
21
  typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(cb) : setTimeout(cb, 16);
@@ -102,6 +113,73 @@ const resolveShowcase = (showcase: boolean | ShowcaseOptions | undefined): Resol
102
113
  };
103
114
  };
104
115
 
116
+ interface ResolvedGyroscope {
117
+ enabled: boolean;
118
+ rangeX: number;
119
+ rangeY: number;
120
+ sensitivity: number;
121
+ invertX: boolean;
122
+ invertY: boolean;
123
+ }
124
+
125
+ const DEFAULT_GYRO_RANGE_X = 16;
126
+ const DEFAULT_GYRO_RANGE_Y = 18;
127
+
128
+ const resolveGyroscope = (gyroscope: boolean | GyroscopeOptions | undefined): ResolvedGyroscope => {
129
+ const opts: GyroscopeOptions = gyroscope && typeof gyroscope === "object" ? gyroscope : {};
130
+ const enabled = typeof gyroscope === "boolean" ? gyroscope : (opts.enabled ?? true);
131
+ return {
132
+ enabled,
133
+ rangeX: opts.rangeX ?? DEFAULT_GYRO_RANGE_X,
134
+ rangeY: opts.rangeY ?? DEFAULT_GYRO_RANGE_Y,
135
+ sensitivity: opts.sensitivity ?? 1,
136
+ invertX: opts.invertX ?? false,
137
+ invertY: opts.invertY ?? false,
138
+ };
139
+ };
140
+
141
+ interface ResolvedDepth {
142
+ enabled: boolean;
143
+ strength: number;
144
+ perspective: number;
145
+ shadow: number;
146
+ layerScale: number;
147
+ }
148
+
149
+ const resolveDepth = (depth: boolean | DepthOptions | undefined): ResolvedDepth => {
150
+ const opts: DepthOptions = depth && typeof depth === "object" ? depth : {};
151
+ return {
152
+ enabled: Boolean(depth),
153
+ strength: opts.strength ?? 14,
154
+ perspective: opts.perspective ?? 600,
155
+ shadow: opts.shadow ?? 0.35,
156
+ layerScale: opts.layerScale ?? 1,
157
+ };
158
+ };
159
+
160
+ const DEFAULT_GLARE_STOPS = ["hsla(0, 0%, 100%, 0.8) 10%", "hsla(0, 0%, 100%, 0.65) 20%", "hsla(0, 0%, 0%, 0.5) 90%"];
161
+
162
+ const composeGlareImage = (glare: GlareOptions): string | undefined => {
163
+ if (glare.image) {
164
+ return glare.image;
165
+ }
166
+ if (
167
+ glare.shape === undefined &&
168
+ glare.extent === undefined &&
169
+ glare.size === undefined &&
170
+ glare.stops === undefined
171
+ ) {
172
+ return undefined;
173
+ }
174
+ const sizeTokens = glare.size ? glare.size.trim().split(/\s+/) : [];
175
+ const shape = glare.shape ?? (sizeTokens.length > 1 ? "ellipse" : "circle");
176
+ const geometry = glare.size ? `${shape} ${glare.size}` : `${glare.extent ?? "farthest-corner"} ${shape}`;
177
+ const stops = (glare.stops?.length ? glare.stops : DEFAULT_GLARE_STOPS).join(", ");
178
+ return `radial-gradient(${geometry} at var(--pointer-x) var(--pointer-y), ${stops})`;
179
+ };
180
+
181
+ const DEPTH_VARS = ["--hc-depth", "--card-perspective", "--hc-depth-shadow", "--hc-depth-layer-scale"];
182
+
105
183
  interface Vec2 {
106
184
  x: number;
107
185
  y: number;
@@ -118,9 +196,8 @@ export class HoloCard {
118
196
  private readonly rotator: HTMLElement;
119
197
  private frontElement: HTMLElement | null;
120
198
  private layersElement: HTMLElement | null = null;
121
- private readonly options: Required<
122
- Pick<HoloCardOptions, "interactive" | "activateOnClick" | "gyroscope" | "showcase">
123
- >;
199
+ private readonly options: Required<Pick<HoloCardOptions, "interactive" | "activateOnClick" | "showcase">>;
200
+ private gyroConfig: ResolvedGyroscope;
124
201
 
125
202
  private readonly springRotate: Spring<Vec2>;
126
203
  private readonly springGlare: Spring<Glare>;
@@ -177,9 +254,9 @@ export class HoloCard {
177
254
  this.options = {
178
255
  interactive: options.interactive ?? true,
179
256
  activateOnClick: options.activateOnClick ?? false,
180
- gyroscope: options.gyroscope ?? true,
181
257
  showcase: options.showcase ?? false,
182
258
  };
259
+ this.gyroConfig = resolveGyroscope(options.gyroscope);
183
260
  this.showcaseRunning = Boolean(options.showcase);
184
261
  this.showcaseConfig = resolveShowcase(options.showcase);
185
262
 
@@ -217,6 +294,7 @@ export class HoloCard {
217
294
  } else if (!element.dataset.effect) {
218
295
  element.dataset.effect = "none";
219
296
  }
297
+ this.applyPalette(options.palette);
220
298
  if (options.glow) {
221
299
  element.style.setProperty("--card-glow", options.glow);
222
300
  }
@@ -226,7 +304,7 @@ export class HoloCard {
226
304
 
227
305
  const mask = normalizeMask(options.mask);
228
306
  if (mask?.image) {
229
- element.style.setProperty("--mask", `url(${mask.image})`);
307
+ element.style.setProperty("--mask", cssUrl(mask.image));
230
308
  if (mask.size) {
231
309
  element.style.setProperty("--mask-size", mask.size);
232
310
  }
@@ -242,9 +320,11 @@ export class HoloCard {
242
320
  }
243
321
  }
244
322
  if (options.foil) {
245
- element.style.setProperty("--foil", `url(${options.foil})`);
323
+ element.style.setProperty("--foil", cssUrl(options.foil));
246
324
  }
247
325
  this.applyVisual(options.visual);
326
+ this.applyGlare(options.glare);
327
+ this.applyDepth(options.depth);
248
328
  applyVars(element, options.vars);
249
329
 
250
330
  if (!this.layersElement && options.layers?.length && this.frontElement) {
@@ -315,6 +395,58 @@ export class HoloCard {
315
395
  }
316
396
  }
317
397
 
398
+ private applyPalette(palette: PaletteOptions | undefined): void {
399
+ if (!palette) {
400
+ return;
401
+ }
402
+ const style = this.element.style;
403
+ const vars = paletteToCssVariables(palette);
404
+ for (const name of PALETTE_VARIABLES) {
405
+ style.removeProperty(name);
406
+ }
407
+ for (const [name, value] of Object.entries(vars)) {
408
+ style.setProperty(name, value);
409
+ }
410
+ }
411
+
412
+ private applyGlare(glare: GlareOptions | undefined): void {
413
+ if (!glare) {
414
+ return;
415
+ }
416
+ const style = this.element.style;
417
+ style.removeProperty("--glare-image");
418
+ style.removeProperty("--glare-blend");
419
+ this.element.classList.remove(CLASS.customGlare);
420
+ if (typeof glare.opacity === "number") {
421
+ style.setProperty("--hc-glare-opacity", String(glare.opacity));
422
+ }
423
+ if (glare.blend !== undefined) {
424
+ style.setProperty("--glare-blend", glare.blend);
425
+ }
426
+ const image = composeGlareImage(glare);
427
+ if (image !== undefined) {
428
+ style.setProperty("--glare-image", image);
429
+ this.element.classList.add(CLASS.customGlare);
430
+ }
431
+ }
432
+
433
+ private applyDepth(depth: boolean | DepthOptions | undefined): void {
434
+ const style = this.element.style;
435
+ const config = resolveDepth(depth);
436
+ if (!config.enabled) {
437
+ this.element.classList.remove(CLASS.depth);
438
+ for (const name of DEPTH_VARS) {
439
+ style.removeProperty(name);
440
+ }
441
+ return;
442
+ }
443
+ this.element.classList.add(CLASS.depth);
444
+ style.setProperty("--hc-depth", `${config.strength}px`);
445
+ style.setProperty("--card-perspective", `${config.perspective}px`);
446
+ style.setProperty("--hc-depth-shadow", String(config.shadow));
447
+ style.setProperty("--hc-depth-layer-scale", String(config.layerScale));
448
+ }
449
+
318
450
  private applyStaticStyles(seed: number | undefined): void {
319
451
  const seedX = Math.random();
320
452
  const seedY = Math.random();
@@ -531,7 +663,7 @@ export class HoloCard {
531
663
  this.popover();
532
664
  this.element.classList.add(CLASS.active);
533
665
  this.element.style.setProperty("--card-active", "1");
534
- if (this.options.gyroscope) {
666
+ if (this.gyroConfig.enabled) {
535
667
  this.startGyroscope();
536
668
  }
537
669
  } else {
@@ -607,20 +739,25 @@ export class HoloCard {
607
739
  if (getActiveCard() !== this) {
608
740
  return;
609
741
  }
610
- const limit = { x: 16, y: 18 };
742
+ const gyro = this.gyroConfig;
743
+ const limit = { x: gyro.rangeX, y: gyro.rangeY };
744
+ const dirX = gyro.invertX ? -1 : 1;
745
+ const dirY = gyro.invertY ? -1 : 1;
611
746
  const degrees = {
612
- x: clamp(orientation.relative.gamma, -limit.x, limit.x),
613
- y: clamp(orientation.relative.beta, -limit.y, limit.y),
747
+ x: clamp(orientation.relative.gamma * gyro.sensitivity * dirX, -limit.x, limit.x),
748
+ y: clamp(orientation.relative.beta * gyro.sensitivity * dirY, -limit.y, limit.y),
614
749
  };
615
- const gx = adjust(degrees.x, -limit.x, limit.x, 0, 100);
616
- const gy = adjust(degrees.y, -limit.y, limit.y, 0, 100);
750
+ const fracX = limit.x === 0 ? 0 : degrees.x / limit.x;
751
+ const fracY = limit.y === 0 ? 0 : degrees.y / limit.y;
752
+ const gx = adjust(fracX, -1, 1, 0, 100);
753
+ const gy = adjust(fracY, -1, 1, 0, 100);
617
754
  this.setInteracting(true);
618
755
  this.updateSprings(
619
- this.parallaxBackground(
620
- adjust(degrees.x, -limit.x, limit.x, 37, 63),
621
- adjust(degrees.y, -limit.y, limit.y, 33, 67),
622
- ),
623
- { x: round(degrees.x * -1 * this.tiltScaleX), y: round(degrees.y * this.tiltScaleY) },
756
+ this.parallaxBackground(adjust(fracX, -1, 1, 37, 63), adjust(fracY, -1, 1, 33, 67)),
757
+ {
758
+ x: round(fracX * DEFAULT_GYRO_RANGE_X * -1 * this.tiltScaleX),
759
+ y: round(fracY * DEFAULT_GYRO_RANGE_Y * this.tiltScaleY),
760
+ },
624
761
  this.rangeGlare(gx, gy, 1),
625
762
  { x: gx, y: gy },
626
763
  );
@@ -739,6 +876,47 @@ export class HoloCard {
739
876
  this.applyVisual(visual);
740
877
  }
741
878
 
879
+ /**
880
+ * Swap the foil colour palette / theme at runtime. This is a full replacement:
881
+ * any palette variable not present in `palette` reverts to its default.
882
+ */
883
+ setPalette(palette: PaletteOptions): void {
884
+ this.applyPalette(palette);
885
+ }
886
+
887
+ /**
888
+ * Update the dynamic glare (reflected light) at runtime. The image / shape /
889
+ * blend are replaced wholesale — omit them to return to the effect's built-in
890
+ * glare. `opacity` is shared with `visual.glareOpacity` and only changes when
891
+ * provided.
892
+ */
893
+ setGlare(glare: GlareOptions): void {
894
+ this.applyGlare(glare);
895
+ }
896
+
897
+ /** Toggle or tune the foil 3D depth / extrusion at runtime. */
898
+ setDepth(depth: boolean | DepthOptions): void {
899
+ this.applyDepth(depth);
900
+ }
901
+
902
+ /** Update the gyroscope physical-behaviour tuning at runtime. */
903
+ setGyroscope(gyroscope: boolean | GyroscopeOptions): void {
904
+ const wasEnabled = this.gyroConfig.enabled;
905
+ this.gyroConfig = resolveGyroscope(gyroscope);
906
+ if (getActiveCard() !== this) {
907
+ return;
908
+ }
909
+ if (this.gyroConfig.enabled) {
910
+ if (!wasEnabled) {
911
+ resetBaseOrientation();
912
+ }
913
+ this.startGyroscope();
914
+ } else {
915
+ this.stopGyroscope();
916
+ this.interactEnd(0);
917
+ }
918
+ }
919
+
742
920
  /**
743
921
  * Insert an extra layer between the artwork and the foil at runtime, returning
744
922
  * the created element. Requires the card to have a `.holo-card__front`.
package/src/index.ts CHANGED
@@ -21,6 +21,7 @@ export {
21
21
  type Orientation,
22
22
  type RelativeOrientation,
23
23
  } from "./orientation.js";
24
+ export { PALETTES, resolvePalette, paletteToCssVariables } from "./palette.js";
24
25
  export { getActiveCard, setActiveCard, subscribeActiveCard } from "./active-registry.js";
25
26
  export { Spring, type SpringValue, type SpringOpts, type SpringSetOpts, type SpringDynamics } from "./spring.js";
26
27
  export { round, clamp, adjust } from "./math.js";
@@ -36,6 +37,11 @@ export type {
36
37
  VisualOptions,
37
38
  MaskOptions,
38
39
  HoloLayerOptions,
40
+ PaletteOptions,
41
+ PalettePreset,
42
+ GlareOptions,
43
+ GyroscopeOptions,
44
+ DepthOptions,
39
45
  } from "./types.js";
40
46
 
41
47
  export const createHoloCard = (options: CreateHoloCardOptions): HoloCard => {