use-scroll-animate 6.3.0 → 6.5.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +33 -2
  2. package/README.md +2 -2
  3. package/README_ja.md +2 -2
  4. package/README_zh.md +2 -2
  5. package/dist/chunks/{generative-BRUZaIsX.js → generative-2LhxG5BJ.js} +2 -2
  6. package/dist/chunks/{generative-BRUZaIsX.js.map → generative-2LhxG5BJ.js.map} +1 -1
  7. package/dist/chunks/{gpu-XHWzeNb5.js → gpu-EjV49FQk.js} +3 -3
  8. package/dist/chunks/{gpu-XHWzeNb5.js.map → gpu-EjV49FQk.js.map} +1 -1
  9. package/dist/chunks/{shared-eweTlzxv.js → shared-CkKHWrtJ.js} +2 -2
  10. package/dist/chunks/{shared-eweTlzxv.js.map → shared-CkKHWrtJ.js.map} +1 -1
  11. package/dist/components/effects.js +3 -3
  12. package/dist/components/fx-3d.cjs +236 -0
  13. package/dist/components/fx-3d.cjs.map +1 -0
  14. package/dist/components/fx-3d.d.cts +67 -0
  15. package/dist/components/fx-3d.d.ts +67 -0
  16. package/dist/components/fx-3d.js +233 -0
  17. package/dist/components/fx-3d.js.map +1 -0
  18. package/dist/components/fx-gpu.js +3 -3
  19. package/dist/components/fx-light.cjs +221 -0
  20. package/dist/components/fx-light.cjs.map +1 -0
  21. package/dist/components/fx-light.d.cts +72 -0
  22. package/dist/components/fx-light.d.ts +72 -0
  23. package/dist/components/fx-light.js +217 -0
  24. package/dist/components/fx-light.js.map +1 -0
  25. package/dist/components/fx-text.js +1 -1
  26. package/dist/components/fx2.cjs +11 -0
  27. package/dist/components/fx2.cjs.map +1 -1
  28. package/dist/components/fx2.d.cts +52 -1
  29. package/dist/components/fx2.d.ts +52 -1
  30. package/dist/components/fx2.js +12 -5
  31. package/dist/components/fx2.js.map +1 -1
  32. package/dist/components/widgets.cjs +1002 -14
  33. package/dist/components/widgets.cjs.map +1 -1
  34. package/dist/components/widgets.d.cts +132 -2
  35. package/dist/components/widgets.d.ts +132 -2
  36. package/dist/components/widgets.js +993 -15
  37. package/dist/components/widgets.js.map +1 -1
  38. package/dist/index.cjs +1 -1
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.js +1 -1
  41. package/dist/index.js.map +1 -1
  42. package/dist/index.umd.js +1 -1
  43. package/dist/index.umd.js.map +1 -1
  44. package/dist/widgets.umd.js +1 -1
  45. package/dist/widgets.umd.js.map +1 -1
  46. package/docs/ROADMAP.md +2 -2
  47. package/docs/components.md +55 -1
  48. package/package.json +24 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-3d.js","sources":["../../src/components/fx2/depth3.ts"],"sourcesContent":["/**\n * 6.5 — 3D scene cards (`motionary/components/fx-3d`), registered through\n * `registerEffect()`:\n *\n * - `depth-stack` (card, persistent) — the children (or `[data-depth]`\n * layers) separate in Z and parallax against each other as the card tilts\n * toward the pointer.\n * - `product-spin` (card, persistent) — a 360° product viewer: drag to turn\n * the element in 3D with inertia, idles with a slow turntable spin.\n * - `card-flip-3d` (click) — a thick card flips to its back face (second\n * child) with an edge that shows its depth.\n * - `origami` (enter) — the element unfolds panel by panel like folded paper.\n * - `orbit-camera` (scroll, persistent) — while the element scrolls through\n * the viewport the camera orbits its 3D children.\n *\n * Reduced motion: no tilt, spin, orbit or fold; the flip swaps faces with a\n * crossfade.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\nimport { all } from '../effects/shared';\nimport { trackPointer } from './light';\n\nconst layers = (el: HTMLElement): HTMLElement[] => {\n const marked = Array.from(el.querySelectorAll<HTMLElement>('[data-depth]'));\n return marked.length ? marked : (Array.from(el.children) as HTMLElement[]);\n};\n\nconst raf = (f: FrameRequestCallback): number => (typeof requestAnimationFrame === 'function' ? requestAnimationFrame(f) : 0);\nconst caf = (h: number): void => {\n if (h && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(h);\n};\n\nexport const DEPTH3_FX: EffectDefinition[] = [\n {\n name: 'depth-stack',\n kind: 'card',\n reduced: 'run',\n description: 'The children (or `[data-depth]` layers) separate in Z and parallax as the card tilts toward the pointer (persistent; `tilt` deg, `depth` px between layers).',\n defaults: { tilt: 14, depth: 28 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const prev = [el.style.transform, el.style.transformStyle, el.style.transition];\n el.style.transformStyle = 'preserve-3d';\n el.style.transition = 'transform .25s ease-out';\n const ls = layers(el);\n const saved = ls.map((l) => [l.style.transform, l.style.transition] as const);\n ls.forEach((l) => (l.style.transition = 'transform .3s ease-out'));\n const stop = trackPointer(el, ctx, (x, y, inside) => {\n const rx = (0.5 - y) * 2 * o.tilt;\n const ry = (x - 0.5) * 2 * o.tilt;\n el.style.transform = ctx.reduced ? '' : inside ? `perspective(800px) rotateX(${rx.toFixed(2)}deg) rotateY(${ry.toFixed(2)}deg)` : 'perspective(800px) rotateX(6deg) rotateY(-8deg)';\n ls.forEach((l, i) => {\n const d = ctx.reduced ? 0 : Number(l.dataset.depth || i + 1) * o.depth * (inside ? 1 : 0.5);\n l.style.transform = `translateZ(${d.toFixed(1)}px)`;\n });\n }, 0.5, 0.5);\n return () => {\n stop();\n [el.style.transform, el.style.transformStyle, el.style.transition] = prev;\n ls.forEach((l, i) => ([l.style.transform, l.style.transition] = saved[i]));\n };\n },\n },\n {\n name: 'product-spin',\n kind: 'card',\n description: 'A 360° product viewer: drag to turn the element in 3D with inertia; idles with a slow turntable spin (persistent; `idle` deg/s, `friction`, `tilt`).',\n defaults: { idle: 18, friction: 0.94, tilt: -8 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const prev = [el.style.transform, el.style.touchAction, el.style.cursor];\n el.style.touchAction = 'pan-y';\n el.style.cursor = 'grab';\n let a = 0;\n let v = 0;\n let drag = false;\n let lx = 0;\n let h = 0;\n let last = performance.now();\n const paint = () => (el.style.transform = `perspective(900px) rotateX(${o.tilt}deg) rotateY(${a.toFixed(2)}deg)`);\n paint();\n const tick = (now: number) => {\n const dt = Math.min(64, now - last) / 1000;\n last = now;\n if (!drag) {\n v *= o.friction;\n a += v * dt + (Math.abs(v) < 4 ? o.idle * dt : 0);\n }\n paint();\n h = raf(tick);\n };\n h = raf(tick);\n const down = (e: PointerEvent) => {\n drag = true;\n lx = e.clientX;\n v = 0;\n el.style.cursor = 'grabbing';\n el.setPointerCapture?.(e.pointerId);\n };\n const move = (e: PointerEvent) => {\n if (!drag) return;\n const dx = e.clientX - lx;\n lx = e.clientX;\n a += dx * 0.6;\n v = dx * 36;\n };\n const up = () => {\n drag = false;\n el.style.cursor = 'grab';\n };\n el.addEventListener('pointerdown', down);\n el.addEventListener('pointermove', move);\n el.addEventListener('pointerup', up);\n el.addEventListener('pointercancel', up);\n return () => {\n caf(h);\n el.removeEventListener('pointerdown', down);\n el.removeEventListener('pointermove', move);\n el.removeEventListener('pointerup', up);\n el.removeEventListener('pointercancel', up);\n [el.style.transform, el.style.touchAction, el.style.cursor] = prev;\n };\n },\n },\n {\n name: 'card-flip-3d',\n kind: 'click',\n description: 'A thick card flips to its back face (second child) and back, showing its edge (`duration`, `axis` y | x). The faces swap `aria-hidden`.',\n defaults: { duration: 800, axis: 'y', thickness: 6 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const [front, back] = Array.from(el.children) as HTMLElement[];\n if (!front || !back) return null;\n const R = o.axis === 'x' ? 'rotateX' : 'rotateY';\n if (!el.dataset.usaFlip) {\n el.dataset.usaFlip = 'front';\n el.style.display = 'grid';\n el.style.transformStyle = 'preserve-3d';\n for (const f of [front, back]) {\n f.style.gridArea = '1 / 1';\n f.style.backfaceVisibility = 'hidden';\n }\n back.setAttribute('aria-hidden', 'true');\n back.style.transform = `${R}(180deg)`;\n }\n const toBack = el.dataset.usaFlip === 'front';\n el.dataset.usaFlip = toBack ? 'back' : 'front';\n front.setAttribute('aria-hidden', String(toBack));\n back.setAttribute('aria-hidden', String(!toBack));\n const from = toBack ? 0 : 180;\n const to = toBack ? 180 : 0;\n el.style.transform = `perspective(1000px) ${R}(${to}deg)`;\n if (ctx.reduced) return ctx.animate(toBack ? back : front, [{ opacity: 0 }, { opacity: 1 }], { duration: 200 });\n return ctx.animate(el, [\n { transform: `perspective(1000px) ${R}(${from}deg) scale(1)` },\n { transform: `perspective(1000px) ${R}(${(from + to) / 2}deg) scale(1.08) translateZ(${o.thickness * 4}px)`, offset: 0.5 },\n { transform: `perspective(1000px) ${R}(${to}deg) scale(1)` },\n ], { duration: o.duration, easing: 'cubic-bezier(.45,.05,.25,1)' });\n },\n },\n {\n name: 'origami',\n kind: 'enter',\n description: 'The element unfolds panel by panel like folded paper (`panels`, `duration` per fold). Uses clipped copies during the fold.',\n defaults: { panels: 4, duration: 420 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (el.dataset.usaOrigami) return null;\n el.dataset.usaOrigami = '1';\n const n = Math.max(2, Math.min(8, Math.round(o.panels)));\n if (getComputedStyle(el).position === 'static') el.style.position = 'relative';\n const prevVis = el.style.visibility;\n const wrap = document.createElement('div');\n wrap.setAttribute('aria-hidden', 'true');\n wrap.style.cssText = 'position:absolute;inset:0;pointer-events:none;perspective:900px;visibility:visible';\n const anims: (Animation | null)[] = [];\n for (let i = 0; i < n; i++) {\n const slice = el.cloneNode(true) as HTMLElement;\n slice.removeAttribute('id');\n slice.querySelectorAll('[id]').forEach((x) => x.removeAttribute('id'));\n const top = (i / n) * 100;\n const bottom = 100 - ((i + 1) / n) * 100;\n slice.style.cssText += `;position:absolute;inset:0;margin:0;width:100%;height:100%;box-sizing:border-box;clip-path:inset(${top}% 0 ${bottom}% 0);transform-origin:50% ${top}%;visibility:visible`;\n wrap.appendChild(slice);\n const dir = i % 2 ? 1 : -1;\n anims.push(ctx.animate(slice, [\n { transform: `rotateX(${dir * 92}deg)`, filter: 'brightness(.55)', opacity: 0 },\n { opacity: 1, offset: 0.15 },\n { transform: 'rotateX(0)', filter: 'brightness(1)', opacity: 1 },\n ], { duration: o.duration, delay: i * o.duration * 0.55, easing: 'cubic-bezier(.3,.7,.3,1)', fill: 'backwards' }));\n }\n el.style.visibility = 'hidden';\n el.appendChild(wrap);\n const done = () => {\n wrap.remove();\n el.style.visibility = prevVis;\n delete el.dataset.usaOrigami;\n };\n return all(anims).then(done, done);\n },\n },\n {\n name: 'orbit-camera',\n kind: 'scroll',\n description: 'While the element scrolls through the viewport the camera orbits its 3D children (persistent; `range` deg of orbit, `tilt`, `depth` px between layers).',\n defaults: { range: 70, tilt: 10, depth: 60 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const prev = [el.style.transform, el.style.transformStyle];\n const ls = layers(el);\n el.style.transformStyle = 'preserve-3d';\n if (!ctx.reduced) ls.forEach((l, i) => (l.style.transform = `translateZ(${((i - (ls.length - 1) / 2) * o.depth).toFixed(0)}px)`));\n let h = 0;\n const paint = () => {\n h = 0;\n const r = el.getBoundingClientRect();\n const vh = window.innerHeight || 800;\n const p = Math.min(1, Math.max(0, (vh - r.top) / (vh + r.height)));\n el.style.setProperty('--usa-orbit', p.toFixed(3));\n if (!ctx.reduced) el.style.transform = `perspective(1000px) rotateX(${o.tilt}deg) rotateY(${((p - 0.5) * o.range).toFixed(2)}deg)`;\n };\n paint();\n const on = () => {\n if (!h) h = raf(paint);\n };\n if (!ctx.reduced) {\n window.addEventListener('scroll', on, { passive: true });\n window.addEventListener('resize', on);\n }\n return () => {\n caf(h);\n window.removeEventListener('scroll', on);\n window.removeEventListener('resize', on);\n [el.style.transform, el.style.transformStyle] = prev;\n ls.forEach((l) => (l.style.transform = ''));\n };\n },\n },\n];\n\n/** Register the 6.5 3D pack (idempotent). */\nexport function register3dEffects(): void {\n registerEffects(DEPTH3_FX);\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import '../chunks/registry-Bu5NrAyA.js';
2
- import '../chunks/generative-BRUZaIsX.js';
3
- import '../chunks/shared-eweTlzxv.js';
4
- export { G as GPU_FX, r as registerGpuEffects } from '../chunks/gpu-XHWzeNb5.js';
2
+ import '../chunks/generative-2LhxG5BJ.js';
3
+ import '../chunks/shared-CkKHWrtJ.js';
4
+ export { G as GPU_FX, r as registerGpuEffects } from '../chunks/gpu-EjV49FQk.js';
5
5
  import '../chunks/base-DchG4q_S.js';
6
6
  //# sourceMappingURL=fx-gpu.js.map
@@ -0,0 +1,221 @@
1
+ 'use strict';
2
+
3
+ var registry = require('../chunks/registry-DehBVRDV.cjs');
4
+ var generative = require('../chunks/generative-BHIj-NU0.cjs');
5
+ var shared = require('../chunks/shared-jkgRH-Hx.cjs');
6
+ require('../chunks/base-BaQV-2ha.cjs');
7
+
8
+ /** Track the pointer over `el` as 0–1 coordinates (`fn(x, y, inside)`); starts at (`x0`, `y0`). Returns a remover. */
9
+ function trackPointer(el, ctx, fn, x0 = 0.3, y0 = 0.25) {
10
+ fn(x0, y0, false);
11
+ if (ctx.reduced)
12
+ return () => undefined;
13
+ let raf = 0;
14
+ let px = x0;
15
+ let py = y0;
16
+ let inside = false;
17
+ const flush = () => {
18
+ raf = 0;
19
+ fn(px, py, inside);
20
+ };
21
+ const queue = () => {
22
+ if (!raf)
23
+ raf = typeof requestAnimationFrame === 'function' ? requestAnimationFrame(flush) : (flush(), 0);
24
+ };
25
+ const move = (e) => {
26
+ const r = el.getBoundingClientRect();
27
+ px = r.width ? Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) : 0.5;
28
+ py = r.height ? Math.min(1, Math.max(0, (e.clientY - r.top) / r.height)) : 0.5;
29
+ inside = true;
30
+ queue();
31
+ };
32
+ const leave = () => {
33
+ inside = false;
34
+ px = x0;
35
+ py = y0;
36
+ queue();
37
+ };
38
+ el.addEventListener('pointermove', move);
39
+ el.addEventListener('pointerleave', leave);
40
+ return () => {
41
+ if (raf && typeof cancelAnimationFrame === 'function')
42
+ cancelAnimationFrame(raf);
43
+ el.removeEventListener('pointermove', move);
44
+ el.removeEventListener('pointerleave', leave);
45
+ };
46
+ }
47
+ const rgba = (hex, a) => {
48
+ const [r, g, b] = generative.hexRgb(hex);
49
+ return `rgba(${r},${g},${b},${a})`;
50
+ };
51
+ const LIGHT_FX = [
52
+ {
53
+ name: 'light-follow',
54
+ kind: 'hover',
55
+ reduced: 'run',
56
+ description: 'A soft point light with a specular hot spot follows the pointer over the surface (persistent; `color`, `size` px, `intensity` 0–1).',
57
+ defaults: { color: '#ffffff', size: 260, intensity: 0.55 },
58
+ run: (el, o, ctx) => {
59
+ const [ov, rm] = shared.overlay(el, 'mix-blend-mode:soft-light;transition:opacity .3s;z-index:1');
60
+ const [spec, rm2] = shared.overlay(el, 'mix-blend-mode:screen;z-index:1');
61
+ const stop = trackPointer(el, ctx, (x, y, inside) => {
62
+ const p = `${(x * 100).toFixed(1)}% ${(y * 100).toFixed(1)}%`;
63
+ ov.style.background = `radial-gradient(${o.size}px circle at ${p}, ${rgba(o.color, o.intensity)}, transparent 70%), radial-gradient(${o.size * 2.4}px circle at ${p}, transparent 30%, rgba(0,0,0,${(o.intensity * 0.45).toFixed(2)}))`;
64
+ spec.style.background = `radial-gradient(${Math.round(o.size / 5)}px circle at ${p}, ${rgba(o.color, inside ? o.intensity * 0.7 : o.intensity * 0.35)}, transparent 70%)`;
65
+ el.style.setProperty('--usa-lx', x.toFixed(3));
66
+ el.style.setProperty('--usa-ly', y.toFixed(3));
67
+ });
68
+ return () => {
69
+ stop();
70
+ rm();
71
+ rm2();
72
+ };
73
+ },
74
+ },
75
+ {
76
+ name: 'refraction',
77
+ kind: 'hover',
78
+ reduced: 'run',
79
+ description: 'A glass lens bends and magnifies what is behind it while following the pointer (persistent; `size` px, `blur`, `rim` color). Uses backdrop-filter.',
80
+ defaults: { size: 120, blur: 1.5, zoom: 1.12, rim: '#9be7ff' },
81
+ run: (el, o, ctx) => {
82
+ if (getComputedStyle(el).position === 'static')
83
+ el.style.position = 'relative';
84
+ const lens = document.createElement('span');
85
+ lens.setAttribute('aria-hidden', 'true');
86
+ const s = Number(o.size) || 120;
87
+ lens.style.cssText = `position:absolute;left:0;top:0;width:${s}px;height:${s}px;border-radius:50%;pointer-events:none;z-index:2;` +
88
+ `-webkit-backdrop-filter:blur(${o.blur}px) saturate(1.6) contrast(1.08) brightness(1.08);backdrop-filter:blur(${o.blur}px) saturate(1.6) contrast(1.08) brightness(1.08);` +
89
+ `box-shadow:inset 0 0 0 1px rgba(255,255,255,.55),inset 6px 8px 14px rgba(255,255,255,.45),inset -8px -10px 18px ${rgba(o.rim, 0.45)},0 10px 30px -8px rgba(0,0,0,.35);` +
90
+ `background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.55),rgba(255,255,255,0) 32%),radial-gradient(circle at 70% 78%,${rgba(o.rim, 0.25)},transparent 45%);transform-origin:50% 50%;will-change:transform;transition:opacity .25s`;
91
+ el.appendChild(lens);
92
+ const stop = trackPointer(el, ctx, (x, y, inside) => {
93
+ const w = el.clientWidth;
94
+ const h = el.clientHeight;
95
+ lens.style.transform = `translate(${(x * w - s / 2).toFixed(1)}px,${(y * h - s / 2).toFixed(1)}px) scale(${inside ? o.zoom : 1})`;
96
+ lens.style.opacity = inside || ctx.reduced ? '1' : '.85';
97
+ }, 0.5, 0.5);
98
+ return () => {
99
+ stop();
100
+ lens.remove();
101
+ };
102
+ },
103
+ },
104
+ {
105
+ name: 'brushed-metal',
106
+ kind: 'card',
107
+ reduced: 'run',
108
+ description: 'Fine brushed-metal lines with an anisotropic sheen that turns with the pointer angle (persistent; `tint`, `lines` px).',
109
+ defaults: { tint: '#cbd5e1', lines: 2 },
110
+ run: (el, o, ctx) => {
111
+ const l = Math.max(1, Number(o.lines) || 2);
112
+ const [grain, rm] = shared.overlay(el, `z-index:0;opacity:.55;mix-blend-mode:overlay;background:repeating-linear-gradient(90deg,rgba(255,255,255,.18) 0 1px,rgba(0,0,0,.12) 1px ${l}px,rgba(255,255,255,.06) ${l}px ${l * 2 + 1}px),linear-gradient(180deg,${rgba(o.tint, 0.9)},${rgba(o.tint, 0.55)})`);
113
+ const [sheen, rm2] = shared.overlay(el, 'z-index:1;mix-blend-mode:soft-light');
114
+ const stop = trackPointer(el, ctx, (x, y) => {
115
+ const ang = Math.atan2(y - 0.5, x - 0.5) * (180 / Math.PI) + 90;
116
+ sheen.style.background = `conic-gradient(from ${ang.toFixed(1)}deg at ${(x * 100).toFixed(1)}% ${(y * 100).toFixed(1)}%, rgba(255,255,255,.75), rgba(0,0,0,.35) 25%, rgba(255,255,255,.6) 50%, rgba(0,0,0,.35) 75%, rgba(255,255,255,.75))`;
117
+ });
118
+ return () => {
119
+ stop();
120
+ rm();
121
+ rm2();
122
+ };
123
+ },
124
+ },
125
+ {
126
+ name: 'pearlescent',
127
+ kind: 'card',
128
+ reduced: 'run',
129
+ description: 'A nacre / holographic film whose hues shift with the pointer position (persistent; `strength` 0–1).',
130
+ defaults: { strength: 0.6 },
131
+ run: (el, o, ctx) => {
132
+ const [film, rm] = shared.overlay(el, `z-index:1;mix-blend-mode:color-dodge;opacity:${o.strength}`);
133
+ const [gloss, rm2] = shared.overlay(el, 'z-index:1;mix-blend-mode:soft-light');
134
+ const stop = trackPointer(el, ctx, (x, y) => {
135
+ const hue = Math.round((x * 0.7 + y * 0.3) * 360);
136
+ film.style.background = `linear-gradient(${Math.round(115 + x * 50)}deg, hsla(${hue},90%,70%,.55), hsla(${hue + 60},90%,75%,.35) 25%, hsla(${hue + 140},85%,70%,.5) 50%, hsla(${hue + 220},90%,75%,.35) 75%, hsla(${hue + 300},90%,70%,.55))`;
137
+ film.style.backgroundSize = '220% 220%';
138
+ film.style.backgroundPosition = `${(x * 100).toFixed(1)}% ${(y * 100).toFixed(1)}%`;
139
+ gloss.style.background = `radial-gradient(80% 60% at ${(x * 100).toFixed(1)}% ${(y * 100).toFixed(1)}%, rgba(255,255,255,.65), transparent 60%)`;
140
+ });
141
+ return () => {
142
+ stop();
143
+ rm();
144
+ rm2();
145
+ };
146
+ },
147
+ },
148
+ {
149
+ name: 'god-rays',
150
+ kind: 'background',
151
+ reduced: 'run',
152
+ description: 'Volumetric light shafts fan out from a source point and slowly sweep (Canvas 2D, additive; `color`, `rays`, `x` / `y` source 0–1).',
153
+ defaults: { color: '#ffe7a3', background: '#0b1020', rays: 14, x: 0.5, y: -0.1, speed: 1, quality: 1 },
154
+ run: (el, o, ctx) => {
155
+ const stop = generative.canvasBackground(el, ctx, {
156
+ init: () => ({ seeds: Array.from({ length: Math.max(3, o.rays | 0) }, (_, i) => ({ a: (i / o.rays) * 1.6 - 0.8 + Math.random() * 0.08, w: 0.03 + Math.random() * 0.06, p: Math.random() * 6.28 })) }),
157
+ draw: ({ ctx: g, w, h, t, state }) => {
158
+ g.globalCompositeOperation = 'source-over';
159
+ g.fillStyle = o.background;
160
+ g.fillRect(0, 0, w, h);
161
+ const sx = o.x * w;
162
+ const sy = o.y * h;
163
+ const len = Math.hypot(w, h) * 1.2;
164
+ const [r, gg, b] = generative.hexRgb(o.color);
165
+ g.globalCompositeOperation = 'lighter';
166
+ for (const s of state.seeds) {
167
+ const a = Math.PI / 2 + s.a + Math.sin(t * 0.25 * o.speed + s.p) * 0.08;
168
+ const alpha = 0.1 + 0.08 * Math.sin(t * 0.8 * o.speed + s.p * 2);
169
+ const grad = g.createLinearGradient(sx, sy, sx + Math.cos(a) * len, sy + Math.sin(a) * len);
170
+ grad.addColorStop(0, `rgba(${r},${gg},${b},${(alpha * 2).toFixed(3)})`);
171
+ grad.addColorStop(1, `rgba(${r},${gg},${b},0)`);
172
+ g.fillStyle = grad;
173
+ g.beginPath();
174
+ g.moveTo(sx, sy);
175
+ g.lineTo(sx + Math.cos(a - s.w) * len, sy + Math.sin(a - s.w) * len);
176
+ g.lineTo(sx + Math.cos(a + s.w) * len, sy + Math.sin(a + s.w) * len);
177
+ g.closePath();
178
+ g.fill();
179
+ }
180
+ const glow = g.createRadialGradient(sx, sy, 0, sx, sy, Math.max(w, h) * 0.45);
181
+ glow.addColorStop(0, `rgba(${r},${gg},${b},.45)`);
182
+ glow.addColorStop(1, `rgba(${r},${gg},${b},0)`);
183
+ g.fillStyle = glow;
184
+ g.fillRect(0, 0, w, h);
185
+ g.globalCompositeOperation = 'source-over';
186
+ },
187
+ }, o);
188
+ ctx.onCleanup(stop);
189
+ return stop;
190
+ },
191
+ },
192
+ {
193
+ name: 'pointer-shadow',
194
+ kind: 'hover',
195
+ reduced: 'run',
196
+ description: 'The pointer is the light: the element casts a soft real-time shadow away from it (persistent; `depth` px, `blur`, `color`).',
197
+ defaults: { depth: 22, blur: 18, color: 'rgba(15,23,42,.38)' },
198
+ run: (el, o, ctx) => {
199
+ const prev = el.style.filter;
200
+ const stop = trackPointer(el, ctx, (x, y, inside) => {
201
+ const dx = (0.5 - x) * 2 * o.depth;
202
+ const dy = (0.5 - y) * 2 * o.depth;
203
+ const k = inside ? 1 : 0.6;
204
+ el.style.filter = `drop-shadow(${(dx * k).toFixed(1)}px ${(dy * k + 4).toFixed(1)}px ${o.blur}px ${o.color})`;
205
+ }, 0.35, 0.2);
206
+ return () => {
207
+ stop();
208
+ el.style.filter = prev;
209
+ };
210
+ },
211
+ },
212
+ ];
213
+ /** Register the 6.4 light & materials pack (idempotent). */
214
+ function registerLightEffects() {
215
+ registry.registerEffects(LIGHT_FX);
216
+ }
217
+
218
+ exports.LIGHT_FX = LIGHT_FX;
219
+ exports.registerLightEffects = registerLightEffects;
220
+ exports.trackPointer = trackPointer;
221
+ //# sourceMappingURL=fx-light.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-light.cjs","sources":["../../src/components/fx2/light.ts"],"sourcesContent":["/**\n * 6.4 — Light & materials (`motionary/components/fx-light`), registered\n * through `registerEffect()`. Persistent effects (use `trigger=\"load\"`)\n * that return a cleanup:\n *\n * - `light-follow` (hover) — a soft point light + specular highlight that\n * follows the pointer over the surface.\n * - `refraction` (hover) — a glass lens that bends and magnifies what is\n * behind it as it follows the pointer (backdrop filter, chromatic rim).\n * - `brushed-metal` (card) — fine brushed lines with an anisotropic sheen\n * that turns with the pointer angle.\n * - `pearlescent` (card) — a nacre / holographic film whose hues shift with\n * the pointer position.\n * - `god-rays` (background) — volumetric light shafts from a source point\n * (Canvas 2D, additive).\n * - `pointer-shadow` (hover) — the pointer is the light: the element casts\n * a soft real-time shadow away from it.\n *\n * Reduced motion: surfaces stay lit from a fixed angle (no tracking),\n * `god-rays` draws one still frame.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\nimport { canvasBackground, hexRgb } from '../effects/generative';\nimport { overlay } from '../effects/shared';\n\n/** Track the pointer over `el` as 0–1 coordinates (`fn(x, y, inside)`); starts at (`x0`, `y0`). Returns a remover. */\nexport function trackPointer(el: HTMLElement, ctx: EffectContext, fn: (x: number, y: number, inside: boolean) => void, x0 = 0.3, y0 = 0.25): () => void {\n fn(x0, y0, false);\n if (ctx.reduced) return () => undefined;\n let raf = 0;\n let px = x0;\n let py = y0;\n let inside = false;\n const flush = () => {\n raf = 0;\n fn(px, py, inside);\n };\n const queue = () => {\n if (!raf) raf = typeof requestAnimationFrame === 'function' ? requestAnimationFrame(flush) : (flush(), 0);\n };\n const move = (e: PointerEvent) => {\n const r = el.getBoundingClientRect();\n px = r.width ? Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) : 0.5;\n py = r.height ? Math.min(1, Math.max(0, (e.clientY - r.top) / r.height)) : 0.5;\n inside = true;\n queue();\n };\n const leave = () => {\n inside = false;\n px = x0;\n py = y0;\n queue();\n };\n el.addEventListener('pointermove', move);\n el.addEventListener('pointerleave', leave);\n return () => {\n if (raf && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(raf);\n el.removeEventListener('pointermove', move);\n el.removeEventListener('pointerleave', leave);\n };\n}\n\nconst rgba = (hex: string, a: number) => {\n const [r, g, b] = hexRgb(hex);\n return `rgba(${r},${g},${b},${a})`;\n};\n\nexport const LIGHT_FX: EffectDefinition[] = [\n {\n name: 'light-follow',\n kind: 'hover',\n reduced: 'run',\n description: 'A soft point light with a specular hot spot follows the pointer over the surface (persistent; `color`, `size` px, `intensity` 0–1).',\n defaults: { color: '#ffffff', size: 260, intensity: 0.55 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const [ov, rm] = overlay(el, 'mix-blend-mode:soft-light;transition:opacity .3s;z-index:1');\n const [spec, rm2] = overlay(el, 'mix-blend-mode:screen;z-index:1');\n const stop = trackPointer(el, ctx, (x, y, inside) => {\n const p = `${(x * 100).toFixed(1)}% ${(y * 100).toFixed(1)}%`;\n ov.style.background = `radial-gradient(${o.size}px circle at ${p}, ${rgba(o.color, o.intensity)}, transparent 70%), radial-gradient(${o.size * 2.4}px circle at ${p}, transparent 30%, rgba(0,0,0,${(o.intensity * 0.45).toFixed(2)}))`;\n spec.style.background = `radial-gradient(${Math.round(o.size / 5)}px circle at ${p}, ${rgba(o.color, inside ? o.intensity * 0.7 : o.intensity * 0.35)}, transparent 70%)`;\n el.style.setProperty('--usa-lx', x.toFixed(3));\n el.style.setProperty('--usa-ly', y.toFixed(3));\n });\n return () => {\n stop();\n rm();\n rm2();\n };\n },\n },\n {\n name: 'refraction',\n kind: 'hover',\n reduced: 'run',\n description: 'A glass lens bends and magnifies what is behind it while following the pointer (persistent; `size` px, `blur`, `rim` color). Uses backdrop-filter.',\n defaults: { size: 120, blur: 1.5, zoom: 1.12, rim: '#9be7ff' },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (getComputedStyle(el).position === 'static') el.style.position = 'relative';\n const lens = document.createElement('span');\n lens.setAttribute('aria-hidden', 'true');\n const s = Number(o.size) || 120;\n lens.style.cssText = `position:absolute;left:0;top:0;width:${s}px;height:${s}px;border-radius:50%;pointer-events:none;z-index:2;` +\n `-webkit-backdrop-filter:blur(${o.blur}px) saturate(1.6) contrast(1.08) brightness(1.08);backdrop-filter:blur(${o.blur}px) saturate(1.6) contrast(1.08) brightness(1.08);` +\n `box-shadow:inset 0 0 0 1px rgba(255,255,255,.55),inset 6px 8px 14px rgba(255,255,255,.45),inset -8px -10px 18px ${rgba(o.rim, 0.45)},0 10px 30px -8px rgba(0,0,0,.35);` +\n `background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.55),rgba(255,255,255,0) 32%),radial-gradient(circle at 70% 78%,${rgba(o.rim, 0.25)},transparent 45%);transform-origin:50% 50%;will-change:transform;transition:opacity .25s`;\n el.appendChild(lens);\n const stop = trackPointer(el, ctx, (x, y, inside) => {\n const w = el.clientWidth;\n const h = el.clientHeight;\n lens.style.transform = `translate(${(x * w - s / 2).toFixed(1)}px,${(y * h - s / 2).toFixed(1)}px) scale(${inside ? o.zoom : 1})`;\n lens.style.opacity = inside || ctx.reduced ? '1' : '.85';\n }, 0.5, 0.5);\n return () => {\n stop();\n lens.remove();\n };\n },\n },\n {\n name: 'brushed-metal',\n kind: 'card',\n reduced: 'run',\n description: 'Fine brushed-metal lines with an anisotropic sheen that turns with the pointer angle (persistent; `tint`, `lines` px).',\n defaults: { tint: '#cbd5e1', lines: 2 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const l = Math.max(1, Number(o.lines) || 2);\n const [grain, rm] = overlay(el, `z-index:0;opacity:.55;mix-blend-mode:overlay;background:repeating-linear-gradient(90deg,rgba(255,255,255,.18) 0 1px,rgba(0,0,0,.12) 1px ${l}px,rgba(255,255,255,.06) ${l}px ${l * 2 + 1}px),linear-gradient(180deg,${rgba(o.tint, 0.9)},${rgba(o.tint, 0.55)})`);\n const [sheen, rm2] = overlay(el, 'z-index:1;mix-blend-mode:soft-light');\n const stop = trackPointer(el, ctx, (x, y) => {\n const ang = Math.atan2(y - 0.5, x - 0.5) * (180 / Math.PI) + 90;\n sheen.style.background = `conic-gradient(from ${ang.toFixed(1)}deg at ${(x * 100).toFixed(1)}% ${(y * 100).toFixed(1)}%, rgba(255,255,255,.75), rgba(0,0,0,.35) 25%, rgba(255,255,255,.6) 50%, rgba(0,0,0,.35) 75%, rgba(255,255,255,.75))`;\n });\n void grain;\n return () => {\n stop();\n rm();\n rm2();\n };\n },\n },\n {\n name: 'pearlescent',\n kind: 'card',\n reduced: 'run',\n description: 'A nacre / holographic film whose hues shift with the pointer position (persistent; `strength` 0–1).',\n defaults: { strength: 0.6 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const [film, rm] = overlay(el, `z-index:1;mix-blend-mode:color-dodge;opacity:${o.strength}`);\n const [gloss, rm2] = overlay(el, 'z-index:1;mix-blend-mode:soft-light');\n const stop = trackPointer(el, ctx, (x, y) => {\n const hue = Math.round((x * 0.7 + y * 0.3) * 360);\n film.style.background = `linear-gradient(${Math.round(115 + x * 50)}deg, hsla(${hue},90%,70%,.55), hsla(${hue + 60},90%,75%,.35) 25%, hsla(${hue + 140},85%,70%,.5) 50%, hsla(${hue + 220},90%,75%,.35) 75%, hsla(${hue + 300},90%,70%,.55))`;\n film.style.backgroundSize = '220% 220%';\n film.style.backgroundPosition = `${(x * 100).toFixed(1)}% ${(y * 100).toFixed(1)}%`;\n gloss.style.background = `radial-gradient(80% 60% at ${(x * 100).toFixed(1)}% ${(y * 100).toFixed(1)}%, rgba(255,255,255,.65), transparent 60%)`;\n });\n return () => {\n stop();\n rm();\n rm2();\n };\n },\n },\n {\n name: 'god-rays',\n kind: 'background',\n reduced: 'run',\n description: 'Volumetric light shafts fan out from a source point and slowly sweep (Canvas 2D, additive; `color`, `rays`, `x` / `y` source 0–1).',\n defaults: { color: '#ffe7a3', background: '#0b1020', rays: 14, x: 0.5, y: -0.1, speed: 1, quality: 1 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const stop = canvasBackground(el, ctx, {\n init: () => ({ seeds: Array.from({ length: Math.max(3, o.rays | 0) }, (_, i) => ({ a: (i / o.rays) * 1.6 - 0.8 + Math.random() * 0.08, w: 0.03 + Math.random() * 0.06, p: Math.random() * 6.28 })) }),\n draw: ({ ctx: g, w, h, t, state }) => {\n g.globalCompositeOperation = 'source-over';\n g.fillStyle = o.background;\n g.fillRect(0, 0, w, h);\n const sx = o.x * w;\n const sy = o.y * h;\n const len = Math.hypot(w, h) * 1.2;\n const [r, gg, b] = hexRgb(o.color);\n g.globalCompositeOperation = 'lighter';\n for (const s of state.seeds) {\n const a = Math.PI / 2 + s.a + Math.sin(t * 0.25 * o.speed + s.p) * 0.08;\n const alpha = 0.1 + 0.08 * Math.sin(t * 0.8 * o.speed + s.p * 2);\n const grad = g.createLinearGradient(sx, sy, sx + Math.cos(a) * len, sy + Math.sin(a) * len);\n grad.addColorStop(0, `rgba(${r},${gg},${b},${(alpha * 2).toFixed(3)})`);\n grad.addColorStop(1, `rgba(${r},${gg},${b},0)`);\n g.fillStyle = grad;\n g.beginPath();\n g.moveTo(sx, sy);\n g.lineTo(sx + Math.cos(a - s.w) * len, sy + Math.sin(a - s.w) * len);\n g.lineTo(sx + Math.cos(a + s.w) * len, sy + Math.sin(a + s.w) * len);\n g.closePath();\n g.fill();\n }\n const glow = g.createRadialGradient(sx, sy, 0, sx, sy, Math.max(w, h) * 0.45);\n glow.addColorStop(0, `rgba(${r},${gg},${b},.45)`);\n glow.addColorStop(1, `rgba(${r},${gg},${b},0)`);\n g.fillStyle = glow;\n g.fillRect(0, 0, w, h);\n g.globalCompositeOperation = 'source-over';\n },\n }, o);\n ctx.onCleanup(stop);\n return stop;\n },\n },\n {\n name: 'pointer-shadow',\n kind: 'hover',\n reduced: 'run',\n description: 'The pointer is the light: the element casts a soft real-time shadow away from it (persistent; `depth` px, `blur`, `color`).',\n defaults: { depth: 22, blur: 18, color: 'rgba(15,23,42,.38)' },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const prev = el.style.filter;\n const stop = trackPointer(el, ctx, (x, y, inside) => {\n const dx = (0.5 - x) * 2 * o.depth;\n const dy = (0.5 - y) * 2 * o.depth;\n const k = inside ? 1 : 0.6;\n el.style.filter = `drop-shadow(${(dx * k).toFixed(1)}px ${(dy * k + 4).toFixed(1)}px ${o.blur}px ${o.color})`;\n }, 0.35, 0.2);\n return () => {\n stop();\n el.style.filter = prev;\n };\n },\n },\n];\n\n/** Register the 6.4 light & materials pack (idempotent). */\nexport function registerLightEffects(): void {\n registerEffects(LIGHT_FX);\n}\n"],"names":["hexRgb","overlay","canvasBackground","registerEffects"],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';
2
+ type Cleanup = () => void;
3
+
4
+ /**
5
+ * 5.0 — unified plugin-style effect registration. Every effect (built-in or
6
+ * yours) is a plain object registered once and played the same way:
7
+ * `playEffect(el, name)`, `bindEffect(el, name, { trigger })` or
8
+ * `<usa-fx effect="name" trigger="click">`. Effects get a context that
9
+ * already applies reduced motion, motion sensitivity, intensity and the
10
+ * animation budget.
11
+ */
12
+
13
+ declare const EFFECT_KINDS: readonly ["enter", "exit", "attention", "click", "hover", "card", "loop", "page", "background", "text", "cursor", "scroll"];
14
+ type EffectKind = (typeof EFFECT_KINDS)[number];
15
+ interface EffectContext {
16
+ /** Reduced motion applies (OS setting, `minimal` / `static` sensitivity). */
17
+ readonly reduced: boolean;
18
+ readonly sensitivity: MotionSensitivity;
19
+ /** The triggering event (pointer position for click effects), if any. */
20
+ readonly event?: Event;
21
+ /** `el.animate()` with the library's motion rules (may return `null`). */
22
+ animate(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null;
23
+ /** Register teardown for long-running effects (loops, listeners). */
24
+ onCleanup(fn: Cleanup): void;
25
+ }
26
+ interface EffectDefinition<O extends Record<string, unknown> = Record<string, any>> {
27
+ /** Unique, kebab-case. */
28
+ name: string;
29
+ kind: EffectKind;
30
+ /** One line for docs and the gallery. */
31
+ description?: string;
32
+ /** Option defaults (merged under the caller's options). */
33
+ defaults?: Partial<O>;
34
+ /**
35
+ * Under reduced motion: `'skip'` (do nothing — default for loop, background
36
+ * and cursor effects) or `'run'` (run with `ctx.reduced === true`, the
37
+ * effect degrades itself — default for everything else).
38
+ */
39
+ reduced?: 'skip' | 'run';
40
+ /** Play the effect. Return an Animation / Promise to be awaited, or a cleanup. */
41
+ run(el: HTMLElement, options: O, ctx: EffectContext): void | Cleanup | Animation | null | Promise<unknown>;
42
+ }
43
+
44
+ /**
45
+ * 6.4 — Light & materials (`motionary/components/fx-light`), registered
46
+ * through `registerEffect()`. Persistent effects (use `trigger="load"`)
47
+ * that return a cleanup:
48
+ *
49
+ * - `light-follow` (hover) — a soft point light + specular highlight that
50
+ * follows the pointer over the surface.
51
+ * - `refraction` (hover) — a glass lens that bends and magnifies what is
52
+ * behind it as it follows the pointer (backdrop filter, chromatic rim).
53
+ * - `brushed-metal` (card) — fine brushed lines with an anisotropic sheen
54
+ * that turns with the pointer angle.
55
+ * - `pearlescent` (card) — a nacre / holographic film whose hues shift with
56
+ * the pointer position.
57
+ * - `god-rays` (background) — volumetric light shafts from a source point
58
+ * (Canvas 2D, additive).
59
+ * - `pointer-shadow` (hover) — the pointer is the light: the element casts
60
+ * a soft real-time shadow away from it.
61
+ *
62
+ * Reduced motion: surfaces stay lit from a fixed angle (no tracking),
63
+ * `god-rays` draws one still frame.
64
+ */
65
+
66
+ /** Track the pointer over `el` as 0–1 coordinates (`fn(x, y, inside)`); starts at (`x0`, `y0`). Returns a remover. */
67
+ declare function trackPointer(el: HTMLElement, ctx: EffectContext, fn: (x: number, y: number, inside: boolean) => void, x0?: number, y0?: number): () => void;
68
+ declare const LIGHT_FX: EffectDefinition[];
69
+ /** Register the 6.4 light & materials pack (idempotent). */
70
+ declare function registerLightEffects(): void;
71
+
72
+ export { LIGHT_FX, registerLightEffects, trackPointer };
@@ -0,0 +1,72 @@
1
+ type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';
2
+ type Cleanup = () => void;
3
+
4
+ /**
5
+ * 5.0 — unified plugin-style effect registration. Every effect (built-in or
6
+ * yours) is a plain object registered once and played the same way:
7
+ * `playEffect(el, name)`, `bindEffect(el, name, { trigger })` or
8
+ * `<usa-fx effect="name" trigger="click">`. Effects get a context that
9
+ * already applies reduced motion, motion sensitivity, intensity and the
10
+ * animation budget.
11
+ */
12
+
13
+ declare const EFFECT_KINDS: readonly ["enter", "exit", "attention", "click", "hover", "card", "loop", "page", "background", "text", "cursor", "scroll"];
14
+ type EffectKind = (typeof EFFECT_KINDS)[number];
15
+ interface EffectContext {
16
+ /** Reduced motion applies (OS setting, `minimal` / `static` sensitivity). */
17
+ readonly reduced: boolean;
18
+ readonly sensitivity: MotionSensitivity;
19
+ /** The triggering event (pointer position for click effects), if any. */
20
+ readonly event?: Event;
21
+ /** `el.animate()` with the library's motion rules (may return `null`). */
22
+ animate(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null;
23
+ /** Register teardown for long-running effects (loops, listeners). */
24
+ onCleanup(fn: Cleanup): void;
25
+ }
26
+ interface EffectDefinition<O extends Record<string, unknown> = Record<string, any>> {
27
+ /** Unique, kebab-case. */
28
+ name: string;
29
+ kind: EffectKind;
30
+ /** One line for docs and the gallery. */
31
+ description?: string;
32
+ /** Option defaults (merged under the caller's options). */
33
+ defaults?: Partial<O>;
34
+ /**
35
+ * Under reduced motion: `'skip'` (do nothing — default for loop, background
36
+ * and cursor effects) or `'run'` (run with `ctx.reduced === true`, the
37
+ * effect degrades itself — default for everything else).
38
+ */
39
+ reduced?: 'skip' | 'run';
40
+ /** Play the effect. Return an Animation / Promise to be awaited, or a cleanup. */
41
+ run(el: HTMLElement, options: O, ctx: EffectContext): void | Cleanup | Animation | null | Promise<unknown>;
42
+ }
43
+
44
+ /**
45
+ * 6.4 — Light & materials (`motionary/components/fx-light`), registered
46
+ * through `registerEffect()`. Persistent effects (use `trigger="load"`)
47
+ * that return a cleanup:
48
+ *
49
+ * - `light-follow` (hover) — a soft point light + specular highlight that
50
+ * follows the pointer over the surface.
51
+ * - `refraction` (hover) — a glass lens that bends and magnifies what is
52
+ * behind it as it follows the pointer (backdrop filter, chromatic rim).
53
+ * - `brushed-metal` (card) — fine brushed lines with an anisotropic sheen
54
+ * that turns with the pointer angle.
55
+ * - `pearlescent` (card) — a nacre / holographic film whose hues shift with
56
+ * the pointer position.
57
+ * - `god-rays` (background) — volumetric light shafts from a source point
58
+ * (Canvas 2D, additive).
59
+ * - `pointer-shadow` (hover) — the pointer is the light: the element casts
60
+ * a soft real-time shadow away from it.
61
+ *
62
+ * Reduced motion: surfaces stay lit from a fixed angle (no tracking),
63
+ * `god-rays` draws one still frame.
64
+ */
65
+
66
+ /** Track the pointer over `el` as 0–1 coordinates (`fn(x, y, inside)`); starts at (`x0`, `y0`). Returns a remover. */
67
+ declare function trackPointer(el: HTMLElement, ctx: EffectContext, fn: (x: number, y: number, inside: boolean) => void, x0?: number, y0?: number): () => void;
68
+ declare const LIGHT_FX: EffectDefinition[];
69
+ /** Register the 6.4 light & materials pack (idempotent). */
70
+ declare function registerLightEffects(): void;
71
+
72
+ export { LIGHT_FX, registerLightEffects, trackPointer };