use-scroll-animate 7.4.0 → 7.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [7.5.0] - 2026-10-08
11
+
12
+ ### Added
13
+ - **4 new components (7.5)** in `motionary/components/widgets` (also in `dist/widgets.umd.js`):
14
+ - `<usa-leaderboard>` — ranked list from `<li data-score>` children or `rows`: on score changes rows glide to their new rank (FLIP), climbers flash green with ▲n, fallers red with ▼n, scores roll; 🥇🥈🥉 for the top three; `limit`, `me`; `setScore()`; `usa:rank`. `rankRows()`.
15
+ - `<usa-xp-bar>` — experience bar (`level`, `xp`, `per`): `add(n)` fills smoothly; overflow fills to the end, the level badge pops and the bar restarts with the remainder (multi-level); `usa:xp`, `usa:levelup`. `levelFor()`.
16
+ - `<usa-badge-wall>` — achievement grid from `<li data-icon data-locked>`: locked badges are grey with 🔒; `unlock(name)` flips the badge to colour with a shine and updates the “n / m unlocked” counter; `badges`, `usa:unlock`. `badgeProgress()`.
17
+ - `<usa-prize-wheel>` — lottery wheel from `segments`: Spin whirls it, it eases out on a random result (or `spin(index)`), the pointer ticks, the wheel glows; `duration`, `turns`, `result`, `spinning`; `usa:result`. `wheelAngle()`.
18
+ - **Gamification motion — `motionary/fx/game`** (= `motionary/components/fx-game`, `registerGamePack()`, also in `registerEffectPacks()`): `achievement-unlock` (attention), `level-up` (attention), `chest-open` (click), `coin-burst` (click), `xp-gain` (enter). `throwPath()`.
19
+ - Showcase: 6 new gallery cards with copyable code and live demos; Animation Store 311 → 317 items.
20
+ - Note: the plan's “lottery” ships as `<usa-prize-wheel>` (wheel + lottery in one component).
21
+
22
+ ### Accessibility
23
+ - Leaderboard = labelled ordered list ("1. Ada, 980 points"), rank changes announced politely; XP bar = `progressbar` labelled "Level 3, 40 of 100 XP", level-ups announced; badge wall = labelled list, each badge "First win, locked/unlocked", unlocks announced; prize wheel = real button (disabled while spinning), result announced. Reduced motion: rows jump, no flash or roll; bar and level change at once; badges change without flip or shine; the wheel jumps to the result; `achievement-unlock` / `level-up` fade, `chest-open` sets the lid open, `coin-burst` / `xp-gain` do nothing.
24
+
25
+ ### Fixed
26
+ - **Store thumbnails are live demos (user report, mobile ~390px).** Cards in “组件 6.x” (now “Components 6.x–7.x”, 90 items incl. every 7.x widget/effect pack) and “框架 / Frameworks” (5) showed only a generic purple tile with a bouncing emoji or letter. Every component card now renders the real `<usa-*>` element with its gallery demo markup + wiring in a lazily mounted frame (`showcase/thumb.html`, mounted by IntersectionObserver near the viewport, dropped 4 s after leaving it, scaled to fit with no overflow, inert on cards, interactive in the detail view and its “related” minis). Framework cards show a live scroll-reveal demo driven through the real adapter (React hooks / Vue composables via minimal hook stand-ins, the Svelte action, `<scroll-animate>`; Solid via the core) next to its code snippet. Reduced motion: the demos are still, the components follow their own reduced-motion paths. Audit: no Store item (all 317) uses the placeholder any more.
27
+ - Showcase: the global icon rule `svg:not([width]) { width: 1.25em }` in `showcase/styles.css` shrank the SVGs inside live demos — `<usa-gauge>` and `<usa-sparkline>` (and the KPI trend) rendered as a 15 px speck in the component gallery. Scoped to UI icons with `:where(…)`.
28
+ - Store detail for components: dropped the meaningless duration/easing controls, keyframes and scroll-test mode; Replay remounts the live demo; the note no longer says “preview only”.
29
+
10
30
  ## [7.4.0] - 2026-10-08
11
31
 
12
32
  ### Added
@@ -0,0 +1,127 @@
1
+ 'use strict';
2
+
3
+ var registry = require('../chunks/registry-DehBVRDV.cjs');
4
+ require('../chunks/base-BaQV-2ha.cjs');
5
+
6
+ /** Ballistic keyframe points for a coin thrown at `deg` with `power` (7.5). */
7
+ function throwPath(deg, power = 120, steps = 6, g = 2.2) {
8
+ const r = (deg * Math.PI) / 180;
9
+ const vx = Math.sin(r) * power;
10
+ const vy = -Math.cos(r) * power;
11
+ return Array.from({ length: steps + 1 }, (_, i) => {
12
+ const t = i / steps;
13
+ return { x: Math.round(vx * t), y: Math.round(vy * t + g * power * t * t * 0.5) };
14
+ });
15
+ }
16
+ const floater = (el, text, css) => {
17
+ const r = el.getBoundingClientRect();
18
+ const s = document.createElement('span');
19
+ s.setAttribute('aria-hidden', 'true');
20
+ s.textContent = text;
21
+ Object.assign(s.style, { position: 'fixed', left: `${r.left + r.width / 2}px`, top: `${r.top + r.height / 2}px`, pointerEvents: 'none', zIndex: '2147483000', translate: '-50% -50%' }, css);
22
+ document.body.appendChild(s);
23
+ return s;
24
+ };
25
+ const fin = (a, el, ctx) => {
26
+ const end = () => el.remove();
27
+ if (a)
28
+ a.finished.then(end, end);
29
+ else
30
+ end();
31
+ ctx.onCleanup(end);
32
+ return a?.finished.catch(() => undefined);
33
+ };
34
+ const GAME_FX = [
35
+ {
36
+ name: 'achievement-unlock',
37
+ kind: 'attention',
38
+ description: 'The element slides in, a light sweep crosses it and its icon (`[data-icon]` or first child) pops (`duration`).',
39
+ defaults: { duration: 900 },
40
+ run: (el, o, ctx) => {
41
+ if (ctx.reduced)
42
+ return ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);
43
+ const icon = (el.querySelector('[data-icon]') || el.firstElementChild);
44
+ const a = ctx.animate(el, [{ transform: 'translateY(30px) scale(.9)', opacity: 0 }, { transform: 'translateY(-4px) scale(1.02)', opacity: 1, offset: 0.5 }, { transform: 'none', opacity: 1 }], { duration: o.duration * 0.6, easing: 'cubic-bezier(.2,.9,.3,1)' });
45
+ if (icon)
46
+ ctx.animate(icon, [{ transform: 'scale(0) rotate(-30deg)' }, { transform: 'scale(1.4) rotate(10deg)', offset: 0.6 }, { transform: 'none' }], { duration: o.duration * 0.6, delay: o.duration * 0.3, easing: 'ease-out', fill: 'backwards' });
47
+ const pos = getComputedStyle(el).position;
48
+ if (pos === 'static')
49
+ el.style.position = 'relative';
50
+ const sh = document.createElement('span');
51
+ sh.setAttribute('aria-hidden', 'true');
52
+ Object.assign(sh.style, { position: 'absolute', inset: '0', borderRadius: 'inherit', pointerEvents: 'none', background: 'linear-gradient(110deg,transparent 35%,rgba(255,255,255,.7) 50%,transparent 65%)', backgroundSize: '250% 100%' });
53
+ el.appendChild(sh);
54
+ fin(ctx.animate(sh, [{ backgroundPosition: '120% 0' }, { backgroundPosition: '-20% 0' }], { duration: o.duration * 0.6, delay: o.duration * 0.4, easing: 'ease-in-out', fill: 'backwards' }), sh, ctx);
55
+ return a?.finished.catch(() => undefined);
56
+ },
57
+ },
58
+ {
59
+ name: 'level-up',
60
+ kind: 'attention',
61
+ description: 'A scale-up with a ring shockwave in `color` (`color`, `duration`).',
62
+ defaults: { color: '#facc15', duration: 800 },
63
+ run: (el, o, ctx) => {
64
+ if (ctx.reduced)
65
+ return ctx.animate(el, [{ opacity: 0.5 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);
66
+ const r = el.getBoundingClientRect();
67
+ const ring = floater(el, '', { width: `${Math.max(r.width, r.height)}px`, height: `${Math.max(r.width, r.height)}px`, borderRadius: '50%', border: `3px solid ${o.color}` });
68
+ fin(ctx.animate(ring, [{ transform: 'scale(.4)', opacity: 1 }, { transform: 'scale(1.8)', opacity: 0 }], { duration: o.duration, easing: 'ease-out' }), ring, ctx);
69
+ return ctx.animate(el, [{ transform: 'scale(1)' }, { transform: 'scale(1.25)', offset: 0.3 }, { transform: 'scale(.95)', offset: 0.6 }, { transform: 'scale(1)' }], { duration: o.duration, easing: 'ease-out' })?.finished.catch(() => undefined);
70
+ },
71
+ },
72
+ {
73
+ name: 'chest-open',
74
+ kind: 'click',
75
+ description: 'The lid (`[data-lid]` or first child) flips open and sparks (`spark`) fly out (`count`).',
76
+ defaults: { spark: '✨', count: 6, duration: 700 },
77
+ run: (el, o, ctx) => {
78
+ const lid = (el.querySelector('[data-lid]') || el.firstElementChild);
79
+ el.setAttribute('data-open', '');
80
+ if (lid)
81
+ lid.style.transformOrigin = '50% 100%';
82
+ if (ctx.reduced)
83
+ return void (lid && (lid.style.transform = 'rotateX(110deg)'));
84
+ if (lid)
85
+ ctx.animate(lid, [{ transform: 'rotateX(0)' }, { transform: 'rotateX(125deg)', offset: 0.6 }, { transform: 'rotateX(110deg)' }], { duration: o.duration, easing: 'cubic-bezier(.3,1.5,.6,1)', fill: 'forwards' });
86
+ const parts = Array.from({ length: o.count }, (_, i) => {
87
+ const s = floater(el, o.spark, { fontSize: '18px' });
88
+ const deg = -60 + (120 * i) / Math.max(1, o.count - 1);
89
+ const p = throwPath(deg, 90, 6, 1.2);
90
+ return fin(ctx.animate(s, p.map((q, k) => ({ transform: `translate(${q.x}px,${q.y}px) scale(${(1 - k / 12).toFixed(2)})`, opacity: k === p.length - 1 ? 0 : 1 })), { duration: o.duration, delay: 150 + i * 30, easing: 'linear' }), s, ctx);
91
+ });
92
+ return Promise.all(parts);
93
+ },
94
+ },
95
+ {
96
+ name: 'coin-burst',
97
+ kind: 'click',
98
+ description: 'Coins (`coin`) arc up out of the element and fall away (`count`, `power`).',
99
+ defaults: { coin: '🪙', count: 8, power: 140, duration: 900 },
100
+ reduced: 'skip',
101
+ run: (el, o, ctx) => Promise.all(Array.from({ length: o.count }, (_, i) => {
102
+ const s = floater(el, o.coin, { fontSize: '20px' });
103
+ const p = throwPath(-50 + (100 * i) / Math.max(1, o.count - 1) + (Math.random() * 10 - 5), o.power * (0.8 + Math.random() * 0.4));
104
+ return fin(ctx.animate(s, p.map((q, k) => ({ transform: `translate(${q.x}px,${q.y}px) rotate(${k * 60}deg)`, opacity: k === p.length - 1 ? 0 : 1 })), { duration: o.duration, delay: i * 25, easing: 'linear' }), s, ctx);
105
+ })),
106
+ },
107
+ {
108
+ name: 'xp-gain',
109
+ kind: 'enter',
110
+ description: 'A “+50 XP” label (`text`, or `data-xp`) floats up from the element and fades (`color`).',
111
+ defaults: { text: '', color: '#7c5cff', duration: 1100 },
112
+ reduced: 'skip',
113
+ run: (el, o, ctx) => {
114
+ const s = floater(el, o.text || `+${el.dataset.xp || 10} XP`, { font: '800 16px/1 system-ui,sans-serif', color: o.color, textShadow: '0 1px 0 #fff' });
115
+ return fin(ctx.animate(s, [{ transform: 'translateY(0) scale(.6)', opacity: 0 }, { transform: 'translateY(-18px) scale(1.15)', opacity: 1, offset: 0.25 }, { transform: 'translateY(-50px) scale(1)', opacity: 0 }], { duration: o.duration, easing: 'ease-out' }), s, ctx);
116
+ },
117
+ },
118
+ ];
119
+ /** Register the 7.5 gamification pack (idempotent). */
120
+ function registerGamePack() {
121
+ registry.registerEffects(GAME_FX);
122
+ }
123
+
124
+ exports.GAME_FX = GAME_FX;
125
+ exports.registerGamePack = registerGamePack;
126
+ exports.throwPath = throwPath;
127
+ //# sourceMappingURL=fx-game.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-game.cjs","sources":["../../src/components/fx2/game.ts"],"sourcesContent":["/**\n * 7.5 — Gamification motion (`motionary/fx/game`, also\n * `motionary/components/fx-game`):\n *\n * - `achievement-unlock` (attention) — the element slides in, a light sweep\n * crosses it and its icon (`[data-icon]` or first child) pops.\n * - `level-up` (attention) — a scale-up with a ring shockwave.\n * - `chest-open` (click) — the lid (`[data-lid]` or first child) flips open\n * and sparks fly out.\n * - `coin-burst` (click) — coins (`coin`, default 🪙) arc up and fall.\n * - `xp-gain` (enter) — a “+50 XP” label (`text` or `data-xp`) floats up and\n * fades.\n *\n * Reduced motion: unlock / level-up fade, chest-open sets the lid open,\n * coin-burst and xp-gain do nothing.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\n\n/** Ballistic keyframe points for a coin thrown at `deg` with `power` (7.5). */\nexport function throwPath(deg: number, power = 120, steps = 6, g = 2.2): { x: number; y: number }[] {\n const r = (deg * Math.PI) / 180;\n const vx = Math.sin(r) * power;\n const vy = -Math.cos(r) * power;\n return Array.from({ length: steps + 1 }, (_, i) => {\n const t = i / steps;\n return { x: Math.round(vx * t), y: Math.round(vy * t + g * power * t * t * 0.5) };\n });\n}\n\nconst floater = (el: HTMLElement, text: string, css: Partial<CSSStyleDeclaration>): HTMLSpanElement => {\n const r = el.getBoundingClientRect();\n const s = document.createElement('span');\n s.setAttribute('aria-hidden', 'true');\n s.textContent = text;\n Object.assign(s.style, { position: 'fixed', left: `${r.left + r.width / 2}px`, top: `${r.top + r.height / 2}px`, pointerEvents: 'none', zIndex: '2147483000', translate: '-50% -50%' }, css);\n document.body.appendChild(s);\n return s;\n};\n\nconst fin = (a: Animation | null | undefined, el: Element, ctx: EffectContext) => {\n const end = () => el.remove();\n if (a) a.finished.then(end, end);\n else end();\n ctx.onCleanup(end);\n return a?.finished.catch(() => undefined);\n};\n\nexport const GAME_FX: EffectDefinition[] = [\n {\n name: 'achievement-unlock',\n kind: 'attention',\n description: 'The element slides in, a light sweep crosses it and its icon (`[data-icon]` or first child) pops (`duration`).',\n defaults: { duration: 900 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);\n const icon = (el.querySelector('[data-icon]') || el.firstElementChild) as HTMLElement | null;\n const a = ctx.animate(el, [{ transform: 'translateY(30px) scale(.9)', opacity: 0 }, { transform: 'translateY(-4px) scale(1.02)', opacity: 1, offset: 0.5 }, { transform: 'none', opacity: 1 }], { duration: o.duration * 0.6, easing: 'cubic-bezier(.2,.9,.3,1)' });\n if (icon) ctx.animate(icon, [{ transform: 'scale(0) rotate(-30deg)' }, { transform: 'scale(1.4) rotate(10deg)', offset: 0.6 }, { transform: 'none' }], { duration: o.duration * 0.6, delay: o.duration * 0.3, easing: 'ease-out', fill: 'backwards' });\n const pos = getComputedStyle(el).position;\n if (pos === 'static') el.style.position = 'relative';\n const sh = document.createElement('span');\n sh.setAttribute('aria-hidden', 'true');\n Object.assign(sh.style, { position: 'absolute', inset: '0', borderRadius: 'inherit', pointerEvents: 'none', background: 'linear-gradient(110deg,transparent 35%,rgba(255,255,255,.7) 50%,transparent 65%)', backgroundSize: '250% 100%' });\n el.appendChild(sh);\n fin(ctx.animate(sh, [{ backgroundPosition: '120% 0' }, { backgroundPosition: '-20% 0' }], { duration: o.duration * 0.6, delay: o.duration * 0.4, easing: 'ease-in-out', fill: 'backwards' }), sh, ctx);\n return a?.finished.catch(() => undefined);\n },\n },\n {\n name: 'level-up',\n kind: 'attention',\n description: 'A scale-up with a ring shockwave in `color` (`color`, `duration`).',\n defaults: { color: '#facc15', duration: 800 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return ctx.animate(el, [{ opacity: 0.5 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);\n const r = el.getBoundingClientRect();\n const ring = floater(el, '', { width: `${Math.max(r.width, r.height)}px`, height: `${Math.max(r.width, r.height)}px`, borderRadius: '50%', border: `3px solid ${o.color}` });\n fin(ctx.animate(ring, [{ transform: 'scale(.4)', opacity: 1 }, { transform: 'scale(1.8)', opacity: 0 }], { duration: o.duration, easing: 'ease-out' }), ring, ctx);\n return ctx.animate(el, [{ transform: 'scale(1)' }, { transform: 'scale(1.25)', offset: 0.3 }, { transform: 'scale(.95)', offset: 0.6 }, { transform: 'scale(1)' }], { duration: o.duration, easing: 'ease-out' })?.finished.catch(() => undefined);\n },\n },\n {\n name: 'chest-open',\n kind: 'click',\n description: 'The lid (`[data-lid]` or first child) flips open and sparks (`spark`) fly out (`count`).',\n defaults: { spark: '✨', count: 6, duration: 700 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const lid = (el.querySelector('[data-lid]') || el.firstElementChild) as HTMLElement | null;\n el.setAttribute('data-open', '');\n if (lid) lid.style.transformOrigin = '50% 100%';\n if (ctx.reduced) return void (lid && (lid.style.transform = 'rotateX(110deg)'));\n if (lid) ctx.animate(lid, [{ transform: 'rotateX(0)' }, { transform: 'rotateX(125deg)', offset: 0.6 }, { transform: 'rotateX(110deg)' }], { duration: o.duration, easing: 'cubic-bezier(.3,1.5,.6,1)', fill: 'forwards' });\n const parts = Array.from({ length: o.count }, (_, i) => {\n const s = floater(el, o.spark, { fontSize: '18px' });\n const deg = -60 + (120 * i) / Math.max(1, o.count - 1);\n const p = throwPath(deg, 90, 6, 1.2);\n return fin(ctx.animate(s, p.map((q, k) => ({ transform: `translate(${q.x}px,${q.y}px) scale(${(1 - k / 12).toFixed(2)})`, opacity: k === p.length - 1 ? 0 : 1 })), { duration: o.duration, delay: 150 + i * 30, easing: 'linear' }), s, ctx);\n });\n return Promise.all(parts);\n },\n },\n {\n name: 'coin-burst',\n kind: 'click',\n description: 'Coins (`coin`) arc up out of the element and fall away (`count`, `power`).',\n defaults: { coin: '🪙', count: 8, power: 140, duration: 900 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) =>\n Promise.all(\n Array.from({ length: o.count }, (_, i) => {\n const s = floater(el, o.coin, { fontSize: '20px' });\n const p = throwPath(-50 + (100 * i) / Math.max(1, o.count - 1) + (Math.random() * 10 - 5), o.power * (0.8 + Math.random() * 0.4));\n return fin(ctx.animate(s, p.map((q, k) => ({ transform: `translate(${q.x}px,${q.y}px) rotate(${k * 60}deg)`, opacity: k === p.length - 1 ? 0 : 1 })), { duration: o.duration, delay: i * 25, easing: 'linear' }), s, ctx);\n })\n ),\n },\n {\n name: 'xp-gain',\n kind: 'enter',\n description: 'A “+50 XP” label (`text`, or `data-xp`) floats up from the element and fades (`color`).',\n defaults: { text: '', color: '#7c5cff', duration: 1100 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const s = floater(el, o.text || `+${el.dataset.xp || 10} XP`, { font: '800 16px/1 system-ui,sans-serif', color: o.color, textShadow: '0 1px 0 #fff' });\n return fin(ctx.animate(s, [{ transform: 'translateY(0) scale(.6)', opacity: 0 }, { transform: 'translateY(-18px) scale(1.15)', opacity: 1, offset: 0.25 }, { transform: 'translateY(-50px) scale(1)', opacity: 0 }], { duration: o.duration, easing: 'ease-out' }), s, ctx);\n },\n },\n];\n\n/** Register the 7.5 gamification pack (idempotent). */\nexport function registerGamePack(): void {\n registerEffects(GAME_FX);\n}\n"],"names":["registerEffects"],"mappings":"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"}
@@ -0,0 +1,70 @@
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
+ * 7.5 — Gamification motion (`motionary/fx/game`, also
46
+ * `motionary/components/fx-game`):
47
+ *
48
+ * - `achievement-unlock` (attention) — the element slides in, a light sweep
49
+ * crosses it and its icon (`[data-icon]` or first child) pops.
50
+ * - `level-up` (attention) — a scale-up with a ring shockwave.
51
+ * - `chest-open` (click) — the lid (`[data-lid]` or first child) flips open
52
+ * and sparks fly out.
53
+ * - `coin-burst` (click) — coins (`coin`, default 🪙) arc up and fall.
54
+ * - `xp-gain` (enter) — a “+50 XP” label (`text` or `data-xp`) floats up and
55
+ * fades.
56
+ *
57
+ * Reduced motion: unlock / level-up fade, chest-open sets the lid open,
58
+ * coin-burst and xp-gain do nothing.
59
+ */
60
+
61
+ /** Ballistic keyframe points for a coin thrown at `deg` with `power` (7.5). */
62
+ declare function throwPath(deg: number, power?: number, steps?: number, g?: number): {
63
+ x: number;
64
+ y: number;
65
+ }[];
66
+ declare const GAME_FX: EffectDefinition[];
67
+ /** Register the 7.5 gamification pack (idempotent). */
68
+ declare function registerGamePack(): void;
69
+
70
+ export { GAME_FX, registerGamePack, throwPath };
@@ -0,0 +1,70 @@
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
+ * 7.5 — Gamification motion (`motionary/fx/game`, also
46
+ * `motionary/components/fx-game`):
47
+ *
48
+ * - `achievement-unlock` (attention) — the element slides in, a light sweep
49
+ * crosses it and its icon (`[data-icon]` or first child) pops.
50
+ * - `level-up` (attention) — a scale-up with a ring shockwave.
51
+ * - `chest-open` (click) — the lid (`[data-lid]` or first child) flips open
52
+ * and sparks fly out.
53
+ * - `coin-burst` (click) — coins (`coin`, default 🪙) arc up and fall.
54
+ * - `xp-gain` (enter) — a “+50 XP” label (`text` or `data-xp`) floats up and
55
+ * fades.
56
+ *
57
+ * Reduced motion: unlock / level-up fade, chest-open sets the lid open,
58
+ * coin-burst and xp-gain do nothing.
59
+ */
60
+
61
+ /** Ballistic keyframe points for a coin thrown at `deg` with `power` (7.5). */
62
+ declare function throwPath(deg: number, power?: number, steps?: number, g?: number): {
63
+ x: number;
64
+ y: number;
65
+ }[];
66
+ declare const GAME_FX: EffectDefinition[];
67
+ /** Register the 7.5 gamification pack (idempotent). */
68
+ declare function registerGamePack(): void;
69
+
70
+ export { GAME_FX, registerGamePack, throwPath };
@@ -0,0 +1,123 @@
1
+ import { registerEffects } from '../chunks/registry-CyKExAmE.js';
2
+ import '../chunks/base-2-yYc93C.js';
3
+
4
+ /** Ballistic keyframe points for a coin thrown at `deg` with `power` (7.5). */
5
+ function throwPath(deg, power = 120, steps = 6, g = 2.2) {
6
+ const r = (deg * Math.PI) / 180;
7
+ const vx = Math.sin(r) * power;
8
+ const vy = -Math.cos(r) * power;
9
+ return Array.from({ length: steps + 1 }, (_, i) => {
10
+ const t = i / steps;
11
+ return { x: Math.round(vx * t), y: Math.round(vy * t + g * power * t * t * 0.5) };
12
+ });
13
+ }
14
+ const floater = (el, text, css) => {
15
+ const r = el.getBoundingClientRect();
16
+ const s = document.createElement('span');
17
+ s.setAttribute('aria-hidden', 'true');
18
+ s.textContent = text;
19
+ Object.assign(s.style, { position: 'fixed', left: `${r.left + r.width / 2}px`, top: `${r.top + r.height / 2}px`, pointerEvents: 'none', zIndex: '2147483000', translate: '-50% -50%' }, css);
20
+ document.body.appendChild(s);
21
+ return s;
22
+ };
23
+ const fin = (a, el, ctx) => {
24
+ const end = () => el.remove();
25
+ if (a)
26
+ a.finished.then(end, end);
27
+ else
28
+ end();
29
+ ctx.onCleanup(end);
30
+ return a?.finished.catch(() => undefined);
31
+ };
32
+ const GAME_FX = [
33
+ {
34
+ name: 'achievement-unlock',
35
+ kind: 'attention',
36
+ description: 'The element slides in, a light sweep crosses it and its icon (`[data-icon]` or first child) pops (`duration`).',
37
+ defaults: { duration: 900 },
38
+ run: (el, o, ctx) => {
39
+ if (ctx.reduced)
40
+ return ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);
41
+ const icon = (el.querySelector('[data-icon]') || el.firstElementChild);
42
+ const a = ctx.animate(el, [{ transform: 'translateY(30px) scale(.9)', opacity: 0 }, { transform: 'translateY(-4px) scale(1.02)', opacity: 1, offset: 0.5 }, { transform: 'none', opacity: 1 }], { duration: o.duration * 0.6, easing: 'cubic-bezier(.2,.9,.3,1)' });
43
+ if (icon)
44
+ ctx.animate(icon, [{ transform: 'scale(0) rotate(-30deg)' }, { transform: 'scale(1.4) rotate(10deg)', offset: 0.6 }, { transform: 'none' }], { duration: o.duration * 0.6, delay: o.duration * 0.3, easing: 'ease-out', fill: 'backwards' });
45
+ const pos = getComputedStyle(el).position;
46
+ if (pos === 'static')
47
+ el.style.position = 'relative';
48
+ const sh = document.createElement('span');
49
+ sh.setAttribute('aria-hidden', 'true');
50
+ Object.assign(sh.style, { position: 'absolute', inset: '0', borderRadius: 'inherit', pointerEvents: 'none', background: 'linear-gradient(110deg,transparent 35%,rgba(255,255,255,.7) 50%,transparent 65%)', backgroundSize: '250% 100%' });
51
+ el.appendChild(sh);
52
+ fin(ctx.animate(sh, [{ backgroundPosition: '120% 0' }, { backgroundPosition: '-20% 0' }], { duration: o.duration * 0.6, delay: o.duration * 0.4, easing: 'ease-in-out', fill: 'backwards' }), sh, ctx);
53
+ return a?.finished.catch(() => undefined);
54
+ },
55
+ },
56
+ {
57
+ name: 'level-up',
58
+ kind: 'attention',
59
+ description: 'A scale-up with a ring shockwave in `color` (`color`, `duration`).',
60
+ defaults: { color: '#facc15', duration: 800 },
61
+ run: (el, o, ctx) => {
62
+ if (ctx.reduced)
63
+ return ctx.animate(el, [{ opacity: 0.5 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);
64
+ const r = el.getBoundingClientRect();
65
+ const ring = floater(el, '', { width: `${Math.max(r.width, r.height)}px`, height: `${Math.max(r.width, r.height)}px`, borderRadius: '50%', border: `3px solid ${o.color}` });
66
+ fin(ctx.animate(ring, [{ transform: 'scale(.4)', opacity: 1 }, { transform: 'scale(1.8)', opacity: 0 }], { duration: o.duration, easing: 'ease-out' }), ring, ctx);
67
+ return ctx.animate(el, [{ transform: 'scale(1)' }, { transform: 'scale(1.25)', offset: 0.3 }, { transform: 'scale(.95)', offset: 0.6 }, { transform: 'scale(1)' }], { duration: o.duration, easing: 'ease-out' })?.finished.catch(() => undefined);
68
+ },
69
+ },
70
+ {
71
+ name: 'chest-open',
72
+ kind: 'click',
73
+ description: 'The lid (`[data-lid]` or first child) flips open and sparks (`spark`) fly out (`count`).',
74
+ defaults: { spark: '✨', count: 6, duration: 700 },
75
+ run: (el, o, ctx) => {
76
+ const lid = (el.querySelector('[data-lid]') || el.firstElementChild);
77
+ el.setAttribute('data-open', '');
78
+ if (lid)
79
+ lid.style.transformOrigin = '50% 100%';
80
+ if (ctx.reduced)
81
+ return void (lid && (lid.style.transform = 'rotateX(110deg)'));
82
+ if (lid)
83
+ ctx.animate(lid, [{ transform: 'rotateX(0)' }, { transform: 'rotateX(125deg)', offset: 0.6 }, { transform: 'rotateX(110deg)' }], { duration: o.duration, easing: 'cubic-bezier(.3,1.5,.6,1)', fill: 'forwards' });
84
+ const parts = Array.from({ length: o.count }, (_, i) => {
85
+ const s = floater(el, o.spark, { fontSize: '18px' });
86
+ const deg = -60 + (120 * i) / Math.max(1, o.count - 1);
87
+ const p = throwPath(deg, 90, 6, 1.2);
88
+ return fin(ctx.animate(s, p.map((q, k) => ({ transform: `translate(${q.x}px,${q.y}px) scale(${(1 - k / 12).toFixed(2)})`, opacity: k === p.length - 1 ? 0 : 1 })), { duration: o.duration, delay: 150 + i * 30, easing: 'linear' }), s, ctx);
89
+ });
90
+ return Promise.all(parts);
91
+ },
92
+ },
93
+ {
94
+ name: 'coin-burst',
95
+ kind: 'click',
96
+ description: 'Coins (`coin`) arc up out of the element and fall away (`count`, `power`).',
97
+ defaults: { coin: '🪙', count: 8, power: 140, duration: 900 },
98
+ reduced: 'skip',
99
+ run: (el, o, ctx) => Promise.all(Array.from({ length: o.count }, (_, i) => {
100
+ const s = floater(el, o.coin, { fontSize: '20px' });
101
+ const p = throwPath(-50 + (100 * i) / Math.max(1, o.count - 1) + (Math.random() * 10 - 5), o.power * (0.8 + Math.random() * 0.4));
102
+ return fin(ctx.animate(s, p.map((q, k) => ({ transform: `translate(${q.x}px,${q.y}px) rotate(${k * 60}deg)`, opacity: k === p.length - 1 ? 0 : 1 })), { duration: o.duration, delay: i * 25, easing: 'linear' }), s, ctx);
103
+ })),
104
+ },
105
+ {
106
+ name: 'xp-gain',
107
+ kind: 'enter',
108
+ description: 'A “+50 XP” label (`text`, or `data-xp`) floats up from the element and fades (`color`).',
109
+ defaults: { text: '', color: '#7c5cff', duration: 1100 },
110
+ reduced: 'skip',
111
+ run: (el, o, ctx) => {
112
+ const s = floater(el, o.text || `+${el.dataset.xp || 10} XP`, { font: '800 16px/1 system-ui,sans-serif', color: o.color, textShadow: '0 1px 0 #fff' });
113
+ return fin(ctx.animate(s, [{ transform: 'translateY(0) scale(.6)', opacity: 0 }, { transform: 'translateY(-18px) scale(1.15)', opacity: 1, offset: 0.25 }, { transform: 'translateY(-50px) scale(1)', opacity: 0 }], { duration: o.duration, easing: 'ease-out' }), s, ctx);
114
+ },
115
+ },
116
+ ];
117
+ /** Register the 7.5 gamification pack (idempotent). */
118
+ function registerGamePack() {
119
+ registerEffects(GAME_FX);
120
+ }
121
+
122
+ export { GAME_FX, registerGamePack, throwPath };
123
+ //# sourceMappingURL=fx-game.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-game.js","sources":["../../src/components/fx2/game.ts"],"sourcesContent":["/**\n * 7.5 — Gamification motion (`motionary/fx/game`, also\n * `motionary/components/fx-game`):\n *\n * - `achievement-unlock` (attention) — the element slides in, a light sweep\n * crosses it and its icon (`[data-icon]` or first child) pops.\n * - `level-up` (attention) — a scale-up with a ring shockwave.\n * - `chest-open` (click) — the lid (`[data-lid]` or first child) flips open\n * and sparks fly out.\n * - `coin-burst` (click) — coins (`coin`, default 🪙) arc up and fall.\n * - `xp-gain` (enter) — a “+50 XP” label (`text` or `data-xp`) floats up and\n * fades.\n *\n * Reduced motion: unlock / level-up fade, chest-open sets the lid open,\n * coin-burst and xp-gain do nothing.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\n\n/** Ballistic keyframe points for a coin thrown at `deg` with `power` (7.5). */\nexport function throwPath(deg: number, power = 120, steps = 6, g = 2.2): { x: number; y: number }[] {\n const r = (deg * Math.PI) / 180;\n const vx = Math.sin(r) * power;\n const vy = -Math.cos(r) * power;\n return Array.from({ length: steps + 1 }, (_, i) => {\n const t = i / steps;\n return { x: Math.round(vx * t), y: Math.round(vy * t + g * power * t * t * 0.5) };\n });\n}\n\nconst floater = (el: HTMLElement, text: string, css: Partial<CSSStyleDeclaration>): HTMLSpanElement => {\n const r = el.getBoundingClientRect();\n const s = document.createElement('span');\n s.setAttribute('aria-hidden', 'true');\n s.textContent = text;\n Object.assign(s.style, { position: 'fixed', left: `${r.left + r.width / 2}px`, top: `${r.top + r.height / 2}px`, pointerEvents: 'none', zIndex: '2147483000', translate: '-50% -50%' }, css);\n document.body.appendChild(s);\n return s;\n};\n\nconst fin = (a: Animation | null | undefined, el: Element, ctx: EffectContext) => {\n const end = () => el.remove();\n if (a) a.finished.then(end, end);\n else end();\n ctx.onCleanup(end);\n return a?.finished.catch(() => undefined);\n};\n\nexport const GAME_FX: EffectDefinition[] = [\n {\n name: 'achievement-unlock',\n kind: 'attention',\n description: 'The element slides in, a light sweep crosses it and its icon (`[data-icon]` or first child) pops (`duration`).',\n defaults: { duration: 900 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);\n const icon = (el.querySelector('[data-icon]') || el.firstElementChild) as HTMLElement | null;\n const a = ctx.animate(el, [{ transform: 'translateY(30px) scale(.9)', opacity: 0 }, { transform: 'translateY(-4px) scale(1.02)', opacity: 1, offset: 0.5 }, { transform: 'none', opacity: 1 }], { duration: o.duration * 0.6, easing: 'cubic-bezier(.2,.9,.3,1)' });\n if (icon) ctx.animate(icon, [{ transform: 'scale(0) rotate(-30deg)' }, { transform: 'scale(1.4) rotate(10deg)', offset: 0.6 }, { transform: 'none' }], { duration: o.duration * 0.6, delay: o.duration * 0.3, easing: 'ease-out', fill: 'backwards' });\n const pos = getComputedStyle(el).position;\n if (pos === 'static') el.style.position = 'relative';\n const sh = document.createElement('span');\n sh.setAttribute('aria-hidden', 'true');\n Object.assign(sh.style, { position: 'absolute', inset: '0', borderRadius: 'inherit', pointerEvents: 'none', background: 'linear-gradient(110deg,transparent 35%,rgba(255,255,255,.7) 50%,transparent 65%)', backgroundSize: '250% 100%' });\n el.appendChild(sh);\n fin(ctx.animate(sh, [{ backgroundPosition: '120% 0' }, { backgroundPosition: '-20% 0' }], { duration: o.duration * 0.6, delay: o.duration * 0.4, easing: 'ease-in-out', fill: 'backwards' }), sh, ctx);\n return a?.finished.catch(() => undefined);\n },\n },\n {\n name: 'level-up',\n kind: 'attention',\n description: 'A scale-up with a ring shockwave in `color` (`color`, `duration`).',\n defaults: { color: '#facc15', duration: 800 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return ctx.animate(el, [{ opacity: 0.5 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);\n const r = el.getBoundingClientRect();\n const ring = floater(el, '', { width: `${Math.max(r.width, r.height)}px`, height: `${Math.max(r.width, r.height)}px`, borderRadius: '50%', border: `3px solid ${o.color}` });\n fin(ctx.animate(ring, [{ transform: 'scale(.4)', opacity: 1 }, { transform: 'scale(1.8)', opacity: 0 }], { duration: o.duration, easing: 'ease-out' }), ring, ctx);\n return ctx.animate(el, [{ transform: 'scale(1)' }, { transform: 'scale(1.25)', offset: 0.3 }, { transform: 'scale(.95)', offset: 0.6 }, { transform: 'scale(1)' }], { duration: o.duration, easing: 'ease-out' })?.finished.catch(() => undefined);\n },\n },\n {\n name: 'chest-open',\n kind: 'click',\n description: 'The lid (`[data-lid]` or first child) flips open and sparks (`spark`) fly out (`count`).',\n defaults: { spark: '✨', count: 6, duration: 700 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const lid = (el.querySelector('[data-lid]') || el.firstElementChild) as HTMLElement | null;\n el.setAttribute('data-open', '');\n if (lid) lid.style.transformOrigin = '50% 100%';\n if (ctx.reduced) return void (lid && (lid.style.transform = 'rotateX(110deg)'));\n if (lid) ctx.animate(lid, [{ transform: 'rotateX(0)' }, { transform: 'rotateX(125deg)', offset: 0.6 }, { transform: 'rotateX(110deg)' }], { duration: o.duration, easing: 'cubic-bezier(.3,1.5,.6,1)', fill: 'forwards' });\n const parts = Array.from({ length: o.count }, (_, i) => {\n const s = floater(el, o.spark, { fontSize: '18px' });\n const deg = -60 + (120 * i) / Math.max(1, o.count - 1);\n const p = throwPath(deg, 90, 6, 1.2);\n return fin(ctx.animate(s, p.map((q, k) => ({ transform: `translate(${q.x}px,${q.y}px) scale(${(1 - k / 12).toFixed(2)})`, opacity: k === p.length - 1 ? 0 : 1 })), { duration: o.duration, delay: 150 + i * 30, easing: 'linear' }), s, ctx);\n });\n return Promise.all(parts);\n },\n },\n {\n name: 'coin-burst',\n kind: 'click',\n description: 'Coins (`coin`) arc up out of the element and fall away (`count`, `power`).',\n defaults: { coin: '🪙', count: 8, power: 140, duration: 900 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) =>\n Promise.all(\n Array.from({ length: o.count }, (_, i) => {\n const s = floater(el, o.coin, { fontSize: '20px' });\n const p = throwPath(-50 + (100 * i) / Math.max(1, o.count - 1) + (Math.random() * 10 - 5), o.power * (0.8 + Math.random() * 0.4));\n return fin(ctx.animate(s, p.map((q, k) => ({ transform: `translate(${q.x}px,${q.y}px) rotate(${k * 60}deg)`, opacity: k === p.length - 1 ? 0 : 1 })), { duration: o.duration, delay: i * 25, easing: 'linear' }), s, ctx);\n })\n ),\n },\n {\n name: 'xp-gain',\n kind: 'enter',\n description: 'A “+50 XP” label (`text`, or `data-xp`) floats up from the element and fades (`color`).',\n defaults: { text: '', color: '#7c5cff', duration: 1100 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const s = floater(el, o.text || `+${el.dataset.xp || 10} XP`, { font: '800 16px/1 system-ui,sans-serif', color: o.color, textShadow: '0 1px 0 #fff' });\n return fin(ctx.animate(s, [{ transform: 'translateY(0) scale(.6)', opacity: 0 }, { transform: 'translateY(-18px) scale(1.15)', opacity: 1, offset: 0.25 }, { transform: 'translateY(-50px) scale(1)', opacity: 0 }], { duration: o.duration, easing: 'ease-out' }), s, ctx);\n },\n },\n];\n\n/** Register the 7.5 gamification pack (idempotent). */\nexport function registerGamePack(): void {\n registerEffects(GAME_FX);\n}\n"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ var components_fxMusic = require('./fx-music.cjs');
14
14
  var components_fxChart = require('./fx-chart.cjs');
15
15
  var components_fxShop = require('./fx-shop.cjs');
16
16
  var components_fxSocial = require('./fx-social.cjs');
17
+ var components_fxGame = require('./fx-game.cjs');
17
18
  require('../chunks/registry-DehBVRDV.cjs');
18
19
  require('../chunks/base-BaQV-2ha.cjs');
19
20
  require('../chunks/generative-BHIj-NU0.cjs');
@@ -35,6 +36,7 @@ const EFFECT_PACKS = {
35
36
  chart: components_fxChart.CHART_FX,
36
37
  shop: components_fxShop.SHOP_FX,
37
38
  social: components_fxSocial.SOCIAL_FX,
39
+ game: components_fxGame.GAME_FX,
38
40
  };
39
41
  /** Register every 6.x effect pack (idempotent). */
40
42
  function registerEffectPacks() {
@@ -51,6 +53,7 @@ function registerEffectPacks() {
51
53
  components_fxChart.registerChartPack();
52
54
  components_fxShop.registerShopPack();
53
55
  components_fxSocial.registerSocialPack();
56
+ components_fxGame.registerGamePack();
54
57
  }
55
58
 
56
59
  exports.EFFECT_PACK_FORMAT = components_marketplace.EFFECT_PACK_FORMAT;
@@ -105,6 +108,9 @@ exports.registerShopPack = components_fxShop.registerShopPack;
105
108
  exports.SOCIAL_FX = components_fxSocial.SOCIAL_FX;
106
109
  exports.fanAngles = components_fxSocial.fanAngles;
107
110
  exports.registerSocialPack = components_fxSocial.registerSocialPack;
111
+ exports.GAME_FX = components_fxGame.GAME_FX;
112
+ exports.registerGamePack = components_fxGame.registerGamePack;
113
+ exports.throwPath = components_fxGame.throwPath;
108
114
  exports.EFFECT_PACKS = EFFECT_PACKS;
109
115
  exports.registerEffectPacks = registerEffectPacks;
110
116
  //# sourceMappingURL=fx2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"fx2.cjs","sources":["../../src/components/fx2/index.ts"],"sourcesContent":["/**\n * The 6.x effect packs, one entry each (`motionary/components/fx-gpu`, …) so\n * their size budgets stay separate. This module (`registerFx2()`) registers\n * them all — used by dist/widgets.umd.js and the showcase.\n */\nimport type { EffectDefinition } from '../fx/registry';\nexport { EFFECT_PACK_FORMAT, packManifest, validateManifest, loadEffectPack } from './manifest';\nexport type { EffectPackManifest } from './manifest';\nimport { GPU_FX, registerGpuPack } from './gpu';\nimport { TEXT3_FX, registerTextPack, splitChars } from './text3';\nimport { LIGHT_FX, registerLightPack, trackPointer } from './light';\nimport { DEPTH3_FX, register3dPack } from './depth3';\nimport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath } from './morph2';\nimport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions } from './transitions2';\nimport { WEATHER_FX, registerWeatherPack, skyAt } from './weather';\nimport { PHYSICS2_FX, registerPhysicsPack, VerletWorld } from './physics2';\nimport { FOCUS_FX, registerFocusPack } from './focus';\nimport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample } from './music';\nimport { CHART_FX, registerChartPack, parseFigure } from './chart';\nimport { SHOP_FX, registerShopPack, arcPath } from './shop';\nimport { SOCIAL_FX, registerSocialPack, fanAngles } from './social';\n\nexport { GPU_FX, registerGpuPack, TEXT3_FX, registerTextPack, splitChars };\nexport { shaderBackground, supportsWebGL2, fieldFallback, GLSL_HEAD } from './gl';\nexport { supportsWebGPU, glslToWgsl, wgslModule, webgpuBackground, WGSL_HEAD } from './webgpu';\nexport type { ShaderSpec } from './gl';\n\nexport { LIGHT_FX, registerLightPack, trackPointer };\n\nexport { DEPTH3_FX, register3dPack };\n\nexport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath };\n\nexport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions };\n\nexport { WEATHER_FX, registerWeatherPack, skyAt };\n\nexport { PHYSICS2_FX, registerPhysicsPack, VerletWorld };\n\nexport { FOCUS_FX, registerFocusPack };\n\nexport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample };\n\nexport { CHART_FX, registerChartPack, parseFigure };\n\nexport { SHOP_FX, registerShopPack, arcPath };\n\nexport { SOCIAL_FX, registerSocialPack, fanAngles };\n\n/** The 6.x effect packs by name. */\nexport const EFFECT_PACKS: Record<string, EffectDefinition[]> = {\n gpu: GPU_FX,\n text: TEXT3_FX,\n light: LIGHT_FX,\n depth: DEPTH3_FX,\n morph: MORPH2_FX,\n transitions: TRANSITIONS2_FX,\n weather: WEATHER_FX,\n physics: PHYSICS2_FX,\n focus: FOCUS_FX,\n music: MUSIC_FX,\n chart: CHART_FX,\n shop: SHOP_FX,\n social: SOCIAL_FX,\n};\n\n/** Register every 6.x effect pack (idempotent). */\nexport function registerEffectPacks(): void {\n registerGpuPack();\n registerTextPack();\n registerLightPack();\n register3dPack();\n registerMorphPack();\n registerTransitionsPack();\n registerWeatherPack();\n registerPhysicsPack();\n registerFocusPack();\n registerMusicPack();\n registerChartPack();\n registerShopPack();\n registerSocialPack();\n}\n\n\n"],"names":["GPU_FX","TEXT3_FX","LIGHT_FX","DEPTH3_FX","MORPH2_FX","TRANSITIONS2_FX","WEATHER_FX","PHYSICS2_FX","FOCUS_FX","MUSIC_FX","CHART_FX","SHOP_FX","SOCIAL_FX","registerGpuPack","registerTextPack","registerLightPack","register3dPack","registerMorphPack","registerTransitionsPack","registerWeatherPack","registerPhysicsPack","registerFocusPack","registerMusicPack","registerChartPack","registerShopPack","registerSocialPack"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiDA;AACO,MAAM,YAAY,GAAuC;AAC9D,IAAA,GAAG,EAAEA,uBAAM;AACX,IAAA,IAAI,EAAEC,0BAAQ;AACd,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,yBAAS;AAChB,IAAA,KAAK,EAAEC,4BAAS;AAChB,IAAA,WAAW,EAAEC,wCAAe;AAC5B,IAAA,OAAO,EAAEC,+BAAU;AACnB,IAAA,OAAO,EAAEC,gCAAW;AACpB,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,IAAI,EAAEC,yBAAO;AACb,IAAA,MAAM,EAAEC,6BAAS;;AAGnB;SACgB,mBAAmB,GAAA;AACjC,IAAAC,gCAAe,EAAE;AACjB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,8BAAc,EAAE;AAChB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,gDAAuB,EAAE;AACzB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,sCAAkB,EAAE;AACtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"fx2.cjs","sources":["../../src/components/fx2/index.ts"],"sourcesContent":["/**\n * The 6.x effect packs, one entry each (`motionary/components/fx-gpu`, …) so\n * their size budgets stay separate. This module (`registerFx2()`) registers\n * them all — used by dist/widgets.umd.js and the showcase.\n */\nimport type { EffectDefinition } from '../fx/registry';\nexport { EFFECT_PACK_FORMAT, packManifest, validateManifest, loadEffectPack } from './manifest';\nexport type { EffectPackManifest } from './manifest';\nimport { GPU_FX, registerGpuPack } from './gpu';\nimport { TEXT3_FX, registerTextPack, splitChars } from './text3';\nimport { LIGHT_FX, registerLightPack, trackPointer } from './light';\nimport { DEPTH3_FX, register3dPack } from './depth3';\nimport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath } from './morph2';\nimport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions } from './transitions2';\nimport { WEATHER_FX, registerWeatherPack, skyAt } from './weather';\nimport { PHYSICS2_FX, registerPhysicsPack, VerletWorld } from './physics2';\nimport { FOCUS_FX, registerFocusPack } from './focus';\nimport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample } from './music';\nimport { CHART_FX, registerChartPack, parseFigure } from './chart';\nimport { SHOP_FX, registerShopPack, arcPath } from './shop';\nimport { SOCIAL_FX, registerSocialPack, fanAngles } from './social';\nimport { GAME_FX, registerGamePack, throwPath } from './game';\n\nexport { GPU_FX, registerGpuPack, TEXT3_FX, registerTextPack, splitChars };\nexport { shaderBackground, supportsWebGL2, fieldFallback, GLSL_HEAD } from './gl';\nexport { supportsWebGPU, glslToWgsl, wgslModule, webgpuBackground, WGSL_HEAD } from './webgpu';\nexport type { ShaderSpec } from './gl';\n\nexport { LIGHT_FX, registerLightPack, trackPointer };\n\nexport { DEPTH3_FX, register3dPack };\n\nexport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath };\n\nexport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions };\n\nexport { WEATHER_FX, registerWeatherPack, skyAt };\n\nexport { PHYSICS2_FX, registerPhysicsPack, VerletWorld };\n\nexport { FOCUS_FX, registerFocusPack };\n\nexport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample };\n\nexport { CHART_FX, registerChartPack, parseFigure };\n\nexport { SHOP_FX, registerShopPack, arcPath };\n\nexport { SOCIAL_FX, registerSocialPack, fanAngles };\n\nexport { GAME_FX, registerGamePack, throwPath };\n\n/** The 6.x effect packs by name. */\nexport const EFFECT_PACKS: Record<string, EffectDefinition[]> = {\n gpu: GPU_FX,\n text: TEXT3_FX,\n light: LIGHT_FX,\n depth: DEPTH3_FX,\n morph: MORPH2_FX,\n transitions: TRANSITIONS2_FX,\n weather: WEATHER_FX,\n physics: PHYSICS2_FX,\n focus: FOCUS_FX,\n music: MUSIC_FX,\n chart: CHART_FX,\n shop: SHOP_FX,\n social: SOCIAL_FX,\n game: GAME_FX,\n};\n\n/** Register every 6.x effect pack (idempotent). */\nexport function registerEffectPacks(): void {\n registerGpuPack();\n registerTextPack();\n registerLightPack();\n register3dPack();\n registerMorphPack();\n registerTransitionsPack();\n registerWeatherPack();\n registerPhysicsPack();\n registerFocusPack();\n registerMusicPack();\n registerChartPack();\n registerShopPack();\n registerSocialPack();\n registerGamePack();\n}\n\n\n"],"names":["GPU_FX","TEXT3_FX","LIGHT_FX","DEPTH3_FX","MORPH2_FX","TRANSITIONS2_FX","WEATHER_FX","PHYSICS2_FX","FOCUS_FX","MUSIC_FX","CHART_FX","SHOP_FX","SOCIAL_FX","GAME_FX","registerGpuPack","registerTextPack","registerLightPack","register3dPack","registerMorphPack","registerTransitionsPack","registerWeatherPack","registerPhysicsPack","registerFocusPack","registerMusicPack","registerChartPack","registerShopPack","registerSocialPack","registerGamePack"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoDA;AACO,MAAM,YAAY,GAAuC;AAC9D,IAAA,GAAG,EAAEA,uBAAM;AACX,IAAA,IAAI,EAAEC,0BAAQ;AACd,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,yBAAS;AAChB,IAAA,KAAK,EAAEC,4BAAS;AAChB,IAAA,WAAW,EAAEC,wCAAe;AAC5B,IAAA,OAAO,EAAEC,+BAAU;AACnB,IAAA,OAAO,EAAEC,gCAAW;AACpB,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,IAAI,EAAEC,yBAAO;AACb,IAAA,MAAM,EAAEC,6BAAS;AACjB,IAAA,IAAI,EAAEC,yBAAO;;AAGf;SACgB,mBAAmB,GAAA;AACjC,IAAAC,gCAAe,EAAE;AACjB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,8BAAc,EAAE;AAChB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,gDAAuB,EAAE;AACzB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,sCAAkB,EAAE;AACpB,IAAAC,kCAAgB,EAAE;AACpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -489,6 +489,32 @@ declare const SOCIAL_FX: EffectDefinition[];
489
489
  /** Register the 7.4 chat & social pack (idempotent). */
490
490
  declare function registerSocialPack(): void;
491
491
 
492
+ /**
493
+ * 7.5 — Gamification motion (`motionary/fx/game`, also
494
+ * `motionary/components/fx-game`):
495
+ *
496
+ * - `achievement-unlock` (attention) — the element slides in, a light sweep
497
+ * crosses it and its icon (`[data-icon]` or first child) pops.
498
+ * - `level-up` (attention) — a scale-up with a ring shockwave.
499
+ * - `chest-open` (click) — the lid (`[data-lid]` or first child) flips open
500
+ * and sparks fly out.
501
+ * - `coin-burst` (click) — coins (`coin`, default 🪙) arc up and fall.
502
+ * - `xp-gain` (enter) — a “+50 XP” label (`text` or `data-xp`) floats up and
503
+ * fades.
504
+ *
505
+ * Reduced motion: unlock / level-up fade, chest-open sets the lid open,
506
+ * coin-burst and xp-gain do nothing.
507
+ */
508
+
509
+ /** Ballistic keyframe points for a coin thrown at `deg` with `power` (7.5). */
510
+ declare function throwPath(deg: number, power?: number, steps?: number, g?: number): {
511
+ x: number;
512
+ y: number;
513
+ }[];
514
+ declare const GAME_FX: EffectDefinition[];
515
+ /** Register the 7.5 gamification pack (idempotent). */
516
+ declare function registerGamePack(): void;
517
+
492
518
  /**
493
519
  * 5.5 — generative backgrounds on Canvas 2D, registered through
494
520
  * `registerEffect()` (kind `background`): `flow-field`, `voronoi`,
@@ -598,5 +624,5 @@ declare const EFFECT_PACKS: Record<string, EffectDefinition[]>;
598
624
  /** Register every 6.x effect pack (idempotent). */
599
625
  declare function registerEffectPacks(): void;
600
626
 
601
- export { CHART_FX, DEPTH3_FX, EFFECT_PACKS, EFFECT_PACK_FORMAT, FOCUS_FX, GLSL_HEAD, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, PHYSICS2_FX, SHOP_FX, SOCIAL_FX, TEXT3_FX, TRANSITIONS2_FX, VerletWorld, WEATHER_FX, WGSL_HEAD, arcPath, crossDocumentTransitions, fanAngles, fieldFallback, glslToWgsl, loadEffectPack, musicSample, packManifest, pageTransition, parseFigure, pointsToPath, register3dPack, registerChartPack, registerEffectPacks, registerFocusPack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerPhysicsPack, registerShopPack, registerSocialPack, registerTextPack, registerTransitionsPack, registerWeatherPack, samplePath, shaderBackground, skyAt, splitChars, supportsWebGL2, supportsWebGPU, syntheticSample, trackPointer, validateManifest, webgpuBackground, wgslModule };
627
+ export { CHART_FX, DEPTH3_FX, EFFECT_PACKS, EFFECT_PACK_FORMAT, FOCUS_FX, GAME_FX, GLSL_HEAD, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, PHYSICS2_FX, SHOP_FX, SOCIAL_FX, TEXT3_FX, TRANSITIONS2_FX, VerletWorld, WEATHER_FX, WGSL_HEAD, arcPath, crossDocumentTransitions, fanAngles, fieldFallback, glslToWgsl, loadEffectPack, musicSample, packManifest, pageTransition, parseFigure, pointsToPath, register3dPack, registerChartPack, registerEffectPacks, registerFocusPack, registerGamePack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerPhysicsPack, registerShopPack, registerSocialPack, registerTextPack, registerTransitionsPack, registerWeatherPack, samplePath, shaderBackground, skyAt, splitChars, supportsWebGL2, supportsWebGPU, syntheticSample, throwPath, trackPointer, validateManifest, webgpuBackground, wgslModule };
602
628
  export type { EffectPackManifest, ShaderSpec };