use-scroll-animate 8.1.0 → 8.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [8.3.0] - 2026-10-09
11
+
12
+ ### Added
13
+ - **2 new components (8.3)** in `motionary/components/widgets` (also in `dist/widgets.umd.js`):
14
+ - `<usa-organic-card>` — card with a soft, living blob outline: breathes slowly while on screen, morphs on hover (`morph(seed)`), `tint` leaf · ocean · petal · sand, `seed` for the starting shape.
15
+ - `<usa-liquid-nav>` — navigation bar with a liquid-drop indicator that stretches towards the next item and settles with a wobble (gooey SVG filter); children are links / buttons, `aria-current="page"`, `value`, arrow keys, `label`; `usa:change` { index, item }.
16
+ - **Organic pack — `motionary/fx/organic`** (= `motionary/components/fx-organic`, `registerOrganicPack()`, also in `registerEffectPacks()`): `vine-grow` (enter), `bloom` (enter), `water-drop` (attention), `breathe` (loop). `blobRadius()`.
17
+ - Showcase: 4 new gallery cards with copyable code, live demos and live Store thumbnails; Animation Store 343 → 347 items.
18
+
19
+ ### Accessibility
20
+ - Liquid nav is a labelled `navigation` that keeps `aria-current="page"` on the active item and moves focus with ← / →; the drop is `aria-hidden`. Organic card keeps your content and shows a focus ring when something inside is focused. Reduced motion: static blob, the drop jumps, `vine-grow` shows the vine, `bloom` fades in, `water-drop` does nothing, `breathe` is skipped.
21
+
22
+ ## [8.2.0] - 2026-10-08
23
+
24
+ ### Added
25
+ - **2 new components (8.2)** in `motionary/components/widgets` (also in `dist/widgets.umd.js`):
26
+ - `<usa-terminal>` — retro terminal window: child `<p data-cmd>` lines are typed after the `prompt` (default `$`) with a blinking block cursor, other children print as output, line by line, when it scrolls into view; `title`, `theme` (dark · green · amber phosphor glow), `speed`, `loop`; `replay()`, `skip()`; `usa:done`.
27
+ - `<usa-retro-button variant="pixel | crt | y2k | win95">` — retro buttons with era-true press motion (stepped 8-bit press, phosphor flicker, chrome bounce, bevel sink); the content becomes a real `<button>` (`type`, `disabled`, `name`, `value`); `RETRO_VARIANTS`.
28
+ - **Retro pack — `motionary/fx/retro`** (= `motionary/components/fx-retro`, `registerRetroPack()`, also in `registerEffectPacks()`): `pixelate-in` (enter), `crt-power` (enter), `vhs-glitch` (attention), `y2k-shine` (attention). `pixelSteps()`. (The 5.8 theme effects `retro` / `retro-scanlines` are unchanged.)
29
+ - Showcase: 4 new gallery cards with copyable code, live demos and live Store thumbnails; Animation Store 339 → 343 items.
30
+
31
+ ### Accessibility
32
+ - Terminal output is a labelled `role="log"`; the prompt and cursor are `aria-hidden`. Retro buttons are real `<button>`s with visible focus styles per variant. Reduced motion: the terminal shows everything at once (no blink), buttons only change colour, `pixelate-in` / `crt-power` fade in, `vhs-glitch` does nothing, `y2k-shine` is a short brightness flash.
33
+
10
34
  ## [8.1.0] - 2026-10-08
11
35
 
12
36
  ### Added
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ var registry = require('../chunks/registry-BVklOepd.cjs');
4
+ require('../chunks/base-DoRUZBy-.cjs');
5
+
6
+ /** A blob border-radius ("63% 37% 54% 46% / 55% 48% 52% 45%") from a seed (8.3). */
7
+ function blobRadius(seed) {
8
+ let s = Math.abs(Math.round(seed * 1000)) % 233280 || 7;
9
+ const r = () => 30 + ((s = (s * 9301 + 49297) % 233280) / 233280) * 40;
10
+ const a = [r(), r(), r(), r()].map(Math.round);
11
+ const b = [r(), r(), r(), r()].map(Math.round);
12
+ return `${a[0]}% ${100 - a[0]}% ${a[2]}% ${100 - a[2]}% / ${b[0]}% ${b[1]}% ${100 - b[1]}% ${100 - b[0]}%`;
13
+ }
14
+ const fade = (el, ctx) => ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);
15
+ const ORGANIC_FX = [
16
+ {
17
+ name: 'vine-grow',
18
+ kind: 'enter',
19
+ description: 'SVG paths grow along their length like a vine; `[data-leaf]` / circles pop in along the way (`duration`).',
20
+ defaults: { duration: 1600 },
21
+ run: (el, o, ctx) => {
22
+ if (ctx.reduced)
23
+ return;
24
+ const paths = Array.from(el.querySelectorAll('path, polyline, line'));
25
+ const leaves = Array.from(el.querySelectorAll('[data-leaf], circle, ellipse'));
26
+ const runs = paths.map((p) => {
27
+ let len = 300;
28
+ try {
29
+ len = p.getTotalLength?.() || 300;
30
+ }
31
+ catch {
32
+ /* not rendered */
33
+ }
34
+ const prev = p.style.strokeDasharray;
35
+ p.style.strokeDasharray = `${len}`;
36
+ ctx.onCleanup(() => (p.style.strokeDasharray = prev));
37
+ return ctx.animate(p, [{ strokeDashoffset: `${len}` }, { strokeDashoffset: '0' }], { duration: o.duration, easing: 'cubic-bezier(.4,.1,.3,1)', fill: 'backwards' })?.finished.catch(() => undefined);
38
+ });
39
+ leaves.forEach((l, i) => {
40
+ l.style.transformBox = 'fill-box';
41
+ l.style.transformOrigin = 'center';
42
+ runs.push(ctx.animate(l, [{ transform: 'scale(0) rotate(-40deg)', opacity: 0 }, { transform: 'scale(1.2) rotate(8deg)', opacity: 1, offset: 0.7 }, { transform: 'none', opacity: 1 }], { duration: 500, delay: (o.duration * (i + 1)) / (leaves.length + 1), easing: 'ease-out', fill: 'backwards' })?.finished.catch(() => undefined));
43
+ });
44
+ return Promise.all(runs).then(() => undefined);
45
+ },
46
+ },
47
+ {
48
+ name: 'bloom',
49
+ kind: 'enter',
50
+ description: "The element's children unfold from the centre like petals, or the element blooms open (`stagger`).",
51
+ defaults: { stagger: 70, duration: 700 },
52
+ run: (el, o, ctx) => {
53
+ const kids = Array.from(el.children);
54
+ const items = kids.length > 1 ? kids : [el];
55
+ return Promise.all(items.map((k, i) => {
56
+ if (ctx.reduced)
57
+ return fade(k, ctx);
58
+ const rot = (i % 2 ? 1 : -1) * (25 + i * 6);
59
+ return ctx.animate(k, [{ transform: `scale(0) rotate(${rot}deg)`, opacity: 0 }, { transform: 'scale(1.1) rotate(-3deg)', opacity: 1, offset: 0.65 }, { transform: 'none', opacity: 1 }], { duration: o.duration, delay: i * o.stagger, easing: 'cubic-bezier(.3,1.3,.5,1)', fill: 'backwards' })?.finished.catch(() => undefined);
60
+ })).then(() => undefined);
61
+ },
62
+ },
63
+ {
64
+ name: 'water-drop',
65
+ kind: 'attention',
66
+ description: 'The element dips like a drop hit water and concentric ripples spread out (`rings`, `color`).',
67
+ defaults: { rings: 3, color: 'rgba(14,165,233,.55)', duration: 1200 },
68
+ run: (el, o, ctx) => {
69
+ if (ctx.reduced)
70
+ return;
71
+ if (getComputedStyle(el).position === 'static') {
72
+ const prev = el.style.position;
73
+ el.style.position = 'relative';
74
+ ctx.onCleanup(() => (el.style.position = prev));
75
+ }
76
+ const runs = [ctx.animate(el, [{ transform: 'none' }, { transform: 'scale(.94, .9) translateY(3px)', offset: 0.2 }, { transform: 'scale(1.03, 1.05)', offset: 0.45 }, { transform: 'none' }], { duration: 700, easing: 'ease-out' })?.finished.catch(() => undefined)];
77
+ const n = Math.max(1, Math.min(5, Number(o.rings) || 3));
78
+ for (let i = 0; i < n; i++) {
79
+ const r = document.createElement('span');
80
+ r.setAttribute('aria-hidden', 'true');
81
+ Object.assign(r.style, { position: 'absolute', left: '50%', top: '50%', width: '100%', aspectRatio: '2 / 1', borderRadius: '50%', border: `2px solid ${o.color}`, translate: '-50% -50%', pointerEvents: 'none' });
82
+ el.appendChild(r);
83
+ const end = () => r.remove();
84
+ ctx.onCleanup(end);
85
+ const a = ctx.animate(r, [{ transform: 'scale(.2)', opacity: 1 }, { transform: 'scale(1.9)', opacity: 0 }], { duration: o.duration, delay: 120 + i * 220, easing: 'ease-out', fill: 'backwards' });
86
+ runs.push(a ? a.finished.then(end, end) : (end(), undefined));
87
+ }
88
+ return Promise.all(runs).then(() => undefined);
89
+ },
90
+ },
91
+ {
92
+ name: 'breathe',
93
+ kind: 'loop',
94
+ description: 'A slow organic morph of shape and scale, like a living blob, until the cleanup runs (`duration`).',
95
+ defaults: { duration: 6000 },
96
+ run: (el, o, ctx) => {
97
+ const prev = el.style.borderRadius;
98
+ const frames = [0, 1, 2, 3, 0].map((i, k) => ({ borderRadius: blobRadius(i + 1), transform: `scale(${k % 2 ? 1.04 : 1}) rotate(${k % 2 ? 4 : -2}deg)`, offset: k / 4 }));
99
+ const a = ctx.animate(el, frames, { duration: o.duration, iterations: Infinity, easing: 'ease-in-out' });
100
+ return () => {
101
+ a?.cancel();
102
+ el.style.borderRadius = prev;
103
+ };
104
+ },
105
+ },
106
+ ];
107
+ /** Register vine-grow, bloom, water-drop and breathe (8.3). */
108
+ function registerOrganicPack() {
109
+ registry.registerEffects(ORGANIC_FX);
110
+ }
111
+
112
+ exports.ORGANIC_FX = ORGANIC_FX;
113
+ exports.blobRadius = blobRadius;
114
+ exports.registerOrganicPack = registerOrganicPack;
115
+ //# sourceMappingURL=fx-organic.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-organic.cjs","sources":["../../src/components/fx2/organic.ts"],"sourcesContent":["/**\n * 8.3 — Organic pack (`motionary/fx/organic`, also `motionary/components/fx-organic`):\n *\n * - `vine-grow` (enter) — SVG paths inside grow along their length like a\n * vine and `[data-leaf]` / circles pop in along the way (`duration`).\n * - `bloom` (enter) — the element's children unfold from the centre like\n * petals (or the element itself blooms open) (`stagger`).\n * - `water-drop` (attention) — the element dips like a drop hit water and\n * concentric ripples spread out (`rings`, `color`).\n * - `breathe` (loop) — a slow organic morph of shape and scale, like a\n * living blob; the cleanup stops it (`duration`).\n *\n * Reduced motion: vine-grow shows the vine, bloom fades in, water-drop does\n * nothing, breathe is skipped.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\n\n/** A blob border-radius (\"63% 37% 54% 46% / 55% 48% 52% 45%\") from a seed (8.3). */\nexport function blobRadius(seed: number): string {\n let s = Math.abs(Math.round(seed * 1000)) % 233280 || 7;\n const r = () => 30 + ((s = (s * 9301 + 49297) % 233280) / 233280) * 40;\n const a = [r(), r(), r(), r()].map(Math.round);\n const b = [r(), r(), r(), r()].map(Math.round);\n return `${a[0]}% ${100 - a[0]}% ${a[2]}% ${100 - a[2]}% / ${b[0]}% ${b[1]}% ${100 - b[1]}% ${100 - b[0]}%`;\n}\n\nconst fade = (el: HTMLElement, ctx: EffectContext) => ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);\n\nexport const ORGANIC_FX: EffectDefinition[] = [\n {\n name: 'vine-grow',\n kind: 'enter',\n description: 'SVG paths grow along their length like a vine; `[data-leaf]` / circles pop in along the way (`duration`).',\n defaults: { duration: 1600 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n const paths = Array.from(el.querySelectorAll<SVGGeometryElement>('path, polyline, line'));\n const leaves = Array.from(el.querySelectorAll<SVGElement | HTMLElement>('[data-leaf], circle, ellipse'));\n const runs: (Promise<unknown> | undefined)[] = paths.map((p) => {\n let len = 300;\n try {\n len = p.getTotalLength?.() || 300;\n } catch {\n /* not rendered */\n }\n const prev = p.style.strokeDasharray;\n p.style.strokeDasharray = `${len}`;\n ctx.onCleanup(() => (p.style.strokeDasharray = prev));\n return ctx.animate(p, [{ strokeDashoffset: `${len}` }, { strokeDashoffset: '0' }], { duration: o.duration, easing: 'cubic-bezier(.4,.1,.3,1)', fill: 'backwards' })?.finished.catch(() => undefined);\n });\n leaves.forEach((l, i) => {\n (l as any).style.transformBox = 'fill-box';\n (l as any).style.transformOrigin = 'center';\n runs.push(ctx.animate(l, [{ transform: 'scale(0) rotate(-40deg)', opacity: 0 }, { transform: 'scale(1.2) rotate(8deg)', opacity: 1, offset: 0.7 }, { transform: 'none', opacity: 1 }], { duration: 500, delay: (o.duration * (i + 1)) / (leaves.length + 1), easing: 'ease-out', fill: 'backwards' })?.finished.catch(() => undefined));\n });\n return Promise.all(runs).then(() => undefined);\n },\n },\n {\n name: 'bloom',\n kind: 'enter',\n description: \"The element's children unfold from the centre like petals, or the element blooms open (`stagger`).\",\n defaults: { stagger: 70, duration: 700 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const kids = Array.from(el.children) as HTMLElement[];\n const items = kids.length > 1 ? kids : [el];\n return Promise.all(\n items.map((k, i) => {\n if (ctx.reduced) return fade(k, ctx);\n const rot = (i % 2 ? 1 : -1) * (25 + i * 6);\n return ctx.animate(k, [{ transform: `scale(0) rotate(${rot}deg)`, opacity: 0 }, { transform: 'scale(1.1) rotate(-3deg)', opacity: 1, offset: 0.65 }, { transform: 'none', opacity: 1 }], { duration: o.duration, delay: i * o.stagger, easing: 'cubic-bezier(.3,1.3,.5,1)', fill: 'backwards' })?.finished.catch(() => undefined);\n })\n ).then(() => undefined);\n },\n },\n {\n name: 'water-drop',\n kind: 'attention',\n description: 'The element dips like a drop hit water and concentric ripples spread out (`rings`, `color`).',\n defaults: { rings: 3, color: 'rgba(14,165,233,.55)', duration: 1200 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n if (getComputedStyle(el).position === 'static') {\n const prev = el.style.position;\n el.style.position = 'relative';\n ctx.onCleanup(() => (el.style.position = prev));\n }\n const runs: (Promise<unknown> | undefined)[] = [ctx.animate(el, [{ transform: 'none' }, { transform: 'scale(.94, .9) translateY(3px)', offset: 0.2 }, { transform: 'scale(1.03, 1.05)', offset: 0.45 }, { transform: 'none' }], { duration: 700, easing: 'ease-out' })?.finished.catch(() => undefined)];\n const n = Math.max(1, Math.min(5, Number(o.rings) || 3));\n for (let i = 0; i < n; i++) {\n const r = document.createElement('span');\n r.setAttribute('aria-hidden', 'true');\n Object.assign(r.style, { position: 'absolute', left: '50%', top: '50%', width: '100%', aspectRatio: '2 / 1', borderRadius: '50%', border: `2px solid ${o.color}`, translate: '-50% -50%', pointerEvents: 'none' });\n el.appendChild(r);\n const end = () => r.remove();\n ctx.onCleanup(end);\n const a = ctx.animate(r, [{ transform: 'scale(.2)', opacity: 1 }, { transform: 'scale(1.9)', opacity: 0 }], { duration: o.duration, delay: 120 + i * 220, easing: 'ease-out', fill: 'backwards' });\n runs.push(a ? a.finished.then(end, end) : (end(), undefined));\n }\n return Promise.all(runs).then(() => undefined);\n },\n },\n {\n name: 'breathe',\n kind: 'loop',\n description: 'A slow organic morph of shape and scale, like a living blob, until the cleanup runs (`duration`).',\n defaults: { duration: 6000 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const prev = el.style.borderRadius;\n const frames: Keyframe[] = [0, 1, 2, 3, 0].map((i, k) => ({ borderRadius: blobRadius(i + 1), transform: `scale(${k % 2 ? 1.04 : 1}) rotate(${k % 2 ? 4 : -2}deg)`, offset: k / 4 }));\n const a = ctx.animate(el, frames, { duration: o.duration, iterations: Infinity, easing: 'ease-in-out' });\n return () => {\n a?.cancel();\n el.style.borderRadius = prev;\n };\n },\n },\n];\n\n/** Register vine-grow, bloom, water-drop and breathe (8.3). */\nexport function registerOrganicPack(): void {\n registerEffects(ORGANIC_FX);\n}\n"],"names":["registerEffects"],"mappings":";;;;;AAkBA;AACM,SAAU,UAAU,CAAC,IAAY,EAAA;AACrC,IAAA,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC;IACvD,MAAM,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE;IACtE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9C,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9C,OAAO,CAAA,EAAG,CAAC,CAAC,CAAC,CAAC,CAAA,EAAA,EAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA,EAAA,EAAK,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA,EAAA,EAAK,CAAC,CAAC,CAAC,CAAC,CAAA,EAAA,EAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA,EAAA,EAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA,CAAA,CAAG;AAC5G;AAEA,MAAM,IAAI,GAAG,CAAC,EAAe,EAAE,GAAkB,KAAK,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC;AAEpJ,MAAM,UAAU,GAAuB;AAC5C,IAAA;AACE,QAAA,IAAI,EAAE,WAAW;AACjB,QAAA,IAAI,EAAE,OAAO;AACb,QAAA,WAAW,EAAE,2GAA2G;AACxH,QAAA,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC5B,GAAG,EAAE,CAAC,EAAe,EAAE,CAAM,EAAE,GAAkB,KAAI;YACnD,IAAI,GAAG,CAAC,OAAO;gBAAE;AACjB,YAAA,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAqB,sBAAsB,CAAC,CAAC;AACzF,YAAA,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAA2B,8BAA8B,CAAC,CAAC;YACxG,MAAM,IAAI,GAAqC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAI;gBAC7D,IAAI,GAAG,GAAG,GAAG;AACb,gBAAA,IAAI;oBACF,GAAG,GAAG,CAAC,CAAC,cAAc,IAAI,IAAI,GAAG;gBACnC;AAAE,gBAAA,MAAM;;gBAER;AACA,gBAAA,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,eAAe;gBACpC,CAAC,CAAC,KAAK,CAAC,eAAe,GAAG,CAAA,EAAG,GAAG,EAAE;AAClC,gBAAA,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;gBACrD,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAA,EAAG,GAAG,CAAA,CAAE,EAAE,EAAE,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,0BAA0B,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC;AACtM,YAAA,CAAC,CAAC;YACF,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;AACrB,gBAAA,CAAS,CAAC,KAAK,CAAC,YAAY,GAAG,UAAU;AACzC,gBAAA,CAAS,CAAC,KAAK,CAAC,eAAe,GAAG,QAAQ;gBAC3C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,yBAAyB,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,yBAAyB,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC,CAAC;AACzU,YAAA,CAAC,CAAC;AACF,YAAA,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC;QAChD,CAAC;AACF,KAAA;AACD,IAAA;AACE,QAAA,IAAI,EAAE,OAAO;AACb,QAAA,IAAI,EAAE,OAAO;AACb,QAAA,WAAW,EAAE,oGAAoG;QACjH,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE;QACxC,GAAG,EAAE,CAAC,EAAe,EAAE,CAAM,EAAE,GAAkB,KAAI;YACnD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAkB;AACrD,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC;AAC3C,YAAA,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;gBACjB,IAAI,GAAG,CAAC,OAAO;AAAE,oBAAA,OAAO,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC;gBACpC,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;AAC3C,gBAAA,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,mBAAmB,GAAG,CAAA,IAAA,CAAM,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,0BAA0B,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,2BAA2B,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC;YACnU,CAAC,CAAC,CACH,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC;QACzB,CAAC;AACF,KAAA;AACD,IAAA;AACE,QAAA,IAAI,EAAE,YAAY;AAClB,QAAA,IAAI,EAAE,WAAW;AACjB,QAAA,WAAW,EAAE,8FAA8F;AAC3G,QAAA,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,QAAQ,EAAE,IAAI,EAAE;QACrE,GAAG,EAAE,CAAC,EAAe,EAAE,CAAM,EAAE,GAAkB,KAAI;YACnD,IAAI,GAAG,CAAC,OAAO;gBAAE;YACjB,IAAI,gBAAgB,CAAC,EAAE,CAAC,CAAC,QAAQ,KAAK,QAAQ,EAAE;AAC9C,gBAAA,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ;AAC9B,gBAAA,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU;AAC9B,gBAAA,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;YACjD;AACA,YAAA,MAAM,IAAI,GAAqC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,gCAAgC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC,CAAC;YACxS,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AACxD,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;gBAC1B,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC;AACxC,gBAAA,CAAC,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC;gBACrC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA,UAAA,EAAa,CAAC,CAAC,KAAK,CAAA,CAAE,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;AAClN,gBAAA,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,MAAM,EAAE;AAC5B,gBAAA,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC;gBAClB,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;gBAClM,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;YAC/D;AACA,YAAA,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC;QAChD,CAAC;AACF,KAAA;AACD,IAAA;AACE,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,WAAW,EAAE,mGAAmG;AAChH,QAAA,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC5B,GAAG,EAAE,CAAC,EAAe,EAAE,CAAM,EAAE,GAAkB,KAAI;AACnD,YAAA,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY;AAClC,YAAA,MAAM,MAAM,GAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,CAAA,MAAA,EAAS,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAA,SAAA,EAAY,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA,IAAA,CAAM,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpL,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AACxG,YAAA,OAAO,MAAK;gBACV,CAAC,EAAE,MAAM,EAAE;AACX,gBAAA,EAAE,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI;AAC9B,YAAA,CAAC;QACH,CAAC;AACF,KAAA;;AAGH;SACgB,mBAAmB,GAAA;IACjCA,wBAAe,CAAC,UAAU,CAAC;AAC7B;;;;;;"}
@@ -0,0 +1,66 @@
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
+ * 8.3 — Organic pack (`motionary/fx/organic`, also `motionary/components/fx-organic`):
46
+ *
47
+ * - `vine-grow` (enter) — SVG paths inside grow along their length like a
48
+ * vine and `[data-leaf]` / circles pop in along the way (`duration`).
49
+ * - `bloom` (enter) — the element's children unfold from the centre like
50
+ * petals (or the element itself blooms open) (`stagger`).
51
+ * - `water-drop` (attention) — the element dips like a drop hit water and
52
+ * concentric ripples spread out (`rings`, `color`).
53
+ * - `breathe` (loop) — a slow organic morph of shape and scale, like a
54
+ * living blob; the cleanup stops it (`duration`).
55
+ *
56
+ * Reduced motion: vine-grow shows the vine, bloom fades in, water-drop does
57
+ * nothing, breathe is skipped.
58
+ */
59
+
60
+ /** A blob border-radius ("63% 37% 54% 46% / 55% 48% 52% 45%") from a seed (8.3). */
61
+ declare function blobRadius(seed: number): string;
62
+ declare const ORGANIC_FX: EffectDefinition[];
63
+ /** Register vine-grow, bloom, water-drop and breathe (8.3). */
64
+ declare function registerOrganicPack(): void;
65
+
66
+ export { ORGANIC_FX, blobRadius, registerOrganicPack };
@@ -0,0 +1,66 @@
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
+ * 8.3 — Organic pack (`motionary/fx/organic`, also `motionary/components/fx-organic`):
46
+ *
47
+ * - `vine-grow` (enter) — SVG paths inside grow along their length like a
48
+ * vine and `[data-leaf]` / circles pop in along the way (`duration`).
49
+ * - `bloom` (enter) — the element's children unfold from the centre like
50
+ * petals (or the element itself blooms open) (`stagger`).
51
+ * - `water-drop` (attention) — the element dips like a drop hit water and
52
+ * concentric ripples spread out (`rings`, `color`).
53
+ * - `breathe` (loop) — a slow organic morph of shape and scale, like a
54
+ * living blob; the cleanup stops it (`duration`).
55
+ *
56
+ * Reduced motion: vine-grow shows the vine, bloom fades in, water-drop does
57
+ * nothing, breathe is skipped.
58
+ */
59
+
60
+ /** A blob border-radius ("63% 37% 54% 46% / 55% 48% 52% 45%") from a seed (8.3). */
61
+ declare function blobRadius(seed: number): string;
62
+ declare const ORGANIC_FX: EffectDefinition[];
63
+ /** Register vine-grow, bloom, water-drop and breathe (8.3). */
64
+ declare function registerOrganicPack(): void;
65
+
66
+ export { ORGANIC_FX, blobRadius, registerOrganicPack };
@@ -0,0 +1,111 @@
1
+ import { registerEffects } from '../chunks/registry-CnO7ZVPK.js';
2
+ import '../chunks/base-CLuqlLfG.js';
3
+
4
+ /** A blob border-radius ("63% 37% 54% 46% / 55% 48% 52% 45%") from a seed (8.3). */
5
+ function blobRadius(seed) {
6
+ let s = Math.abs(Math.round(seed * 1000)) % 233280 || 7;
7
+ const r = () => 30 + ((s = (s * 9301 + 49297) % 233280) / 233280) * 40;
8
+ const a = [r(), r(), r(), r()].map(Math.round);
9
+ const b = [r(), r(), r(), r()].map(Math.round);
10
+ return `${a[0]}% ${100 - a[0]}% ${a[2]}% ${100 - a[2]}% / ${b[0]}% ${b[1]}% ${100 - b[1]}% ${100 - b[0]}%`;
11
+ }
12
+ const fade = (el, ctx) => ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);
13
+ const ORGANIC_FX = [
14
+ {
15
+ name: 'vine-grow',
16
+ kind: 'enter',
17
+ description: 'SVG paths grow along their length like a vine; `[data-leaf]` / circles pop in along the way (`duration`).',
18
+ defaults: { duration: 1600 },
19
+ run: (el, o, ctx) => {
20
+ if (ctx.reduced)
21
+ return;
22
+ const paths = Array.from(el.querySelectorAll('path, polyline, line'));
23
+ const leaves = Array.from(el.querySelectorAll('[data-leaf], circle, ellipse'));
24
+ const runs = paths.map((p) => {
25
+ let len = 300;
26
+ try {
27
+ len = p.getTotalLength?.() || 300;
28
+ }
29
+ catch {
30
+ /* not rendered */
31
+ }
32
+ const prev = p.style.strokeDasharray;
33
+ p.style.strokeDasharray = `${len}`;
34
+ ctx.onCleanup(() => (p.style.strokeDasharray = prev));
35
+ return ctx.animate(p, [{ strokeDashoffset: `${len}` }, { strokeDashoffset: '0' }], { duration: o.duration, easing: 'cubic-bezier(.4,.1,.3,1)', fill: 'backwards' })?.finished.catch(() => undefined);
36
+ });
37
+ leaves.forEach((l, i) => {
38
+ l.style.transformBox = 'fill-box';
39
+ l.style.transformOrigin = 'center';
40
+ runs.push(ctx.animate(l, [{ transform: 'scale(0) rotate(-40deg)', opacity: 0 }, { transform: 'scale(1.2) rotate(8deg)', opacity: 1, offset: 0.7 }, { transform: 'none', opacity: 1 }], { duration: 500, delay: (o.duration * (i + 1)) / (leaves.length + 1), easing: 'ease-out', fill: 'backwards' })?.finished.catch(() => undefined));
41
+ });
42
+ return Promise.all(runs).then(() => undefined);
43
+ },
44
+ },
45
+ {
46
+ name: 'bloom',
47
+ kind: 'enter',
48
+ description: "The element's children unfold from the centre like petals, or the element blooms open (`stagger`).",
49
+ defaults: { stagger: 70, duration: 700 },
50
+ run: (el, o, ctx) => {
51
+ const kids = Array.from(el.children);
52
+ const items = kids.length > 1 ? kids : [el];
53
+ return Promise.all(items.map((k, i) => {
54
+ if (ctx.reduced)
55
+ return fade(k, ctx);
56
+ const rot = (i % 2 ? 1 : -1) * (25 + i * 6);
57
+ return ctx.animate(k, [{ transform: `scale(0) rotate(${rot}deg)`, opacity: 0 }, { transform: 'scale(1.1) rotate(-3deg)', opacity: 1, offset: 0.65 }, { transform: 'none', opacity: 1 }], { duration: o.duration, delay: i * o.stagger, easing: 'cubic-bezier(.3,1.3,.5,1)', fill: 'backwards' })?.finished.catch(() => undefined);
58
+ })).then(() => undefined);
59
+ },
60
+ },
61
+ {
62
+ name: 'water-drop',
63
+ kind: 'attention',
64
+ description: 'The element dips like a drop hit water and concentric ripples spread out (`rings`, `color`).',
65
+ defaults: { rings: 3, color: 'rgba(14,165,233,.55)', duration: 1200 },
66
+ run: (el, o, ctx) => {
67
+ if (ctx.reduced)
68
+ return;
69
+ if (getComputedStyle(el).position === 'static') {
70
+ const prev = el.style.position;
71
+ el.style.position = 'relative';
72
+ ctx.onCleanup(() => (el.style.position = prev));
73
+ }
74
+ const runs = [ctx.animate(el, [{ transform: 'none' }, { transform: 'scale(.94, .9) translateY(3px)', offset: 0.2 }, { transform: 'scale(1.03, 1.05)', offset: 0.45 }, { transform: 'none' }], { duration: 700, easing: 'ease-out' })?.finished.catch(() => undefined)];
75
+ const n = Math.max(1, Math.min(5, Number(o.rings) || 3));
76
+ for (let i = 0; i < n; i++) {
77
+ const r = document.createElement('span');
78
+ r.setAttribute('aria-hidden', 'true');
79
+ Object.assign(r.style, { position: 'absolute', left: '50%', top: '50%', width: '100%', aspectRatio: '2 / 1', borderRadius: '50%', border: `2px solid ${o.color}`, translate: '-50% -50%', pointerEvents: 'none' });
80
+ el.appendChild(r);
81
+ const end = () => r.remove();
82
+ ctx.onCleanup(end);
83
+ const a = ctx.animate(r, [{ transform: 'scale(.2)', opacity: 1 }, { transform: 'scale(1.9)', opacity: 0 }], { duration: o.duration, delay: 120 + i * 220, easing: 'ease-out', fill: 'backwards' });
84
+ runs.push(a ? a.finished.then(end, end) : (end(), undefined));
85
+ }
86
+ return Promise.all(runs).then(() => undefined);
87
+ },
88
+ },
89
+ {
90
+ name: 'breathe',
91
+ kind: 'loop',
92
+ description: 'A slow organic morph of shape and scale, like a living blob, until the cleanup runs (`duration`).',
93
+ defaults: { duration: 6000 },
94
+ run: (el, o, ctx) => {
95
+ const prev = el.style.borderRadius;
96
+ const frames = [0, 1, 2, 3, 0].map((i, k) => ({ borderRadius: blobRadius(i + 1), transform: `scale(${k % 2 ? 1.04 : 1}) rotate(${k % 2 ? 4 : -2}deg)`, offset: k / 4 }));
97
+ const a = ctx.animate(el, frames, { duration: o.duration, iterations: Infinity, easing: 'ease-in-out' });
98
+ return () => {
99
+ a?.cancel();
100
+ el.style.borderRadius = prev;
101
+ };
102
+ },
103
+ },
104
+ ];
105
+ /** Register vine-grow, bloom, water-drop and breathe (8.3). */
106
+ function registerOrganicPack() {
107
+ registerEffects(ORGANIC_FX);
108
+ }
109
+
110
+ export { ORGANIC_FX, blobRadius, registerOrganicPack };
111
+ //# sourceMappingURL=fx-organic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-organic.js","sources":["../../src/components/fx2/organic.ts"],"sourcesContent":["/**\n * 8.3 — Organic pack (`motionary/fx/organic`, also `motionary/components/fx-organic`):\n *\n * - `vine-grow` (enter) — SVG paths inside grow along their length like a\n * vine and `[data-leaf]` / circles pop in along the way (`duration`).\n * - `bloom` (enter) — the element's children unfold from the centre like\n * petals (or the element itself blooms open) (`stagger`).\n * - `water-drop` (attention) — the element dips like a drop hit water and\n * concentric ripples spread out (`rings`, `color`).\n * - `breathe` (loop) — a slow organic morph of shape and scale, like a\n * living blob; the cleanup stops it (`duration`).\n *\n * Reduced motion: vine-grow shows the vine, bloom fades in, water-drop does\n * nothing, breathe is skipped.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\n\n/** A blob border-radius (\"63% 37% 54% 46% / 55% 48% 52% 45%\") from a seed (8.3). */\nexport function blobRadius(seed: number): string {\n let s = Math.abs(Math.round(seed * 1000)) % 233280 || 7;\n const r = () => 30 + ((s = (s * 9301 + 49297) % 233280) / 233280) * 40;\n const a = [r(), r(), r(), r()].map(Math.round);\n const b = [r(), r(), r(), r()].map(Math.round);\n return `${a[0]}% ${100 - a[0]}% ${a[2]}% ${100 - a[2]}% / ${b[0]}% ${b[1]}% ${100 - b[1]}% ${100 - b[0]}%`;\n}\n\nconst fade = (el: HTMLElement, ctx: EffectContext) => ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);\n\nexport const ORGANIC_FX: EffectDefinition[] = [\n {\n name: 'vine-grow',\n kind: 'enter',\n description: 'SVG paths grow along their length like a vine; `[data-leaf]` / circles pop in along the way (`duration`).',\n defaults: { duration: 1600 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n const paths = Array.from(el.querySelectorAll<SVGGeometryElement>('path, polyline, line'));\n const leaves = Array.from(el.querySelectorAll<SVGElement | HTMLElement>('[data-leaf], circle, ellipse'));\n const runs: (Promise<unknown> | undefined)[] = paths.map((p) => {\n let len = 300;\n try {\n len = p.getTotalLength?.() || 300;\n } catch {\n /* not rendered */\n }\n const prev = p.style.strokeDasharray;\n p.style.strokeDasharray = `${len}`;\n ctx.onCleanup(() => (p.style.strokeDasharray = prev));\n return ctx.animate(p, [{ strokeDashoffset: `${len}` }, { strokeDashoffset: '0' }], { duration: o.duration, easing: 'cubic-bezier(.4,.1,.3,1)', fill: 'backwards' })?.finished.catch(() => undefined);\n });\n leaves.forEach((l, i) => {\n (l as any).style.transformBox = 'fill-box';\n (l as any).style.transformOrigin = 'center';\n runs.push(ctx.animate(l, [{ transform: 'scale(0) rotate(-40deg)', opacity: 0 }, { transform: 'scale(1.2) rotate(8deg)', opacity: 1, offset: 0.7 }, { transform: 'none', opacity: 1 }], { duration: 500, delay: (o.duration * (i + 1)) / (leaves.length + 1), easing: 'ease-out', fill: 'backwards' })?.finished.catch(() => undefined));\n });\n return Promise.all(runs).then(() => undefined);\n },\n },\n {\n name: 'bloom',\n kind: 'enter',\n description: \"The element's children unfold from the centre like petals, or the element blooms open (`stagger`).\",\n defaults: { stagger: 70, duration: 700 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const kids = Array.from(el.children) as HTMLElement[];\n const items = kids.length > 1 ? kids : [el];\n return Promise.all(\n items.map((k, i) => {\n if (ctx.reduced) return fade(k, ctx);\n const rot = (i % 2 ? 1 : -1) * (25 + i * 6);\n return ctx.animate(k, [{ transform: `scale(0) rotate(${rot}deg)`, opacity: 0 }, { transform: 'scale(1.1) rotate(-3deg)', opacity: 1, offset: 0.65 }, { transform: 'none', opacity: 1 }], { duration: o.duration, delay: i * o.stagger, easing: 'cubic-bezier(.3,1.3,.5,1)', fill: 'backwards' })?.finished.catch(() => undefined);\n })\n ).then(() => undefined);\n },\n },\n {\n name: 'water-drop',\n kind: 'attention',\n description: 'The element dips like a drop hit water and concentric ripples spread out (`rings`, `color`).',\n defaults: { rings: 3, color: 'rgba(14,165,233,.55)', duration: 1200 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n if (getComputedStyle(el).position === 'static') {\n const prev = el.style.position;\n el.style.position = 'relative';\n ctx.onCleanup(() => (el.style.position = prev));\n }\n const runs: (Promise<unknown> | undefined)[] = [ctx.animate(el, [{ transform: 'none' }, { transform: 'scale(.94, .9) translateY(3px)', offset: 0.2 }, { transform: 'scale(1.03, 1.05)', offset: 0.45 }, { transform: 'none' }], { duration: 700, easing: 'ease-out' })?.finished.catch(() => undefined)];\n const n = Math.max(1, Math.min(5, Number(o.rings) || 3));\n for (let i = 0; i < n; i++) {\n const r = document.createElement('span');\n r.setAttribute('aria-hidden', 'true');\n Object.assign(r.style, { position: 'absolute', left: '50%', top: '50%', width: '100%', aspectRatio: '2 / 1', borderRadius: '50%', border: `2px solid ${o.color}`, translate: '-50% -50%', pointerEvents: 'none' });\n el.appendChild(r);\n const end = () => r.remove();\n ctx.onCleanup(end);\n const a = ctx.animate(r, [{ transform: 'scale(.2)', opacity: 1 }, { transform: 'scale(1.9)', opacity: 0 }], { duration: o.duration, delay: 120 + i * 220, easing: 'ease-out', fill: 'backwards' });\n runs.push(a ? a.finished.then(end, end) : (end(), undefined));\n }\n return Promise.all(runs).then(() => undefined);\n },\n },\n {\n name: 'breathe',\n kind: 'loop',\n description: 'A slow organic morph of shape and scale, like a living blob, until the cleanup runs (`duration`).',\n defaults: { duration: 6000 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const prev = el.style.borderRadius;\n const frames: Keyframe[] = [0, 1, 2, 3, 0].map((i, k) => ({ borderRadius: blobRadius(i + 1), transform: `scale(${k % 2 ? 1.04 : 1}) rotate(${k % 2 ? 4 : -2}deg)`, offset: k / 4 }));\n const a = ctx.animate(el, frames, { duration: o.duration, iterations: Infinity, easing: 'ease-in-out' });\n return () => {\n a?.cancel();\n el.style.borderRadius = prev;\n };\n },\n },\n];\n\n/** Register vine-grow, bloom, water-drop and breathe (8.3). */\nexport function registerOrganicPack(): void {\n registerEffects(ORGANIC_FX);\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ 'use strict';
2
+
3
+ var registry = require('../chunks/registry-BVklOepd.cjs');
4
+ require('../chunks/base-DoRUZBy-.cjs');
5
+
6
+ /** Keyframes stepping a CSS blur/contrast "pixel" filter from coarse to sharp (8.2). */
7
+ function pixelSteps(steps = 6) {
8
+ const n = Math.max(2, Math.min(12, Math.round(steps)));
9
+ return Array.from({ length: n + 1 }, (_, i) => {
10
+ const k = 1 - i / n;
11
+ return { filter: k ? `blur(${(k * 6).toFixed(1)}px) contrast(${(1 + k * 4).toFixed(1)}) saturate(${(1 + k).toFixed(1)})` : 'none', opacity: Math.min(1, 0.3 + i / n), offset: i / n };
12
+ });
13
+ }
14
+ const fade = (el, ctx) => ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);
15
+ const RETRO_FX = [
16
+ {
17
+ name: 'pixelate-in',
18
+ kind: 'enter',
19
+ description: 'The element resolves from blocky pixels to sharp, like an 8-bit sprite loading (`steps`).',
20
+ defaults: { steps: 6, duration: 700 },
21
+ run: (el, o, ctx) => {
22
+ if (ctx.reduced)
23
+ return fade(el, ctx);
24
+ const n = Math.max(2, Math.min(12, Number(o.steps) || 6));
25
+ return ctx.animate(el, pixelSteps(n), { duration: o.duration, easing: `steps(${n}, end)`, fill: 'backwards' })?.finished.catch(() => undefined);
26
+ },
27
+ },
28
+ {
29
+ name: 'crt-power',
30
+ kind: 'enter',
31
+ description: 'A CRT switching on: a bright line opens into the picture with a flash (`duration`).',
32
+ defaults: { duration: 650 },
33
+ run: (el, o, ctx) => {
34
+ if (ctx.reduced)
35
+ return fade(el, ctx);
36
+ return ctx
37
+ .animate(el, [{ transform: 'scale(.02, .004)', filter: 'brightness(6)', opacity: 0.9 }, { transform: 'scale(1, .006)', filter: 'brightness(5)', opacity: 1, offset: 0.35 }, { transform: 'scale(1, 1.04)', filter: 'brightness(1.6)', offset: 0.75 }, { transform: 'none', filter: 'none', opacity: 1 }], { duration: o.duration, easing: 'cubic-bezier(.2,.7,.3,1)', fill: 'backwards' })
38
+ ?.finished.catch(() => undefined);
39
+ },
40
+ },
41
+ {
42
+ name: 'vhs-glitch',
43
+ kind: 'attention',
44
+ description: 'VHS tracking jitter with an RGB split and a noise band (`intensity` px).',
45
+ defaults: { intensity: 4, duration: 600 },
46
+ run: (el, o, ctx) => {
47
+ if (ctx.reduced)
48
+ return;
49
+ const k = Math.max(1, Math.min(12, Number(o.intensity) || 4));
50
+ const f = [];
51
+ for (let i = 0; i <= 8; i++) {
52
+ const d = i === 0 || i === 8 ? 0 : (i % 2 ? 1 : -1) * k * (1 - i / 10);
53
+ f.push({ transform: d ? `translateX(${d}px) skewX(${(d / 2).toFixed(1)}deg)` : 'none', textShadow: d ? `${-d}px 0 rgba(255,0,80,.75), ${d}px 0 rgba(0,220,255,.75)` : 'none', filter: d ? `hue-rotate(${d * 6}deg)` : 'none', offset: i / 8 });
54
+ }
55
+ return ctx.animate(el, f, { duration: o.duration, easing: 'steps(8, end)' })?.finished.catch(() => undefined);
56
+ },
57
+ },
58
+ {
59
+ name: 'y2k-shine',
60
+ kind: 'attention',
61
+ description: 'A chrome Y2K highlight sweeps across the element with a little bounce (`color`).',
62
+ defaults: { color: 'rgba(255,255,255,.85)', duration: 900 },
63
+ run: (el, o, ctx) => {
64
+ if (ctx.reduced)
65
+ return ctx.animate(el, [{ filter: 'none' }, { filter: 'brightness(1.25)' }, { filter: 'none' }], { duration: 300 })?.finished.catch(() => undefined);
66
+ if (getComputedStyle(el).position === 'static') {
67
+ const prev = el.style.position;
68
+ el.style.position = 'relative';
69
+ ctx.onCleanup(() => (el.style.position = prev));
70
+ }
71
+ const prevO = el.style.overflow;
72
+ el.style.overflow = 'hidden';
73
+ const sh = document.createElement('span');
74
+ sh.setAttribute('aria-hidden', 'true');
75
+ Object.assign(sh.style, { position: 'absolute', top: '-20%', bottom: '-20%', left: '0', width: '45%', background: `linear-gradient(105deg, transparent, ${o.color} 45%, rgba(180,220,255,.6) 55%, transparent)`, pointerEvents: 'none', mixBlendMode: 'screen' });
76
+ el.appendChild(sh);
77
+ const end = () => {
78
+ sh.remove();
79
+ el.style.overflow = prevO;
80
+ };
81
+ ctx.onCleanup(end);
82
+ ctx.animate(el, [{ transform: 'none' }, { transform: 'scale(1.04)', offset: 0.3 }, { transform: 'none' }], { duration: o.duration * 0.6, easing: 'ease-out' });
83
+ const a = ctx.animate(sh, [{ transform: 'translateX(-120%) skewX(-12deg)' }, { transform: 'translateX(330%) skewX(-12deg)' }], { duration: o.duration, easing: 'cubic-bezier(.3,.6,.3,1)' });
84
+ return a ? a.finished.then(end, end) : (end(), undefined);
85
+ },
86
+ },
87
+ ];
88
+ /** Register pixelate-in, crt-power, vhs-glitch and y2k-shine (8.2). */
89
+ function registerRetroPack() {
90
+ registry.registerEffects(RETRO_FX);
91
+ }
92
+
93
+ exports.RETRO_FX = RETRO_FX;
94
+ exports.pixelSteps = pixelSteps;
95
+ exports.registerRetroPack = registerRetroPack;
96
+ //# sourceMappingURL=fx-retro.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-retro.cjs","sources":["../../src/components/fx2/retro2.ts"],"sourcesContent":["/**\n * 8.2 — Retro pack (`motionary/fx/retro`, also `motionary/components/fx-retro`):\n *\n * - `pixelate-in` (enter) — the element resolves from big blocky pixels to\n * sharp, like an 8-bit sprite loading (`steps`).\n * - `crt-power` (enter) — a CRT switching on: a bright line opens into the\n * picture with a flash (`duration`).\n * - `vhs-glitch` (attention) — VHS tracking jitter with an RGB split and a\n * noise band (`intensity`).\n * - `y2k-shine` (attention) — a chrome Y2K highlight sweeps across the\n * element with a little bounce (`color`).\n *\n * Reduced motion: pixelate-in / crt-power fade in, vhs-glitch does nothing,\n * y2k-shine is a short brightness flash.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\n\n/** Keyframes stepping a CSS blur/contrast \"pixel\" filter from coarse to sharp (8.2). */\nexport function pixelSteps(steps = 6): Keyframe[] {\n const n = Math.max(2, Math.min(12, Math.round(steps)));\n return Array.from({ length: n + 1 }, (_, i) => {\n const k = 1 - i / n;\n return { filter: k ? `blur(${(k * 6).toFixed(1)}px) contrast(${(1 + k * 4).toFixed(1)}) saturate(${(1 + k).toFixed(1)})` : 'none', opacity: Math.min(1, 0.3 + i / n), offset: i / n };\n });\n}\n\nconst fade = (el: HTMLElement, ctx: EffectContext) => ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })?.finished.catch(() => undefined);\n\nexport const RETRO_FX: EffectDefinition[] = [\n {\n name: 'pixelate-in',\n kind: 'enter',\n description: 'The element resolves from blocky pixels to sharp, like an 8-bit sprite loading (`steps`).',\n defaults: { steps: 6, duration: 700 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return fade(el, ctx);\n const n = Math.max(2, Math.min(12, Number(o.steps) || 6));\n return ctx.animate(el, pixelSteps(n), { duration: o.duration, easing: `steps(${n}, end)`, fill: 'backwards' })?.finished.catch(() => undefined);\n },\n },\n {\n name: 'crt-power',\n kind: 'enter',\n description: 'A CRT switching on: a bright line opens into the picture with a flash (`duration`).',\n defaults: { duration: 650 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return fade(el, ctx);\n return ctx\n .animate(el, [{ transform: 'scale(.02, .004)', filter: 'brightness(6)', opacity: 0.9 }, { transform: 'scale(1, .006)', filter: 'brightness(5)', opacity: 1, offset: 0.35 }, { transform: 'scale(1, 1.04)', filter: 'brightness(1.6)', offset: 0.75 }, { transform: 'none', filter: 'none', opacity: 1 }], { duration: o.duration, easing: 'cubic-bezier(.2,.7,.3,1)', fill: 'backwards' })\n ?.finished.catch(() => undefined);\n },\n },\n {\n name: 'vhs-glitch',\n kind: 'attention',\n description: 'VHS tracking jitter with an RGB split and a noise band (`intensity` px).',\n defaults: { intensity: 4, duration: 600 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n const k = Math.max(1, Math.min(12, Number(o.intensity) || 4));\n const f: Keyframe[] = [];\n for (let i = 0; i <= 8; i++) {\n const d = i === 0 || i === 8 ? 0 : (i % 2 ? 1 : -1) * k * (1 - i / 10);\n f.push({ transform: d ? `translateX(${d}px) skewX(${(d / 2).toFixed(1)}deg)` : 'none', textShadow: d ? `${-d}px 0 rgba(255,0,80,.75), ${d}px 0 rgba(0,220,255,.75)` : 'none', filter: d ? `hue-rotate(${d * 6}deg)` : 'none', offset: i / 8 });\n }\n return ctx.animate(el, f, { duration: o.duration, easing: 'steps(8, end)' })?.finished.catch(() => undefined);\n },\n },\n {\n name: 'y2k-shine',\n kind: 'attention',\n description: 'A chrome Y2K highlight sweeps across the element with a little bounce (`color`).',\n defaults: { color: 'rgba(255,255,255,.85)', duration: 900 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return ctx.animate(el, [{ filter: 'none' }, { filter: 'brightness(1.25)' }, { filter: 'none' }], { duration: 300 })?.finished.catch(() => undefined);\n if (getComputedStyle(el).position === 'static') {\n const prev = el.style.position;\n el.style.position = 'relative';\n ctx.onCleanup(() => (el.style.position = prev));\n }\n const prevO = el.style.overflow;\n el.style.overflow = 'hidden';\n const sh = document.createElement('span');\n sh.setAttribute('aria-hidden', 'true');\n Object.assign(sh.style, { position: 'absolute', top: '-20%', bottom: '-20%', left: '0', width: '45%', background: `linear-gradient(105deg, transparent, ${o.color} 45%, rgba(180,220,255,.6) 55%, transparent)`, pointerEvents: 'none', mixBlendMode: 'screen' });\n el.appendChild(sh);\n const end = () => {\n sh.remove();\n el.style.overflow = prevO;\n };\n ctx.onCleanup(end);\n ctx.animate(el, [{ transform: 'none' }, { transform: 'scale(1.04)', offset: 0.3 }, { transform: 'none' }], { duration: o.duration * 0.6, easing: 'ease-out' });\n const a = ctx.animate(sh, [{ transform: 'translateX(-120%) skewX(-12deg)' }, { transform: 'translateX(330%) skewX(-12deg)' }], { duration: o.duration, easing: 'cubic-bezier(.3,.6,.3,1)' });\n return a ? a.finished.then(end, end) : (end(), undefined);\n },\n },\n];\n\n/** Register pixelate-in, crt-power, vhs-glitch and y2k-shine (8.2). */\nexport function registerRetroPack(): void {\n registerEffects(RETRO_FX);\n}\n"],"names":["registerEffects"],"mappings":"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"}