motionary 7.1.0 → 7.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 +32 -0
- package/dist/chunks/builtins-HlqAkK0f.js +99 -0
- package/dist/chunks/builtins-HlqAkK0f.js.map +1 -0
- package/dist/chunks/builtins-xalxV2d5.cjs +101 -0
- package/dist/chunks/builtins-xalxV2d5.cjs.map +1 -0
- package/dist/components/angular.cjs +1 -0
- package/dist/components/angular.cjs.map +1 -1
- package/dist/components/angular.js +1 -0
- package/dist/components/angular.js.map +1 -1
- package/dist/components/effects.cjs +1 -0
- package/dist/components/effects.cjs.map +1 -1
- package/dist/components/effects.js +1 -0
- package/dist/components/effects.js.map +1 -1
- package/dist/components/fx-chart.cjs +158 -0
- package/dist/components/fx-chart.cjs.map +1 -0
- package/dist/components/fx-chart.d.cts +73 -0
- package/dist/components/fx-chart.d.ts +73 -0
- package/dist/components/fx-chart.js +154 -0
- package/dist/components/fx-chart.js.map +1 -0
- package/dist/components/fx-shop.cjs +133 -0
- package/dist/components/fx-shop.cjs.map +1 -0
- package/dist/components/fx-shop.d.cts +70 -0
- package/dist/components/fx-shop.d.ts +70 -0
- package/dist/components/fx-shop.js +129 -0
- package/dist/components/fx-shop.js.map +1 -0
- package/dist/components/fx.cjs +5 -98
- package/dist/components/fx.cjs.map +1 -1
- package/dist/components/fx.js +3 -96
- package/dist/components/fx.js.map +1 -1
- package/dist/components/fx2.cjs +12 -0
- package/dist/components/fx2.cjs.map +1 -1
- package/dist/components/fx2.d.cts +56 -1
- package/dist/components/fx2.d.ts +56 -1
- package/dist/components/fx2.js +9 -1
- package/dist/components/fx2.js.map +1 -1
- package/dist/components/solid.cjs +1 -0
- package/dist/components/solid.cjs.map +1 -1
- package/dist/components/solid.js +1 -0
- package/dist/components/solid.js.map +1 -1
- package/dist/components/svelte.cjs +1 -0
- package/dist/components/svelte.cjs.map +1 -1
- package/dist/components/svelte.js +1 -0
- package/dist/components/svelte.js.map +1 -1
- package/dist/components/vue.cjs +1 -0
- package/dist/components/vue.cjs.map +1 -1
- package/dist/components/vue.js +1 -0
- package/dist/components/vue.js.map +1 -1
- package/dist/components/widgets.cjs +916 -70
- package/dist/components/widgets.cjs.map +1 -1
- package/dist/components/widgets.d.cts +158 -2
- package/dist/components/widgets.d.ts +158 -2
- package/dist/components/widgets.js +904 -71
- package/dist/components/widgets.js.map +1 -1
- package/dist/components.cjs +2 -1
- package/dist/components.cjs.map +1 -1
- package/dist/components.js +2 -1
- package/dist/components.js.map +1 -1
- package/dist/widgets.umd.js +1 -1
- package/dist/widgets.umd.js.map +1 -1
- package/docs/ROADMAP.md +2 -2
- package/docs/components.md +50 -0
- package/package.json +41 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var registry = require('../chunks/registry-DehBVRDV.cjs');
|
|
4
|
+
require('../chunks/base-BaQV-2ha.cjs');
|
|
5
|
+
|
|
6
|
+
/** Quadratic-bezier arc points from a to b, lifted by `lift` px (7.3). */
|
|
7
|
+
function arcPath(ax, ay, bx, by, lift = 120, steps = 8) {
|
|
8
|
+
const cx = (ax + bx) / 2;
|
|
9
|
+
const cy = Math.min(ay, by) - lift;
|
|
10
|
+
return Array.from({ length: steps + 1 }, (_, i) => {
|
|
11
|
+
const t = i / steps;
|
|
12
|
+
const u = 1 - t;
|
|
13
|
+
return { x: u * u * ax + 2 * u * t * cx + t * t * bx, y: u * u * ay + 2 * u * t * cy + t * t * by };
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const bump = (el, ctx) => el && ctx.animate(el, ctx.reduced ? [{ opacity: 0.5 }, { opacity: 1 }] : [{ transform: 'scale(1)' }, { transform: 'scale(1.25)', offset: 0.35 }, { transform: 'scale(.92)', offset: 0.7 }, { transform: 'scale(1)' }], { duration: ctx.reduced ? 250 : 480, easing: 'ease-out' });
|
|
17
|
+
const SHOP_FX = [
|
|
18
|
+
{
|
|
19
|
+
name: 'fly-to-cart',
|
|
20
|
+
kind: 'click',
|
|
21
|
+
description: 'A ghost of the element (or its first `img`) flies on an arc into the cart (`to` selector, default `[data-cart]`), shrinking; the cart bumps (`duration`, `lift`).',
|
|
22
|
+
defaults: { to: '[data-cart]', duration: 750, lift: 120 },
|
|
23
|
+
run: (el, o, ctx) => {
|
|
24
|
+
const cart = document.querySelector(o.to);
|
|
25
|
+
if (!cart)
|
|
26
|
+
return;
|
|
27
|
+
if (ctx.reduced)
|
|
28
|
+
return void bump(cart, ctx);
|
|
29
|
+
const src = el.querySelector('img') || el;
|
|
30
|
+
const a = src.getBoundingClientRect();
|
|
31
|
+
const b = cart.getBoundingClientRect();
|
|
32
|
+
const ghost = src.cloneNode(true);
|
|
33
|
+
ghost.removeAttribute('id');
|
|
34
|
+
ghost.setAttribute('aria-hidden', 'true');
|
|
35
|
+
Object.assign(ghost.style, { position: 'fixed', left: `${a.left}px`, top: `${a.top}px`, width: `${a.width}px`, height: `${a.height}px`, margin: '0', zIndex: '2147483000', pointerEvents: 'none', borderRadius: '12px', overflow: 'hidden' });
|
|
36
|
+
document.body.appendChild(ghost);
|
|
37
|
+
const pts = arcPath(0, 0, b.left + b.width / 2 - (a.left + a.width / 2), b.top + b.height / 2 - (a.top + a.height / 2), o.lift);
|
|
38
|
+
const s = Math.max(0.12, Math.min(1, 28 / Math.max(a.width, a.height, 1)));
|
|
39
|
+
const anim = ctx.animate(ghost, pts.map((p, i) => ({ transform: `translate(${p.x.toFixed(1)}px,${p.y.toFixed(1)}px) scale(${(1 - (1 - s) * (i / (pts.length - 1))).toFixed(3)})`, opacity: i === pts.length - 1 ? 0.6 : 1 })), { duration: o.duration, easing: 'cubic-bezier(.5,0,.75,.4)', fill: 'forwards' });
|
|
40
|
+
const done = () => (ghost.remove(), bump(cart, ctx));
|
|
41
|
+
if (anim)
|
|
42
|
+
anim.finished.then(done, () => ghost.remove());
|
|
43
|
+
else
|
|
44
|
+
done();
|
|
45
|
+
ctx.onCleanup(() => ghost.remove());
|
|
46
|
+
return anim?.finished.catch(() => undefined);
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'price-flip',
|
|
51
|
+
kind: 'enter',
|
|
52
|
+
description: 'The price flips character by character like a split-flap display from `data-from` (or scrambled digits) to its text (`stagger`).',
|
|
53
|
+
defaults: { stagger: 55, duration: 380 },
|
|
54
|
+
run: (el, o, ctx) => {
|
|
55
|
+
const to = el.dataset.priceTo || el.textContent || '';
|
|
56
|
+
el.dataset.priceTo = to;
|
|
57
|
+
if (ctx.reduced)
|
|
58
|
+
return void (el.textContent = to);
|
|
59
|
+
const from = (el.dataset.from || '').padStart(to.length, ' ');
|
|
60
|
+
el.textContent = '';
|
|
61
|
+
el.setAttribute('aria-label', to.trim());
|
|
62
|
+
const anims = Array.from(to).map((ch, i) => {
|
|
63
|
+
const span = document.createElement('span');
|
|
64
|
+
span.setAttribute('aria-hidden', 'true');
|
|
65
|
+
span.style.display = 'inline-block';
|
|
66
|
+
span.textContent = /\d/.test(ch) ? (from[i] && from[i] !== ' ' ? from[i] : String((Number(ch) + 5) % 10)) : ch;
|
|
67
|
+
el.appendChild(span);
|
|
68
|
+
const a = ctx.animate(span, [{ transform: 'rotateX(0)' }, { transform: 'rotateX(90deg)', offset: 0.5 }, { transform: 'rotateX(0)' }], { duration: o.duration, delay: i * o.stagger, easing: 'ease-in-out' });
|
|
69
|
+
setTimeout(() => (span.textContent = ch), i * o.stagger + o.duration / 2);
|
|
70
|
+
return a;
|
|
71
|
+
});
|
|
72
|
+
return Promise.all(anims.map((a) => a?.finished.catch(() => undefined))).then(() => {
|
|
73
|
+
el.textContent = to;
|
|
74
|
+
el.removeAttribute('aria-label');
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'stock-pulse',
|
|
80
|
+
kind: 'loop',
|
|
81
|
+
description: 'A soft urgency pulse — a glow ring in `color` — for low stock / last items (`color`, `period`).',
|
|
82
|
+
defaults: { color: 'rgba(239,68,68,.55)', period: 1400 },
|
|
83
|
+
reduced: 'skip',
|
|
84
|
+
run: (el, o, ctx) => {
|
|
85
|
+
const a = ctx.animate(el, [{ boxShadow: `0 0 0 0 ${o.color}` }, { boxShadow: '0 0 0 12px rgba(0,0,0,0)' }], { duration: o.period, iterations: Infinity, easing: 'ease-out' });
|
|
86
|
+
const stop = () => a?.cancel();
|
|
87
|
+
ctx.onCleanup(stop);
|
|
88
|
+
return stop;
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'sale-shine',
|
|
93
|
+
kind: 'hover',
|
|
94
|
+
description: 'A diagonal light sweep across the element (product cards, buy buttons) (`duration`).',
|
|
95
|
+
defaults: { duration: 700 },
|
|
96
|
+
reduced: 'skip',
|
|
97
|
+
run: (el, o, ctx) => {
|
|
98
|
+
const s = document.createElement('span');
|
|
99
|
+
s.setAttribute('aria-hidden', 'true');
|
|
100
|
+
Object.assign(s.style, { position: 'absolute', inset: '0', pointerEvents: 'none', background: 'linear-gradient(115deg,transparent 30%,rgba(255,255,255,.55) 50%,transparent 70%)', borderRadius: 'inherit' });
|
|
101
|
+
if (getComputedStyle(el).position === 'static')
|
|
102
|
+
el.style.position = 'relative';
|
|
103
|
+
const prev = el.style.overflow;
|
|
104
|
+
el.style.overflow = 'hidden';
|
|
105
|
+
el.appendChild(s);
|
|
106
|
+
const a = ctx.animate(s, [{ transform: 'translateX(-100%)' }, { transform: 'translateX(100%)' }], { duration: o.duration, easing: 'ease-in-out' });
|
|
107
|
+
const end = () => (s.remove(), (el.style.overflow = prev));
|
|
108
|
+
if (a)
|
|
109
|
+
a.finished.then(end, end);
|
|
110
|
+
else
|
|
111
|
+
end();
|
|
112
|
+
return a?.finished.catch(() => undefined);
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: 'badge-pop',
|
|
117
|
+
kind: 'attention',
|
|
118
|
+
description: 'A sale badge pops in with a wobble (`duration`).',
|
|
119
|
+
defaults: { duration: 650 },
|
|
120
|
+
run: (el, o, ctx) => ctx.reduced
|
|
121
|
+
? ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })
|
|
122
|
+
: ctx.animate(el, [{ transform: 'scale(0) rotate(-20deg)' }, { transform: 'scale(1.2) rotate(8deg)', offset: 0.5 }, { transform: 'scale(.95) rotate(-4deg)', offset: 0.75 }, { transform: 'none' }], { duration: o.duration, easing: 'ease-out' }),
|
|
123
|
+
},
|
|
124
|
+
];
|
|
125
|
+
/** Register the 7.3 e-commerce pack (idempotent). */
|
|
126
|
+
function registerShopPack() {
|
|
127
|
+
registry.registerEffects(SHOP_FX);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
exports.SHOP_FX = SHOP_FX;
|
|
131
|
+
exports.arcPath = arcPath;
|
|
132
|
+
exports.registerShopPack = registerShopPack;
|
|
133
|
+
//# sourceMappingURL=fx-shop.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fx-shop.cjs","sources":["../../src/components/fx2/shop.ts"],"sourcesContent":["/**\n * 7.3 — E-commerce motion (`motionary/fx/shop`, also\n * `motionary/components/fx-shop`):\n *\n * - `fly-to-cart` (click) — a ghost of the element (or its first `img`) flies\n * on an arc into the cart (`to`, default `[data-cart]`), shrinking; the cart\n * bumps when it lands.\n * - `price-flip` (enter) — the price flips like a split-flap display from\n * `data-from` (or a scramble) to its text.\n * - `stock-pulse` (loop) — a soft urgency pulse (glow ring) for low stock.\n * - `sale-shine` (hover) — a diagonal light sweep across the element.\n * - `badge-pop` (attention) — a sale badge pops in with a wobble.\n *\n * Reduced motion: fly-to-cart only bumps the cart with a fade, price-flip\n * sets the text, stock-pulse and sale-shine do nothing, badge-pop fades.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\n\n/** Quadratic-bezier arc points from a to b, lifted by `lift` px (7.3). */\nexport function arcPath(ax: number, ay: number, bx: number, by: number, lift = 120, steps = 8): { x: number; y: number }[] {\n const cx = (ax + bx) / 2;\n const cy = Math.min(ay, by) - lift;\n return Array.from({ length: steps + 1 }, (_, i) => {\n const t = i / steps;\n const u = 1 - t;\n return { x: u * u * ax + 2 * u * t * cx + t * t * bx, y: u * u * ay + 2 * u * t * cy + t * t * by };\n });\n}\n\nconst bump = (el: Element | null, ctx: EffectContext) =>\n el && ctx.animate(el, ctx.reduced ? [{ opacity: 0.5 }, { opacity: 1 }] : [{ transform: 'scale(1)' }, { transform: 'scale(1.25)', offset: 0.35 }, { transform: 'scale(.92)', offset: 0.7 }, { transform: 'scale(1)' }], { duration: ctx.reduced ? 250 : 480, easing: 'ease-out' });\n\nexport const SHOP_FX: EffectDefinition[] = [\n {\n name: 'fly-to-cart',\n kind: 'click',\n description: 'A ghost of the element (or its first `img`) flies on an arc into the cart (`to` selector, default `[data-cart]`), shrinking; the cart bumps (`duration`, `lift`).',\n defaults: { to: '[data-cart]', duration: 750, lift: 120 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const cart = document.querySelector(o.to) as HTMLElement | null;\n if (!cart) return;\n if (ctx.reduced) return void bump(cart, ctx);\n const src = (el.querySelector('img') as HTMLElement | null) || el;\n const a = src.getBoundingClientRect();\n const b = cart.getBoundingClientRect();\n const ghost = src.cloneNode(true) as HTMLElement;\n ghost.removeAttribute('id');\n ghost.setAttribute('aria-hidden', 'true');\n Object.assign(ghost.style, { position: 'fixed', left: `${a.left}px`, top: `${a.top}px`, width: `${a.width}px`, height: `${a.height}px`, margin: '0', zIndex: '2147483000', pointerEvents: 'none', borderRadius: '12px', overflow: 'hidden' });\n document.body.appendChild(ghost);\n const pts = arcPath(0, 0, b.left + b.width / 2 - (a.left + a.width / 2), b.top + b.height / 2 - (a.top + a.height / 2), o.lift);\n const s = Math.max(0.12, Math.min(1, 28 / Math.max(a.width, a.height, 1)));\n const anim = ctx.animate(ghost, pts.map((p, i) => ({ transform: `translate(${p.x.toFixed(1)}px,${p.y.toFixed(1)}px) scale(${(1 - (1 - s) * (i / (pts.length - 1))).toFixed(3)})`, opacity: i === pts.length - 1 ? 0.6 : 1 })), { duration: o.duration, easing: 'cubic-bezier(.5,0,.75,.4)', fill: 'forwards' });\n const done = () => (ghost.remove(), bump(cart, ctx));\n if (anim) anim.finished.then(done, () => ghost.remove());\n else done();\n ctx.onCleanup(() => ghost.remove());\n return anim?.finished.catch(() => undefined);\n },\n },\n {\n name: 'price-flip',\n kind: 'enter',\n description: 'The price flips character by character like a split-flap display from `data-from` (or scrambled digits) to its text (`stagger`).',\n defaults: { stagger: 55, duration: 380 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const to = el.dataset.priceTo || el.textContent || '';\n el.dataset.priceTo = to;\n if (ctx.reduced) return void (el.textContent = to);\n const from = (el.dataset.from || '').padStart(to.length, ' ');\n el.textContent = '';\n el.setAttribute('aria-label', to.trim());\n const anims = Array.from(to).map((ch, i) => {\n const span = document.createElement('span');\n span.setAttribute('aria-hidden', 'true');\n span.style.display = 'inline-block';\n span.textContent = /\\d/.test(ch) ? (from[i] && from[i] !== ' ' ? from[i] : String((Number(ch) + 5) % 10)) : ch;\n el.appendChild(span);\n const a = ctx.animate(span, [{ transform: 'rotateX(0)' }, { transform: 'rotateX(90deg)', offset: 0.5 }, { transform: 'rotateX(0)' }], { duration: o.duration, delay: i * o.stagger, easing: 'ease-in-out' });\n setTimeout(() => (span.textContent = ch), i * o.stagger + o.duration / 2);\n return a;\n });\n return Promise.all(anims.map((a) => a?.finished.catch(() => undefined))).then(() => {\n el.textContent = to;\n el.removeAttribute('aria-label');\n });\n },\n },\n {\n name: 'stock-pulse',\n kind: 'loop',\n description: 'A soft urgency pulse — a glow ring in `color` — for low stock / last items (`color`, `period`).',\n defaults: { color: 'rgba(239,68,68,.55)', period: 1400 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const a = ctx.animate(el, [{ boxShadow: `0 0 0 0 ${o.color}` }, { boxShadow: '0 0 0 12px rgba(0,0,0,0)' }], { duration: o.period, iterations: Infinity, easing: 'ease-out' });\n const stop = () => a?.cancel();\n ctx.onCleanup(stop);\n return stop;\n },\n },\n {\n name: 'sale-shine',\n kind: 'hover',\n description: 'A diagonal light sweep across the element (product cards, buy buttons) (`duration`).',\n defaults: { duration: 700 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const s = document.createElement('span');\n s.setAttribute('aria-hidden', 'true');\n Object.assign(s.style, { position: 'absolute', inset: '0', pointerEvents: 'none', background: 'linear-gradient(115deg,transparent 30%,rgba(255,255,255,.55) 50%,transparent 70%)', borderRadius: 'inherit' });\n if (getComputedStyle(el).position === 'static') el.style.position = 'relative';\n const prev = el.style.overflow;\n el.style.overflow = 'hidden';\n el.appendChild(s);\n const a = ctx.animate(s, [{ transform: 'translateX(-100%)' }, { transform: 'translateX(100%)' }], { duration: o.duration, easing: 'ease-in-out' });\n const end = () => (s.remove(), (el.style.overflow = prev));\n if (a) a.finished.then(end, end);\n else end();\n return a?.finished.catch(() => undefined);\n },\n },\n {\n name: 'badge-pop',\n kind: 'attention',\n description: 'A sale badge pops in with a wobble (`duration`).',\n defaults: { duration: 650 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) =>\n ctx.reduced\n ? ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })\n : ctx.animate(el, [{ transform: 'scale(0) rotate(-20deg)' }, { transform: 'scale(1.2) rotate(8deg)', offset: 0.5 }, { transform: 'scale(.95) rotate(-4deg)', offset: 0.75 }, { transform: 'none' }], { duration: o.duration, easing: 'ease-out' }),\n },\n];\n\n/** Register the 7.3 e-commerce pack (idempotent). */\nexport function registerShopPack(): void {\n registerEffects(SHOP_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.3 — E-commerce motion (`motionary/fx/shop`, also
|
|
46
|
+
* `motionary/components/fx-shop`):
|
|
47
|
+
*
|
|
48
|
+
* - `fly-to-cart` (click) — a ghost of the element (or its first `img`) flies
|
|
49
|
+
* on an arc into the cart (`to`, default `[data-cart]`), shrinking; the cart
|
|
50
|
+
* bumps when it lands.
|
|
51
|
+
* - `price-flip` (enter) — the price flips like a split-flap display from
|
|
52
|
+
* `data-from` (or a scramble) to its text.
|
|
53
|
+
* - `stock-pulse` (loop) — a soft urgency pulse (glow ring) for low stock.
|
|
54
|
+
* - `sale-shine` (hover) — a diagonal light sweep across the element.
|
|
55
|
+
* - `badge-pop` (attention) — a sale badge pops in with a wobble.
|
|
56
|
+
*
|
|
57
|
+
* Reduced motion: fly-to-cart only bumps the cart with a fade, price-flip
|
|
58
|
+
* sets the text, stock-pulse and sale-shine do nothing, badge-pop fades.
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
/** Quadratic-bezier arc points from a to b, lifted by `lift` px (7.3). */
|
|
62
|
+
declare function arcPath(ax: number, ay: number, bx: number, by: number, lift?: number, steps?: number): {
|
|
63
|
+
x: number;
|
|
64
|
+
y: number;
|
|
65
|
+
}[];
|
|
66
|
+
declare const SHOP_FX: EffectDefinition[];
|
|
67
|
+
/** Register the 7.3 e-commerce pack (idempotent). */
|
|
68
|
+
declare function registerShopPack(): void;
|
|
69
|
+
|
|
70
|
+
export { SHOP_FX, arcPath, registerShopPack };
|
|
@@ -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.3 — E-commerce motion (`motionary/fx/shop`, also
|
|
46
|
+
* `motionary/components/fx-shop`):
|
|
47
|
+
*
|
|
48
|
+
* - `fly-to-cart` (click) — a ghost of the element (or its first `img`) flies
|
|
49
|
+
* on an arc into the cart (`to`, default `[data-cart]`), shrinking; the cart
|
|
50
|
+
* bumps when it lands.
|
|
51
|
+
* - `price-flip` (enter) — the price flips like a split-flap display from
|
|
52
|
+
* `data-from` (or a scramble) to its text.
|
|
53
|
+
* - `stock-pulse` (loop) — a soft urgency pulse (glow ring) for low stock.
|
|
54
|
+
* - `sale-shine` (hover) — a diagonal light sweep across the element.
|
|
55
|
+
* - `badge-pop` (attention) — a sale badge pops in with a wobble.
|
|
56
|
+
*
|
|
57
|
+
* Reduced motion: fly-to-cart only bumps the cart with a fade, price-flip
|
|
58
|
+
* sets the text, stock-pulse and sale-shine do nothing, badge-pop fades.
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
/** Quadratic-bezier arc points from a to b, lifted by `lift` px (7.3). */
|
|
62
|
+
declare function arcPath(ax: number, ay: number, bx: number, by: number, lift?: number, steps?: number): {
|
|
63
|
+
x: number;
|
|
64
|
+
y: number;
|
|
65
|
+
}[];
|
|
66
|
+
declare const SHOP_FX: EffectDefinition[];
|
|
67
|
+
/** Register the 7.3 e-commerce pack (idempotent). */
|
|
68
|
+
declare function registerShopPack(): void;
|
|
69
|
+
|
|
70
|
+
export { SHOP_FX, arcPath, registerShopPack };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { registerEffects } from '../chunks/registry-CyKExAmE.js';
|
|
2
|
+
import '../chunks/base-2-yYc93C.js';
|
|
3
|
+
|
|
4
|
+
/** Quadratic-bezier arc points from a to b, lifted by `lift` px (7.3). */
|
|
5
|
+
function arcPath(ax, ay, bx, by, lift = 120, steps = 8) {
|
|
6
|
+
const cx = (ax + bx) / 2;
|
|
7
|
+
const cy = Math.min(ay, by) - lift;
|
|
8
|
+
return Array.from({ length: steps + 1 }, (_, i) => {
|
|
9
|
+
const t = i / steps;
|
|
10
|
+
const u = 1 - t;
|
|
11
|
+
return { x: u * u * ax + 2 * u * t * cx + t * t * bx, y: u * u * ay + 2 * u * t * cy + t * t * by };
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
const bump = (el, ctx) => el && ctx.animate(el, ctx.reduced ? [{ opacity: 0.5 }, { opacity: 1 }] : [{ transform: 'scale(1)' }, { transform: 'scale(1.25)', offset: 0.35 }, { transform: 'scale(.92)', offset: 0.7 }, { transform: 'scale(1)' }], { duration: ctx.reduced ? 250 : 480, easing: 'ease-out' });
|
|
15
|
+
const SHOP_FX = [
|
|
16
|
+
{
|
|
17
|
+
name: 'fly-to-cart',
|
|
18
|
+
kind: 'click',
|
|
19
|
+
description: 'A ghost of the element (or its first `img`) flies on an arc into the cart (`to` selector, default `[data-cart]`), shrinking; the cart bumps (`duration`, `lift`).',
|
|
20
|
+
defaults: { to: '[data-cart]', duration: 750, lift: 120 },
|
|
21
|
+
run: (el, o, ctx) => {
|
|
22
|
+
const cart = document.querySelector(o.to);
|
|
23
|
+
if (!cart)
|
|
24
|
+
return;
|
|
25
|
+
if (ctx.reduced)
|
|
26
|
+
return void bump(cart, ctx);
|
|
27
|
+
const src = el.querySelector('img') || el;
|
|
28
|
+
const a = src.getBoundingClientRect();
|
|
29
|
+
const b = cart.getBoundingClientRect();
|
|
30
|
+
const ghost = src.cloneNode(true);
|
|
31
|
+
ghost.removeAttribute('id');
|
|
32
|
+
ghost.setAttribute('aria-hidden', 'true');
|
|
33
|
+
Object.assign(ghost.style, { position: 'fixed', left: `${a.left}px`, top: `${a.top}px`, width: `${a.width}px`, height: `${a.height}px`, margin: '0', zIndex: '2147483000', pointerEvents: 'none', borderRadius: '12px', overflow: 'hidden' });
|
|
34
|
+
document.body.appendChild(ghost);
|
|
35
|
+
const pts = arcPath(0, 0, b.left + b.width / 2 - (a.left + a.width / 2), b.top + b.height / 2 - (a.top + a.height / 2), o.lift);
|
|
36
|
+
const s = Math.max(0.12, Math.min(1, 28 / Math.max(a.width, a.height, 1)));
|
|
37
|
+
const anim = ctx.animate(ghost, pts.map((p, i) => ({ transform: `translate(${p.x.toFixed(1)}px,${p.y.toFixed(1)}px) scale(${(1 - (1 - s) * (i / (pts.length - 1))).toFixed(3)})`, opacity: i === pts.length - 1 ? 0.6 : 1 })), { duration: o.duration, easing: 'cubic-bezier(.5,0,.75,.4)', fill: 'forwards' });
|
|
38
|
+
const done = () => (ghost.remove(), bump(cart, ctx));
|
|
39
|
+
if (anim)
|
|
40
|
+
anim.finished.then(done, () => ghost.remove());
|
|
41
|
+
else
|
|
42
|
+
done();
|
|
43
|
+
ctx.onCleanup(() => ghost.remove());
|
|
44
|
+
return anim?.finished.catch(() => undefined);
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'price-flip',
|
|
49
|
+
kind: 'enter',
|
|
50
|
+
description: 'The price flips character by character like a split-flap display from `data-from` (or scrambled digits) to its text (`stagger`).',
|
|
51
|
+
defaults: { stagger: 55, duration: 380 },
|
|
52
|
+
run: (el, o, ctx) => {
|
|
53
|
+
const to = el.dataset.priceTo || el.textContent || '';
|
|
54
|
+
el.dataset.priceTo = to;
|
|
55
|
+
if (ctx.reduced)
|
|
56
|
+
return void (el.textContent = to);
|
|
57
|
+
const from = (el.dataset.from || '').padStart(to.length, ' ');
|
|
58
|
+
el.textContent = '';
|
|
59
|
+
el.setAttribute('aria-label', to.trim());
|
|
60
|
+
const anims = Array.from(to).map((ch, i) => {
|
|
61
|
+
const span = document.createElement('span');
|
|
62
|
+
span.setAttribute('aria-hidden', 'true');
|
|
63
|
+
span.style.display = 'inline-block';
|
|
64
|
+
span.textContent = /\d/.test(ch) ? (from[i] && from[i] !== ' ' ? from[i] : String((Number(ch) + 5) % 10)) : ch;
|
|
65
|
+
el.appendChild(span);
|
|
66
|
+
const a = ctx.animate(span, [{ transform: 'rotateX(0)' }, { transform: 'rotateX(90deg)', offset: 0.5 }, { transform: 'rotateX(0)' }], { duration: o.duration, delay: i * o.stagger, easing: 'ease-in-out' });
|
|
67
|
+
setTimeout(() => (span.textContent = ch), i * o.stagger + o.duration / 2);
|
|
68
|
+
return a;
|
|
69
|
+
});
|
|
70
|
+
return Promise.all(anims.map((a) => a?.finished.catch(() => undefined))).then(() => {
|
|
71
|
+
el.textContent = to;
|
|
72
|
+
el.removeAttribute('aria-label');
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'stock-pulse',
|
|
78
|
+
kind: 'loop',
|
|
79
|
+
description: 'A soft urgency pulse — a glow ring in `color` — for low stock / last items (`color`, `period`).',
|
|
80
|
+
defaults: { color: 'rgba(239,68,68,.55)', period: 1400 },
|
|
81
|
+
reduced: 'skip',
|
|
82
|
+
run: (el, o, ctx) => {
|
|
83
|
+
const a = ctx.animate(el, [{ boxShadow: `0 0 0 0 ${o.color}` }, { boxShadow: '0 0 0 12px rgba(0,0,0,0)' }], { duration: o.period, iterations: Infinity, easing: 'ease-out' });
|
|
84
|
+
const stop = () => a?.cancel();
|
|
85
|
+
ctx.onCleanup(stop);
|
|
86
|
+
return stop;
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'sale-shine',
|
|
91
|
+
kind: 'hover',
|
|
92
|
+
description: 'A diagonal light sweep across the element (product cards, buy buttons) (`duration`).',
|
|
93
|
+
defaults: { duration: 700 },
|
|
94
|
+
reduced: 'skip',
|
|
95
|
+
run: (el, o, ctx) => {
|
|
96
|
+
const s = document.createElement('span');
|
|
97
|
+
s.setAttribute('aria-hidden', 'true');
|
|
98
|
+
Object.assign(s.style, { position: 'absolute', inset: '0', pointerEvents: 'none', background: 'linear-gradient(115deg,transparent 30%,rgba(255,255,255,.55) 50%,transparent 70%)', borderRadius: 'inherit' });
|
|
99
|
+
if (getComputedStyle(el).position === 'static')
|
|
100
|
+
el.style.position = 'relative';
|
|
101
|
+
const prev = el.style.overflow;
|
|
102
|
+
el.style.overflow = 'hidden';
|
|
103
|
+
el.appendChild(s);
|
|
104
|
+
const a = ctx.animate(s, [{ transform: 'translateX(-100%)' }, { transform: 'translateX(100%)' }], { duration: o.duration, easing: 'ease-in-out' });
|
|
105
|
+
const end = () => (s.remove(), (el.style.overflow = prev));
|
|
106
|
+
if (a)
|
|
107
|
+
a.finished.then(end, end);
|
|
108
|
+
else
|
|
109
|
+
end();
|
|
110
|
+
return a?.finished.catch(() => undefined);
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'badge-pop',
|
|
115
|
+
kind: 'attention',
|
|
116
|
+
description: 'A sale badge pops in with a wobble (`duration`).',
|
|
117
|
+
defaults: { duration: 650 },
|
|
118
|
+
run: (el, o, ctx) => ctx.reduced
|
|
119
|
+
? ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })
|
|
120
|
+
: ctx.animate(el, [{ transform: 'scale(0) rotate(-20deg)' }, { transform: 'scale(1.2) rotate(8deg)', offset: 0.5 }, { transform: 'scale(.95) rotate(-4deg)', offset: 0.75 }, { transform: 'none' }], { duration: o.duration, easing: 'ease-out' }),
|
|
121
|
+
},
|
|
122
|
+
];
|
|
123
|
+
/** Register the 7.3 e-commerce pack (idempotent). */
|
|
124
|
+
function registerShopPack() {
|
|
125
|
+
registerEffects(SHOP_FX);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export { SHOP_FX, arcPath, registerShopPack };
|
|
129
|
+
//# sourceMappingURL=fx-shop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fx-shop.js","sources":["../../src/components/fx2/shop.ts"],"sourcesContent":["/**\n * 7.3 — E-commerce motion (`motionary/fx/shop`, also\n * `motionary/components/fx-shop`):\n *\n * - `fly-to-cart` (click) — a ghost of the element (or its first `img`) flies\n * on an arc into the cart (`to`, default `[data-cart]`), shrinking; the cart\n * bumps when it lands.\n * - `price-flip` (enter) — the price flips like a split-flap display from\n * `data-from` (or a scramble) to its text.\n * - `stock-pulse` (loop) — a soft urgency pulse (glow ring) for low stock.\n * - `sale-shine` (hover) — a diagonal light sweep across the element.\n * - `badge-pop` (attention) — a sale badge pops in with a wobble.\n *\n * Reduced motion: fly-to-cart only bumps the cart with a fade, price-flip\n * sets the text, stock-pulse and sale-shine do nothing, badge-pop fades.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\n\n/** Quadratic-bezier arc points from a to b, lifted by `lift` px (7.3). */\nexport function arcPath(ax: number, ay: number, bx: number, by: number, lift = 120, steps = 8): { x: number; y: number }[] {\n const cx = (ax + bx) / 2;\n const cy = Math.min(ay, by) - lift;\n return Array.from({ length: steps + 1 }, (_, i) => {\n const t = i / steps;\n const u = 1 - t;\n return { x: u * u * ax + 2 * u * t * cx + t * t * bx, y: u * u * ay + 2 * u * t * cy + t * t * by };\n });\n}\n\nconst bump = (el: Element | null, ctx: EffectContext) =>\n el && ctx.animate(el, ctx.reduced ? [{ opacity: 0.5 }, { opacity: 1 }] : [{ transform: 'scale(1)' }, { transform: 'scale(1.25)', offset: 0.35 }, { transform: 'scale(.92)', offset: 0.7 }, { transform: 'scale(1)' }], { duration: ctx.reduced ? 250 : 480, easing: 'ease-out' });\n\nexport const SHOP_FX: EffectDefinition[] = [\n {\n name: 'fly-to-cart',\n kind: 'click',\n description: 'A ghost of the element (or its first `img`) flies on an arc into the cart (`to` selector, default `[data-cart]`), shrinking; the cart bumps (`duration`, `lift`).',\n defaults: { to: '[data-cart]', duration: 750, lift: 120 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const cart = document.querySelector(o.to) as HTMLElement | null;\n if (!cart) return;\n if (ctx.reduced) return void bump(cart, ctx);\n const src = (el.querySelector('img') as HTMLElement | null) || el;\n const a = src.getBoundingClientRect();\n const b = cart.getBoundingClientRect();\n const ghost = src.cloneNode(true) as HTMLElement;\n ghost.removeAttribute('id');\n ghost.setAttribute('aria-hidden', 'true');\n Object.assign(ghost.style, { position: 'fixed', left: `${a.left}px`, top: `${a.top}px`, width: `${a.width}px`, height: `${a.height}px`, margin: '0', zIndex: '2147483000', pointerEvents: 'none', borderRadius: '12px', overflow: 'hidden' });\n document.body.appendChild(ghost);\n const pts = arcPath(0, 0, b.left + b.width / 2 - (a.left + a.width / 2), b.top + b.height / 2 - (a.top + a.height / 2), o.lift);\n const s = Math.max(0.12, Math.min(1, 28 / Math.max(a.width, a.height, 1)));\n const anim = ctx.animate(ghost, pts.map((p, i) => ({ transform: `translate(${p.x.toFixed(1)}px,${p.y.toFixed(1)}px) scale(${(1 - (1 - s) * (i / (pts.length - 1))).toFixed(3)})`, opacity: i === pts.length - 1 ? 0.6 : 1 })), { duration: o.duration, easing: 'cubic-bezier(.5,0,.75,.4)', fill: 'forwards' });\n const done = () => (ghost.remove(), bump(cart, ctx));\n if (anim) anim.finished.then(done, () => ghost.remove());\n else done();\n ctx.onCleanup(() => ghost.remove());\n return anim?.finished.catch(() => undefined);\n },\n },\n {\n name: 'price-flip',\n kind: 'enter',\n description: 'The price flips character by character like a split-flap display from `data-from` (or scrambled digits) to its text (`stagger`).',\n defaults: { stagger: 55, duration: 380 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const to = el.dataset.priceTo || el.textContent || '';\n el.dataset.priceTo = to;\n if (ctx.reduced) return void (el.textContent = to);\n const from = (el.dataset.from || '').padStart(to.length, ' ');\n el.textContent = '';\n el.setAttribute('aria-label', to.trim());\n const anims = Array.from(to).map((ch, i) => {\n const span = document.createElement('span');\n span.setAttribute('aria-hidden', 'true');\n span.style.display = 'inline-block';\n span.textContent = /\\d/.test(ch) ? (from[i] && from[i] !== ' ' ? from[i] : String((Number(ch) + 5) % 10)) : ch;\n el.appendChild(span);\n const a = ctx.animate(span, [{ transform: 'rotateX(0)' }, { transform: 'rotateX(90deg)', offset: 0.5 }, { transform: 'rotateX(0)' }], { duration: o.duration, delay: i * o.stagger, easing: 'ease-in-out' });\n setTimeout(() => (span.textContent = ch), i * o.stagger + o.duration / 2);\n return a;\n });\n return Promise.all(anims.map((a) => a?.finished.catch(() => undefined))).then(() => {\n el.textContent = to;\n el.removeAttribute('aria-label');\n });\n },\n },\n {\n name: 'stock-pulse',\n kind: 'loop',\n description: 'A soft urgency pulse — a glow ring in `color` — for low stock / last items (`color`, `period`).',\n defaults: { color: 'rgba(239,68,68,.55)', period: 1400 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const a = ctx.animate(el, [{ boxShadow: `0 0 0 0 ${o.color}` }, { boxShadow: '0 0 0 12px rgba(0,0,0,0)' }], { duration: o.period, iterations: Infinity, easing: 'ease-out' });\n const stop = () => a?.cancel();\n ctx.onCleanup(stop);\n return stop;\n },\n },\n {\n name: 'sale-shine',\n kind: 'hover',\n description: 'A diagonal light sweep across the element (product cards, buy buttons) (`duration`).',\n defaults: { duration: 700 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const s = document.createElement('span');\n s.setAttribute('aria-hidden', 'true');\n Object.assign(s.style, { position: 'absolute', inset: '0', pointerEvents: 'none', background: 'linear-gradient(115deg,transparent 30%,rgba(255,255,255,.55) 50%,transparent 70%)', borderRadius: 'inherit' });\n if (getComputedStyle(el).position === 'static') el.style.position = 'relative';\n const prev = el.style.overflow;\n el.style.overflow = 'hidden';\n el.appendChild(s);\n const a = ctx.animate(s, [{ transform: 'translateX(-100%)' }, { transform: 'translateX(100%)' }], { duration: o.duration, easing: 'ease-in-out' });\n const end = () => (s.remove(), (el.style.overflow = prev));\n if (a) a.finished.then(end, end);\n else end();\n return a?.finished.catch(() => undefined);\n },\n },\n {\n name: 'badge-pop',\n kind: 'attention',\n description: 'A sale badge pops in with a wobble (`duration`).',\n defaults: { duration: 650 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) =>\n ctx.reduced\n ? ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: 250 })\n : ctx.animate(el, [{ transform: 'scale(0) rotate(-20deg)' }, { transform: 'scale(1.2) rotate(8deg)', offset: 0.5 }, { transform: 'scale(.95) rotate(-4deg)', offset: 0.75 }, { transform: 'none' }], { duration: o.duration, easing: 'ease-out' }),\n },\n];\n\n/** Register the 7.3 e-commerce pack (idempotent). */\nexport function registerShopPack(): void {\n registerEffects(SHOP_FX);\n}\n"],"names":[],"mappings":"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"}
|
package/dist/components/fx.cjs
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
var base = require('../chunks/base-BaQV-2ha.cjs');
|
|
4
4
|
var registry = require('../chunks/registry-DehBVRDV.cjs');
|
|
5
|
-
var
|
|
6
|
-
|
|
5
|
+
var builtins = require('../chunks/builtins-xalxV2d5.cjs');
|
|
6
|
+
require('../chunks/core-BGAyaY6L.cjs');
|
|
7
7
|
require('./tokens.cjs');
|
|
8
|
+
require('../chunks/fx-lBGVtQO1.cjs');
|
|
8
9
|
|
|
9
10
|
function defineFx(tag = 'usa-fx') {
|
|
10
11
|
return base.defineElement(tag, (Base) => class UsaFx extends Base {
|
|
@@ -41,100 +42,6 @@ function defineFx(tag = 'usa-fx') {
|
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
/**
|
|
45
|
-
* 5.0 built-in effects, all registered through `registerEffect()`:
|
|
46
|
-
* every timeline preset as an `enter` effect, attention seekers, and the
|
|
47
|
-
* click effects (burst, confetti, shake, ripple).
|
|
48
|
-
*/
|
|
49
|
-
const enter = Object.entries(core.TIMELINE_PRESETS).map(([name, frames]) => ({
|
|
50
|
-
name,
|
|
51
|
-
kind: 'enter',
|
|
52
|
-
description: `Entrance: ${name} (same keyframes as the timeline preset).`,
|
|
53
|
-
defaults: { duration: 600, delay: 0, easing: 'cubic-bezier(0.22, 1, 0.36, 1)' },
|
|
54
|
-
run: (el, o, ctx) => ctx.animate(el, ctx.reduced ? [{ opacity: 0 }, { opacity: 1 }] : frames, { duration: o.duration, delay: o.delay, easing: o.easing, fill: 'backwards' }),
|
|
55
|
-
}));
|
|
56
|
-
const A = (name, description, frames, duration = 700, easing = 'ease-in-out') => ({
|
|
57
|
-
name,
|
|
58
|
-
kind: 'attention',
|
|
59
|
-
description,
|
|
60
|
-
defaults: { duration, iterations: 1 },
|
|
61
|
-
run: (el, o, ctx) => (ctx.reduced ? ctx.animate(el, [{ opacity: 1 }, { opacity: 0.6 }, { opacity: 1 }], { duration: 400 }) : ctx.animate(el, frames, { duration: o.duration, easing, iterations: o.iterations })),
|
|
62
|
-
});
|
|
63
|
-
const attention = [
|
|
64
|
-
A('pulse', 'Gentle scale pulse.', [{ transform: 'scale(1)' }, { transform: 'scale(1.08)' }, { transform: 'scale(1)' }], 600),
|
|
65
|
-
A('pop', 'Quick overshoot pop.', [{ transform: 'scale(1)' }, { transform: 'scale(1.18)', offset: 0.4 }, { transform: 'scale(0.96)', offset: 0.7 }, { transform: 'scale(1)' }], 450, 'cubic-bezier(0.34, 1.56, 0.64, 1)'),
|
|
66
|
-
A('jelly', 'Rubbery squash-and-stretch.', [{ transform: 'scale(1,1)' }, { transform: 'scale(1.25,0.75)', offset: 0.3 }, { transform: 'scale(0.75,1.25)', offset: 0.4 }, { transform: 'scale(1.15,0.85)', offset: 0.5 }, { transform: 'scale(0.95,1.05)', offset: 0.65 }, { transform: 'scale(1.05,0.95)', offset: 0.75 }, { transform: 'scale(1,1)' }], 900),
|
|
67
|
-
A('wiggle', 'Playful rotate wiggle.', [{ transform: 'rotate(0)' }, { transform: 'rotate(-8deg)', offset: 0.2 }, { transform: 'rotate(7deg)', offset: 0.4 }, { transform: 'rotate(-5deg)', offset: 0.6 }, { transform: 'rotate(3deg)', offset: 0.8 }, { transform: 'rotate(0)' }], 650),
|
|
68
|
-
A('heartbeat', 'Double-beat heart pulse.', [{ transform: 'scale(1)' }, { transform: 'scale(1.2)', offset: 0.14 }, { transform: 'scale(1)', offset: 0.28 }, { transform: 'scale(1.2)', offset: 0.42 }, { transform: 'scale(1)', offset: 0.7 }], 1100),
|
|
69
|
-
A('bounce', 'Hop up and settle with a squash.', [{ transform: 'translateY(0) scale(1,1)' }, { transform: 'translateY(-22px) scale(0.95,1.05)', offset: 0.35 }, { transform: 'translateY(0) scale(1.08,0.92)', offset: 0.6 }, { transform: 'translateY(-6px) scale(1,1)', offset: 0.8 }, { transform: 'translateY(0) scale(1,1)' }], 800),
|
|
70
|
-
A('flash', 'Two soft flashes (well under 3 per second).', [{ opacity: 1 }, { opacity: 0.25, offset: 0.25 }, { opacity: 1, offset: 0.5 }, { opacity: 0.25, offset: 0.75 }, { opacity: 1 }], 1400),
|
|
71
|
-
A('tada', 'Scale + shake celebration.', [{ transform: 'scale(1) rotate(0)' }, { transform: 'scale(0.9) rotate(-3deg)', offset: 0.1 }, { transform: 'scale(1.1) rotate(3deg)', offset: 0.3 }, { transform: 'scale(1.1) rotate(-3deg)', offset: 0.5 }, { transform: 'scale(1.1) rotate(3deg)', offset: 0.7 }, { transform: 'scale(1) rotate(0)' }], 1000),
|
|
72
|
-
];
|
|
73
|
-
const click = [
|
|
74
|
-
{
|
|
75
|
-
name: 'burst',
|
|
76
|
-
kind: 'click',
|
|
77
|
-
description: 'Particle burst from the click point (or `x` / `y`, or the element center).',
|
|
78
|
-
defaults: { count: 12 },
|
|
79
|
-
run: (el, o, ctx) => {
|
|
80
|
-
if (ctx.reduced)
|
|
81
|
-
return;
|
|
82
|
-
const r = el.getBoundingClientRect();
|
|
83
|
-
const e = ctx.event;
|
|
84
|
-
fx.burst(o.x ?? e?.clientX ?? r.left + r.width / 2, o.y ?? e?.clientY ?? r.top + r.height / 2, o);
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
name: 'confetti',
|
|
89
|
-
kind: 'click',
|
|
90
|
-
description: 'Confetti cannon from the element.',
|
|
91
|
-
defaults: { count: 80 },
|
|
92
|
-
run: (el, o, ctx) => {
|
|
93
|
-
if (ctx.reduced)
|
|
94
|
-
return;
|
|
95
|
-
const r = el.getBoundingClientRect();
|
|
96
|
-
fx.confetti({ x: r.left + r.width / 2, y: r.top + r.height / 2, ...o });
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
name: 'shake',
|
|
101
|
-
kind: 'attention',
|
|
102
|
-
description: 'Horizontal "no" shake (errors, wrong password).',
|
|
103
|
-
defaults: { intensity: 8, duration: 480 },
|
|
104
|
-
run: (el, o, ctx) => (ctx.reduced ? ctx.animate(el, [{ opacity: 1 }, { opacity: 0.5 }, { opacity: 1 }], { duration: 300 }) : fx.shake(el, o.intensity, o.duration)),
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
name: 'ripple',
|
|
108
|
-
kind: 'click',
|
|
109
|
-
description: 'Material-style ink ripple from the pointer.',
|
|
110
|
-
defaults: { color: 'currentColor', duration: 600 },
|
|
111
|
-
run: (el, o, ctx) => {
|
|
112
|
-
var _a;
|
|
113
|
-
if (ctx.reduced)
|
|
114
|
-
return;
|
|
115
|
-
const r = el.getBoundingClientRect();
|
|
116
|
-
const e = ctx.event;
|
|
117
|
-
const d = Math.hypot(r.width, r.height) * 2;
|
|
118
|
-
const dot = document.createElement('span');
|
|
119
|
-
dot.setAttribute('aria-hidden', 'true');
|
|
120
|
-
Object.assign(dot.style, { position: 'absolute', left: `${(e?.clientX ?? r.left + r.width / 2) - r.left - d / 2}px`, top: `${(e?.clientY ?? r.top + r.height / 2) - r.top - d / 2}px`, width: `${d}px`, height: `${d}px`, borderRadius: '50%', background: o.color, opacity: '0.25', pointerEvents: 'none' });
|
|
121
|
-
if (getComputedStyle(el).position === 'static')
|
|
122
|
-
el.style.position = 'relative';
|
|
123
|
-
(_a = el.style).overflow || (_a.overflow = 'hidden');
|
|
124
|
-
el.appendChild(dot);
|
|
125
|
-
const a = ctx.animate(dot, [{ transform: 'scale(0)', opacity: 0.3 }, { transform: 'scale(1)', opacity: 0 }], { duration: o.duration, easing: 'ease-out' });
|
|
126
|
-
const done = () => dot.remove();
|
|
127
|
-
if (a)
|
|
128
|
-
a.finished.then(done, done);
|
|
129
|
-
else
|
|
130
|
-
done();
|
|
131
|
-
return a;
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
];
|
|
135
|
-
/** Every built-in 5.0 effect definition. */
|
|
136
|
-
const BUILTIN_EFFECTS = [...enter, ...attention, ...click];
|
|
137
|
-
|
|
138
45
|
/**
|
|
139
46
|
* motionary/components/fx — unified plugin-style effects (5.0).
|
|
140
47
|
* `registerEffect({ name, kind, run })`, `playEffect(el, name)`,
|
|
@@ -145,7 +52,7 @@ const BUILTIN_EFFECTS = [...enter, ...attention, ...click];
|
|
|
145
52
|
*/
|
|
146
53
|
/** Register the built-in effects (idempotent; `defineFxComponents()` calls it). */
|
|
147
54
|
function registerBuiltinEffects() {
|
|
148
|
-
registry.registerEffects(BUILTIN_EFFECTS);
|
|
55
|
+
registry.registerEffects(builtins.BUILTIN_EFFECTS);
|
|
149
56
|
}
|
|
150
57
|
/** Register every component of this category under its default tag (+ the built-in effects). */
|
|
151
58
|
function defineFxComponents() {
|
|
@@ -162,7 +69,7 @@ exports.listEffects = registry.listEffects;
|
|
|
162
69
|
exports.playEffect = registry.playEffect;
|
|
163
70
|
exports.registerEffect = registry.registerEffect;
|
|
164
71
|
exports.registerEffects = registry.registerEffects;
|
|
165
|
-
exports.BUILTIN_EFFECTS = BUILTIN_EFFECTS;
|
|
72
|
+
exports.BUILTIN_EFFECTS = builtins.BUILTIN_EFFECTS;
|
|
166
73
|
exports.defineFx = defineFx;
|
|
167
74
|
exports.defineFxComponents = defineFxComponents;
|
|
168
75
|
exports.registerBuiltinEffects = registerBuiltinEffects;
|