use-scroll-animate 9.5.0 → 9.6.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 +12 -0
- package/dist/components/fx-perf.cjs +161 -0
- package/dist/components/fx-perf.cjs.map +1 -0
- package/dist/components/fx-perf.d.cts +86 -0
- package/dist/components/fx-perf.d.ts +86 -0
- package/dist/components/fx-perf.js +155 -0
- package/dist/components/fx-perf.js.map +1 -0
- package/dist/components/fx2.cjs +8 -0
- package/dist/components/fx2.cjs.map +1 -1
- package/dist/components/fx2.d.cts +42 -1
- package/dist/components/fx2.d.ts +42 -1
- package/dist/components/fx2.js +5 -1
- package/dist/components/fx2.js.map +1 -1
- package/dist/components/marketplace.cjs +1 -0
- package/dist/components/marketplace.cjs.map +1 -1
- package/dist/components/marketplace.js +1 -0
- package/dist/components/marketplace.js.map +1 -1
- package/dist/components/widgets.cjs +311 -185
- package/dist/components/widgets.cjs.map +1 -1
- package/dist/components/widgets.d.cts +63 -2
- package/dist/components/widgets.d.ts +63 -2
- package/dist/components/widgets.js +310 -187
- package/dist/components/widgets.js.map +1 -1
- package/dist/widgets.umd.js +1 -1
- package/dist/widgets.umd.js.map +1 -1
- package/docs/ROADMAP.md +1 -1
- package/docs/components.md +16 -0
- package/package.json +21 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [9.6.0] - 2026-10-09
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Performance 3.0 — `motionary/fx/perf`** (= `motionary/components/fx-perf`, `registerPerf3Pack()`, also in `registerEffectPacks()` and the marketplace): `offscreenRender(canvas, program, { worker, paused })` (canvas animation in a Web Worker via OffscreenCanvas, main-thread fallback on the shared frame loop; `{ backend, stop, resize }`), `runInWorker(fn, ...args)` (one-off pure computation in a worker, inline fallback), `fpsMeter()`. Effects `idle-reveal` (enter — waits for `requestIdleCallback`) and `gpu-lift` (hover — compositor-only).
|
|
14
|
+
- **2 new components (9.6)** in `motionary/components/widgets`:
|
|
15
|
+
- `<usa-perf-monitor>` — live overlay: FPS + sparkline, active animations, frame-loop callbacks, long tasks, clock state; `corner` (or `inline`), `collapsed`, `warn`; `stats`; `usa:jank` { fps }.
|
|
16
|
+
- `<usa-worker-canvas>` — canvas animation rendered off the main thread (`scene` particles · orbits · starfield, or your `program`); `data-usa-backend` worker / main; `backend`; `usa:backend`; `WORKER_SCENES`.
|
|
17
|
+
- Showcase: 3 new gallery cards with copyable code, live demos and live Store thumbnails.
|
|
18
|
+
|
|
19
|
+
### Accessibility
|
|
20
|
+
- The perf monitor is a labelled `status` region with a real expand / collapse button (`aria-expanded`). The worker canvas is an `img` with `label`. Reduced motion: the worker canvas paints one still frame, `idle-reveal` shows at once, `gpu-lift` does nothing.
|
|
21
|
+
|
|
10
22
|
## [9.5.0] - 2026-10-09
|
|
11
23
|
|
|
12
24
|
### Added
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var registry = require('../chunks/registry-BVklOepd.cjs');
|
|
4
|
+
var base = require('../chunks/base-DoRUZBy-.cjs');
|
|
5
|
+
|
|
6
|
+
/** Run a pure function in a Web Worker; resolves with its (structured-cloneable) result (9.6). */
|
|
7
|
+
function runInWorker(fn, ...args) {
|
|
8
|
+
if (typeof Worker === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined' || !URL.createObjectURL)
|
|
9
|
+
return Promise.resolve().then(() => fn(...args));
|
|
10
|
+
const src = `self.onmessage=async(e)=>{try{const r=await (${fn.toString()})(...e.data);self.postMessage({ok:true,r})}catch(err){self.postMessage({ok:false,e:String(err&&err.message||err)})}}`;
|
|
11
|
+
const url = URL.createObjectURL(new Blob([src], { type: 'text/javascript' }));
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
let w;
|
|
14
|
+
try {
|
|
15
|
+
w = new Worker(url);
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
URL.revokeObjectURL(url);
|
|
19
|
+
return resolve(Promise.resolve().then(() => fn(...args)));
|
|
20
|
+
}
|
|
21
|
+
const done = () => {
|
|
22
|
+
w.terminate();
|
|
23
|
+
URL.revokeObjectURL(url);
|
|
24
|
+
};
|
|
25
|
+
w.onmessage = (e) => {
|
|
26
|
+
done();
|
|
27
|
+
if (e.data?.ok)
|
|
28
|
+
resolve(e.data.r);
|
|
29
|
+
else
|
|
30
|
+
reject(new Error(e.data?.e || 'worker failed'));
|
|
31
|
+
};
|
|
32
|
+
w.onerror = (e) => {
|
|
33
|
+
done();
|
|
34
|
+
reject(new Error(e.message || 'worker error'));
|
|
35
|
+
};
|
|
36
|
+
w.postMessage(args);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** Animate `canvas` with `program` in a worker (OffscreenCanvas) when possible, else on the main thread (9.6). */
|
|
40
|
+
function offscreenRender(canvas, program, opts = {}) {
|
|
41
|
+
const code = typeof program === 'string' ? program : program.toString();
|
|
42
|
+
const canWorker = opts.worker !== false && typeof Worker !== 'undefined' && typeof canvas.transferControlToOffscreen === 'function' && typeof Blob !== 'undefined' && !!URL.createObjectURL;
|
|
43
|
+
if (canWorker) {
|
|
44
|
+
try {
|
|
45
|
+
const off = canvas.transferControlToOffscreen();
|
|
46
|
+
const src = `let c,ctx,w,h,st={},run=true,t0=0;const draw=(${code});self.onmessage=(e)=>{const d=e.data;if(d.canvas){c=d.canvas;ctx=c.getContext('2d');w=c.width;h=c.height;const loop=(t)=>{if(run){if(!t0)t0=t;draw(ctx,t-t0,w,h,st)}requestAnimationFrame(loop)};requestAnimationFrame(loop)}if(d.size){w=c.width=d.size[0];h=c.height=d.size[1]}if('run' in d)run=d.run;if(d.stop)close()}`;
|
|
47
|
+
const url = URL.createObjectURL(new Blob([src], { type: 'text/javascript' }));
|
|
48
|
+
const w = new Worker(url);
|
|
49
|
+
w.postMessage({ canvas: off }, [off]);
|
|
50
|
+
if (opts.paused)
|
|
51
|
+
w.postMessage({ run: false });
|
|
52
|
+
return {
|
|
53
|
+
backend: 'worker',
|
|
54
|
+
stop: () => {
|
|
55
|
+
w.postMessage({ stop: true });
|
|
56
|
+
w.terminate();
|
|
57
|
+
URL.revokeObjectURL(url);
|
|
58
|
+
},
|
|
59
|
+
resize: (a, b) => w.postMessage({ size: [a, b] }),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
/* fall back to the main thread */
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const ctx = canvas.getContext?.('2d');
|
|
67
|
+
if (!ctx)
|
|
68
|
+
return { backend: 'none', stop: () => undefined, resize: () => undefined };
|
|
69
|
+
// eslint-disable-next-line no-new-func
|
|
70
|
+
const draw = typeof program === 'function' ? program : new Function(`return (${code})`)();
|
|
71
|
+
const st = {};
|
|
72
|
+
let t = 0;
|
|
73
|
+
const stop = opts.paused
|
|
74
|
+
? () => undefined
|
|
75
|
+
: base.onFrame((_now, dt) => {
|
|
76
|
+
t += dt;
|
|
77
|
+
draw(ctx, t, canvas.width, canvas.height, st);
|
|
78
|
+
});
|
|
79
|
+
if (opts.paused)
|
|
80
|
+
draw(ctx, 0, canvas.width, canvas.height, st);
|
|
81
|
+
return {
|
|
82
|
+
backend: 'main',
|
|
83
|
+
stop,
|
|
84
|
+
resize: (a, b) => {
|
|
85
|
+
canvas.width = a;
|
|
86
|
+
canvas.height = b;
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** A rolling FPS meter on the shared frame loop: { fps, stop } (fps updates every frame) (9.6). */
|
|
91
|
+
function fpsMeter(window = 30) {
|
|
92
|
+
const samples = [];
|
|
93
|
+
let fps = 0;
|
|
94
|
+
const stop = base.onFrame((_t, dt) => {
|
|
95
|
+
if (dt <= 0)
|
|
96
|
+
return;
|
|
97
|
+
samples.push(1000 / dt);
|
|
98
|
+
if (samples.length > window)
|
|
99
|
+
samples.shift();
|
|
100
|
+
fps = Math.round(samples.reduce((a, b) => a + b, 0) / samples.length);
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
get fps() {
|
|
104
|
+
return fps;
|
|
105
|
+
},
|
|
106
|
+
samples,
|
|
107
|
+
stop,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const PERF3_FX = [
|
|
111
|
+
{
|
|
112
|
+
name: 'idle-reveal',
|
|
113
|
+
kind: 'enter',
|
|
114
|
+
description: 'Waits for an idle moment (requestIdleCallback, ≤ `timeout` ms) before fading in, keeping first paint and input snappy.',
|
|
115
|
+
defaults: { duration: 400, timeout: 600 },
|
|
116
|
+
run: (el, o, ctx) => {
|
|
117
|
+
if (ctx.reduced)
|
|
118
|
+
return;
|
|
119
|
+
const prev = el.style.opacity;
|
|
120
|
+
el.style.opacity = '0';
|
|
121
|
+
ctx.onCleanup(() => (el.style.opacity = prev));
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
const go = () => {
|
|
124
|
+
el.style.opacity = prev;
|
|
125
|
+
const a = ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: o.duration, easing: 'ease-out' });
|
|
126
|
+
if (a)
|
|
127
|
+
a.finished.then(() => resolve(), () => resolve());
|
|
128
|
+
else
|
|
129
|
+
resolve();
|
|
130
|
+
};
|
|
131
|
+
const ric = globalThis.requestIdleCallback;
|
|
132
|
+
if (ric)
|
|
133
|
+
ric(go, { timeout: Number(o.timeout) || 600 });
|
|
134
|
+
else
|
|
135
|
+
setTimeout(go, 1);
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: 'gpu-lift',
|
|
141
|
+
kind: 'hover',
|
|
142
|
+
description: 'A compositor-only hover lift — only transform and opacity change, so it never triggers layout or paint.',
|
|
143
|
+
defaults: { duration: 250, lift: 6 },
|
|
144
|
+
run: (el, o, ctx) => {
|
|
145
|
+
if (ctx.reduced)
|
|
146
|
+
return;
|
|
147
|
+
return ctx.animate(el, [{ transform: 'translateY(0) scale(1)' }, { transform: `translateY(${-Math.abs(Number(o.lift) || 6)}px) scale(1.02)` }], { duration: o.duration, easing: 'ease-out', fill: 'forwards' })?.finished.catch(() => undefined);
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
];
|
|
151
|
+
/** Register idle-reveal and gpu-lift (9.6). */
|
|
152
|
+
function registerPerf3Pack() {
|
|
153
|
+
registry.registerEffects(PERF3_FX);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
exports.PERF3_FX = PERF3_FX;
|
|
157
|
+
exports.fpsMeter = fpsMeter;
|
|
158
|
+
exports.offscreenRender = offscreenRender;
|
|
159
|
+
exports.registerPerf3Pack = registerPerf3Pack;
|
|
160
|
+
exports.runInWorker = runInWorker;
|
|
161
|
+
//# sourceMappingURL=fx-perf.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fx-perf.cjs","sources":["../../src/components/fx2/perf3.ts"],"sourcesContent":["/**\n * 9.6 — Performance 3.0 (`motionary/fx/perf`, also `motionary/components/fx-perf`):\n *\n * - `runInWorker(fn, ...args)` — run a pure function in a throw-away Web\n * Worker (built from its source) and get a promise of its result; runs\n * inline when Workers are unavailable.\n * - `offscreenRender(canvas, program, options)` — move a canvas animation\n * off the main thread: `program` is the source of\n * `function (ctx, t, w, h, state) {…}`; with OffscreenCanvas + Worker it\n * runs in a worker (`backend: 'worker'`), otherwise on the main thread via\n * the shared frame loop (`'main'`). Returns { backend, stop, resize }.\n * - `fpsMeter()` — a rolling frames-per-second meter on the shared loop.\n *\n * Effects: `idle-reveal` (enter) waits for an idle moment before fading in\n * (keeps first paint / input snappy); `gpu-lift` (hover) a compositor-only\n * lift (transform + opacity only). Reduced motion: idle-reveal just shows,\n * gpu-lift does nothing.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\nimport { onFrame } from '../base';\n\n/** Run a pure function in a Web Worker; resolves with its (structured-cloneable) result (9.6). */\nexport function runInWorker<A extends unknown[], R>(fn: (...args: A) => R | Promise<R>, ...args: A): Promise<R> {\n if (typeof Worker === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined' || !URL.createObjectURL) return Promise.resolve().then(() => fn(...args));\n const src = `self.onmessage=async(e)=>{try{const r=await (${fn.toString()})(...e.data);self.postMessage({ok:true,r})}catch(err){self.postMessage({ok:false,e:String(err&&err.message||err)})}}`;\n const url = URL.createObjectURL(new Blob([src], { type: 'text/javascript' }));\n return new Promise<R>((resolve, reject) => {\n let w: Worker;\n try {\n w = new Worker(url);\n } catch (e) {\n URL.revokeObjectURL(url);\n return resolve(Promise.resolve().then(() => fn(...args)));\n }\n const done = () => {\n w.terminate();\n URL.revokeObjectURL(url);\n };\n w.onmessage = (e) => {\n done();\n if (e.data?.ok) resolve(e.data.r as R);\n else reject(new Error(e.data?.e || 'worker failed'));\n };\n w.onerror = (e) => {\n done();\n reject(new Error(e.message || 'worker error'));\n };\n w.postMessage(args);\n });\n}\n\nexport type DrawProgram = string | ((ctx: CanvasRenderingContext2D, t: number, w: number, h: number, state: Record<string, unknown>) => void);\n/** Animate `canvas` with `program` in a worker (OffscreenCanvas) when possible, else on the main thread (9.6). */\nexport function offscreenRender(canvas: HTMLCanvasElement, program: DrawProgram, opts: { worker?: boolean; paused?: boolean } = {}): { backend: 'worker' | 'main' | 'none'; stop(): void; resize(w: number, h: number): void } {\n const code = typeof program === 'string' ? program : program.toString();\n const canWorker = opts.worker !== false && typeof Worker !== 'undefined' && typeof (canvas as any).transferControlToOffscreen === 'function' && typeof Blob !== 'undefined' && !!URL.createObjectURL;\n if (canWorker) {\n try {\n const off = (canvas as any).transferControlToOffscreen();\n const src = `let c,ctx,w,h,st={},run=true,t0=0;const draw=(${code});self.onmessage=(e)=>{const d=e.data;if(d.canvas){c=d.canvas;ctx=c.getContext('2d');w=c.width;h=c.height;const loop=(t)=>{if(run){if(!t0)t0=t;draw(ctx,t-t0,w,h,st)}requestAnimationFrame(loop)};requestAnimationFrame(loop)}if(d.size){w=c.width=d.size[0];h=c.height=d.size[1]}if('run' in d)run=d.run;if(d.stop)close()}`;\n const url = URL.createObjectURL(new Blob([src], { type: 'text/javascript' }));\n const w = new Worker(url);\n w.postMessage({ canvas: off }, [off]);\n if (opts.paused) w.postMessage({ run: false });\n return {\n backend: 'worker',\n stop: () => {\n w.postMessage({ stop: true });\n w.terminate();\n URL.revokeObjectURL(url);\n },\n resize: (a, b) => w.postMessage({ size: [a, b] }),\n };\n } catch {\n /* fall back to the main thread */\n }\n }\n const ctx = canvas.getContext?.('2d');\n if (!ctx) return { backend: 'none', stop: () => undefined, resize: () => undefined };\n // eslint-disable-next-line no-new-func\n const draw = typeof program === 'function' ? program : (new Function(`return (${code})`)() as Exclude<DrawProgram, string>);\n const st: Record<string, unknown> = {};\n let t = 0;\n const stop = opts.paused\n ? () => undefined\n : onFrame((_now, dt) => {\n t += dt;\n draw(ctx, t, canvas.width, canvas.height, st);\n });\n if (opts.paused) draw(ctx, 0, canvas.width, canvas.height, st);\n return {\n backend: 'main',\n stop,\n resize: (a, b) => {\n canvas.width = a;\n canvas.height = b;\n },\n };\n}\n\n/** A rolling FPS meter on the shared frame loop: { fps, stop } (fps updates every frame) (9.6). */\nexport function fpsMeter(window = 30): { readonly fps: number; readonly samples: number[]; stop(): void } {\n const samples: number[] = [];\n let fps = 0;\n const stop = onFrame((_t, dt) => {\n if (dt <= 0) return;\n samples.push(1000 / dt);\n if (samples.length > window) samples.shift();\n fps = Math.round(samples.reduce((a, b) => a + b, 0) / samples.length);\n });\n return {\n get fps() {\n return fps;\n },\n samples,\n stop,\n };\n}\n\nexport const PERF3_FX: EffectDefinition[] = [\n {\n name: 'idle-reveal',\n kind: 'enter',\n description: 'Waits for an idle moment (requestIdleCallback, ≤ `timeout` ms) before fading in, keeping first paint and input snappy.',\n defaults: { duration: 400, timeout: 600 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n const prev = el.style.opacity;\n el.style.opacity = '0';\n ctx.onCleanup(() => (el.style.opacity = prev));\n return new Promise<void>((resolve) => {\n const go = () => {\n el.style.opacity = prev;\n const a = ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: o.duration, easing: 'ease-out' });\n if (a) a.finished.then(() => resolve(), () => resolve());\n else resolve();\n };\n const ric = (globalThis as any).requestIdleCallback as ((cb: () => void, o?: { timeout: number }) => number) | undefined;\n if (ric) ric(go, { timeout: Number(o.timeout) || 600 });\n else setTimeout(go, 1);\n });\n },\n },\n {\n name: 'gpu-lift',\n kind: 'hover',\n description: 'A compositor-only hover lift — only transform and opacity change, so it never triggers layout or paint.',\n defaults: { duration: 250, lift: 6 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n return ctx.animate(el, [{ transform: 'translateY(0) scale(1)' }, { transform: `translateY(${-Math.abs(Number(o.lift) || 6)}px) scale(1.02)` }], { duration: o.duration, easing: 'ease-out', fill: 'forwards' })?.finished.catch(() => undefined);\n },\n },\n];\n\n/** Register idle-reveal and gpu-lift (9.6). */\nexport function registerPerf3Pack(): void {\n registerEffects(PERF3_FX);\n}\n"],"names":["onFrame","registerEffects"],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
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
|
+
* 9.6 — Performance 3.0 (`motionary/fx/perf`, also `motionary/components/fx-perf`):
|
|
46
|
+
*
|
|
47
|
+
* - `runInWorker(fn, ...args)` — run a pure function in a throw-away Web
|
|
48
|
+
* Worker (built from its source) and get a promise of its result; runs
|
|
49
|
+
* inline when Workers are unavailable.
|
|
50
|
+
* - `offscreenRender(canvas, program, options)` — move a canvas animation
|
|
51
|
+
* off the main thread: `program` is the source of
|
|
52
|
+
* `function (ctx, t, w, h, state) {…}`; with OffscreenCanvas + Worker it
|
|
53
|
+
* runs in a worker (`backend: 'worker'`), otherwise on the main thread via
|
|
54
|
+
* the shared frame loop (`'main'`). Returns { backend, stop, resize }.
|
|
55
|
+
* - `fpsMeter()` — a rolling frames-per-second meter on the shared loop.
|
|
56
|
+
*
|
|
57
|
+
* Effects: `idle-reveal` (enter) waits for an idle moment before fading in
|
|
58
|
+
* (keeps first paint / input snappy); `gpu-lift` (hover) a compositor-only
|
|
59
|
+
* lift (transform + opacity only). Reduced motion: idle-reveal just shows,
|
|
60
|
+
* gpu-lift does nothing.
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
/** Run a pure function in a Web Worker; resolves with its (structured-cloneable) result (9.6). */
|
|
64
|
+
declare function runInWorker<A extends unknown[], R>(fn: (...args: A) => R | Promise<R>, ...args: A): Promise<R>;
|
|
65
|
+
type DrawProgram = string | ((ctx: CanvasRenderingContext2D, t: number, w: number, h: number, state: Record<string, unknown>) => void);
|
|
66
|
+
/** Animate `canvas` with `program` in a worker (OffscreenCanvas) when possible, else on the main thread (9.6). */
|
|
67
|
+
declare function offscreenRender(canvas: HTMLCanvasElement, program: DrawProgram, opts?: {
|
|
68
|
+
worker?: boolean;
|
|
69
|
+
paused?: boolean;
|
|
70
|
+
}): {
|
|
71
|
+
backend: 'worker' | 'main' | 'none';
|
|
72
|
+
stop(): void;
|
|
73
|
+
resize(w: number, h: number): void;
|
|
74
|
+
};
|
|
75
|
+
/** A rolling FPS meter on the shared frame loop: { fps, stop } (fps updates every frame) (9.6). */
|
|
76
|
+
declare function fpsMeter(window?: number): {
|
|
77
|
+
readonly fps: number;
|
|
78
|
+
readonly samples: number[];
|
|
79
|
+
stop(): void;
|
|
80
|
+
};
|
|
81
|
+
declare const PERF3_FX: EffectDefinition[];
|
|
82
|
+
/** Register idle-reveal and gpu-lift (9.6). */
|
|
83
|
+
declare function registerPerf3Pack(): void;
|
|
84
|
+
|
|
85
|
+
export { PERF3_FX, fpsMeter, offscreenRender, registerPerf3Pack, runInWorker };
|
|
86
|
+
export type { DrawProgram };
|
|
@@ -0,0 +1,86 @@
|
|
|
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
|
+
* 9.6 — Performance 3.0 (`motionary/fx/perf`, also `motionary/components/fx-perf`):
|
|
46
|
+
*
|
|
47
|
+
* - `runInWorker(fn, ...args)` — run a pure function in a throw-away Web
|
|
48
|
+
* Worker (built from its source) and get a promise of its result; runs
|
|
49
|
+
* inline when Workers are unavailable.
|
|
50
|
+
* - `offscreenRender(canvas, program, options)` — move a canvas animation
|
|
51
|
+
* off the main thread: `program` is the source of
|
|
52
|
+
* `function (ctx, t, w, h, state) {…}`; with OffscreenCanvas + Worker it
|
|
53
|
+
* runs in a worker (`backend: 'worker'`), otherwise on the main thread via
|
|
54
|
+
* the shared frame loop (`'main'`). Returns { backend, stop, resize }.
|
|
55
|
+
* - `fpsMeter()` — a rolling frames-per-second meter on the shared loop.
|
|
56
|
+
*
|
|
57
|
+
* Effects: `idle-reveal` (enter) waits for an idle moment before fading in
|
|
58
|
+
* (keeps first paint / input snappy); `gpu-lift` (hover) a compositor-only
|
|
59
|
+
* lift (transform + opacity only). Reduced motion: idle-reveal just shows,
|
|
60
|
+
* gpu-lift does nothing.
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
/** Run a pure function in a Web Worker; resolves with its (structured-cloneable) result (9.6). */
|
|
64
|
+
declare function runInWorker<A extends unknown[], R>(fn: (...args: A) => R | Promise<R>, ...args: A): Promise<R>;
|
|
65
|
+
type DrawProgram = string | ((ctx: CanvasRenderingContext2D, t: number, w: number, h: number, state: Record<string, unknown>) => void);
|
|
66
|
+
/** Animate `canvas` with `program` in a worker (OffscreenCanvas) when possible, else on the main thread (9.6). */
|
|
67
|
+
declare function offscreenRender(canvas: HTMLCanvasElement, program: DrawProgram, opts?: {
|
|
68
|
+
worker?: boolean;
|
|
69
|
+
paused?: boolean;
|
|
70
|
+
}): {
|
|
71
|
+
backend: 'worker' | 'main' | 'none';
|
|
72
|
+
stop(): void;
|
|
73
|
+
resize(w: number, h: number): void;
|
|
74
|
+
};
|
|
75
|
+
/** A rolling FPS meter on the shared frame loop: { fps, stop } (fps updates every frame) (9.6). */
|
|
76
|
+
declare function fpsMeter(window?: number): {
|
|
77
|
+
readonly fps: number;
|
|
78
|
+
readonly samples: number[];
|
|
79
|
+
stop(): void;
|
|
80
|
+
};
|
|
81
|
+
declare const PERF3_FX: EffectDefinition[];
|
|
82
|
+
/** Register idle-reveal and gpu-lift (9.6). */
|
|
83
|
+
declare function registerPerf3Pack(): void;
|
|
84
|
+
|
|
85
|
+
export { PERF3_FX, fpsMeter, offscreenRender, registerPerf3Pack, runInWorker };
|
|
86
|
+
export type { DrawProgram };
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { registerEffects } from '../chunks/registry-CnO7ZVPK.js';
|
|
2
|
+
import { o as onFrame } from '../chunks/base-CLuqlLfG.js';
|
|
3
|
+
|
|
4
|
+
/** Run a pure function in a Web Worker; resolves with its (structured-cloneable) result (9.6). */
|
|
5
|
+
function runInWorker(fn, ...args) {
|
|
6
|
+
if (typeof Worker === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined' || !URL.createObjectURL)
|
|
7
|
+
return Promise.resolve().then(() => fn(...args));
|
|
8
|
+
const src = `self.onmessage=async(e)=>{try{const r=await (${fn.toString()})(...e.data);self.postMessage({ok:true,r})}catch(err){self.postMessage({ok:false,e:String(err&&err.message||err)})}}`;
|
|
9
|
+
const url = URL.createObjectURL(new Blob([src], { type: 'text/javascript' }));
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
let w;
|
|
12
|
+
try {
|
|
13
|
+
w = new Worker(url);
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
URL.revokeObjectURL(url);
|
|
17
|
+
return resolve(Promise.resolve().then(() => fn(...args)));
|
|
18
|
+
}
|
|
19
|
+
const done = () => {
|
|
20
|
+
w.terminate();
|
|
21
|
+
URL.revokeObjectURL(url);
|
|
22
|
+
};
|
|
23
|
+
w.onmessage = (e) => {
|
|
24
|
+
done();
|
|
25
|
+
if (e.data?.ok)
|
|
26
|
+
resolve(e.data.r);
|
|
27
|
+
else
|
|
28
|
+
reject(new Error(e.data?.e || 'worker failed'));
|
|
29
|
+
};
|
|
30
|
+
w.onerror = (e) => {
|
|
31
|
+
done();
|
|
32
|
+
reject(new Error(e.message || 'worker error'));
|
|
33
|
+
};
|
|
34
|
+
w.postMessage(args);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** Animate `canvas` with `program` in a worker (OffscreenCanvas) when possible, else on the main thread (9.6). */
|
|
38
|
+
function offscreenRender(canvas, program, opts = {}) {
|
|
39
|
+
const code = typeof program === 'string' ? program : program.toString();
|
|
40
|
+
const canWorker = opts.worker !== false && typeof Worker !== 'undefined' && typeof canvas.transferControlToOffscreen === 'function' && typeof Blob !== 'undefined' && !!URL.createObjectURL;
|
|
41
|
+
if (canWorker) {
|
|
42
|
+
try {
|
|
43
|
+
const off = canvas.transferControlToOffscreen();
|
|
44
|
+
const src = `let c,ctx,w,h,st={},run=true,t0=0;const draw=(${code});self.onmessage=(e)=>{const d=e.data;if(d.canvas){c=d.canvas;ctx=c.getContext('2d');w=c.width;h=c.height;const loop=(t)=>{if(run){if(!t0)t0=t;draw(ctx,t-t0,w,h,st)}requestAnimationFrame(loop)};requestAnimationFrame(loop)}if(d.size){w=c.width=d.size[0];h=c.height=d.size[1]}if('run' in d)run=d.run;if(d.stop)close()}`;
|
|
45
|
+
const url = URL.createObjectURL(new Blob([src], { type: 'text/javascript' }));
|
|
46
|
+
const w = new Worker(url);
|
|
47
|
+
w.postMessage({ canvas: off }, [off]);
|
|
48
|
+
if (opts.paused)
|
|
49
|
+
w.postMessage({ run: false });
|
|
50
|
+
return {
|
|
51
|
+
backend: 'worker',
|
|
52
|
+
stop: () => {
|
|
53
|
+
w.postMessage({ stop: true });
|
|
54
|
+
w.terminate();
|
|
55
|
+
URL.revokeObjectURL(url);
|
|
56
|
+
},
|
|
57
|
+
resize: (a, b) => w.postMessage({ size: [a, b] }),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
/* fall back to the main thread */
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const ctx = canvas.getContext?.('2d');
|
|
65
|
+
if (!ctx)
|
|
66
|
+
return { backend: 'none', stop: () => undefined, resize: () => undefined };
|
|
67
|
+
// eslint-disable-next-line no-new-func
|
|
68
|
+
const draw = typeof program === 'function' ? program : new Function(`return (${code})`)();
|
|
69
|
+
const st = {};
|
|
70
|
+
let t = 0;
|
|
71
|
+
const stop = opts.paused
|
|
72
|
+
? () => undefined
|
|
73
|
+
: onFrame((_now, dt) => {
|
|
74
|
+
t += dt;
|
|
75
|
+
draw(ctx, t, canvas.width, canvas.height, st);
|
|
76
|
+
});
|
|
77
|
+
if (opts.paused)
|
|
78
|
+
draw(ctx, 0, canvas.width, canvas.height, st);
|
|
79
|
+
return {
|
|
80
|
+
backend: 'main',
|
|
81
|
+
stop,
|
|
82
|
+
resize: (a, b) => {
|
|
83
|
+
canvas.width = a;
|
|
84
|
+
canvas.height = b;
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** A rolling FPS meter on the shared frame loop: { fps, stop } (fps updates every frame) (9.6). */
|
|
89
|
+
function fpsMeter(window = 30) {
|
|
90
|
+
const samples = [];
|
|
91
|
+
let fps = 0;
|
|
92
|
+
const stop = onFrame((_t, dt) => {
|
|
93
|
+
if (dt <= 0)
|
|
94
|
+
return;
|
|
95
|
+
samples.push(1000 / dt);
|
|
96
|
+
if (samples.length > window)
|
|
97
|
+
samples.shift();
|
|
98
|
+
fps = Math.round(samples.reduce((a, b) => a + b, 0) / samples.length);
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
get fps() {
|
|
102
|
+
return fps;
|
|
103
|
+
},
|
|
104
|
+
samples,
|
|
105
|
+
stop,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const PERF3_FX = [
|
|
109
|
+
{
|
|
110
|
+
name: 'idle-reveal',
|
|
111
|
+
kind: 'enter',
|
|
112
|
+
description: 'Waits for an idle moment (requestIdleCallback, ≤ `timeout` ms) before fading in, keeping first paint and input snappy.',
|
|
113
|
+
defaults: { duration: 400, timeout: 600 },
|
|
114
|
+
run: (el, o, ctx) => {
|
|
115
|
+
if (ctx.reduced)
|
|
116
|
+
return;
|
|
117
|
+
const prev = el.style.opacity;
|
|
118
|
+
el.style.opacity = '0';
|
|
119
|
+
ctx.onCleanup(() => (el.style.opacity = prev));
|
|
120
|
+
return new Promise((resolve) => {
|
|
121
|
+
const go = () => {
|
|
122
|
+
el.style.opacity = prev;
|
|
123
|
+
const a = ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: o.duration, easing: 'ease-out' });
|
|
124
|
+
if (a)
|
|
125
|
+
a.finished.then(() => resolve(), () => resolve());
|
|
126
|
+
else
|
|
127
|
+
resolve();
|
|
128
|
+
};
|
|
129
|
+
const ric = globalThis.requestIdleCallback;
|
|
130
|
+
if (ric)
|
|
131
|
+
ric(go, { timeout: Number(o.timeout) || 600 });
|
|
132
|
+
else
|
|
133
|
+
setTimeout(go, 1);
|
|
134
|
+
});
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'gpu-lift',
|
|
139
|
+
kind: 'hover',
|
|
140
|
+
description: 'A compositor-only hover lift — only transform and opacity change, so it never triggers layout or paint.',
|
|
141
|
+
defaults: { duration: 250, lift: 6 },
|
|
142
|
+
run: (el, o, ctx) => {
|
|
143
|
+
if (ctx.reduced)
|
|
144
|
+
return;
|
|
145
|
+
return ctx.animate(el, [{ transform: 'translateY(0) scale(1)' }, { transform: `translateY(${-Math.abs(Number(o.lift) || 6)}px) scale(1.02)` }], { duration: o.duration, easing: 'ease-out', fill: 'forwards' })?.finished.catch(() => undefined);
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
];
|
|
149
|
+
/** Register idle-reveal and gpu-lift (9.6). */
|
|
150
|
+
function registerPerf3Pack() {
|
|
151
|
+
registerEffects(PERF3_FX);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export { PERF3_FX, fpsMeter, offscreenRender, registerPerf3Pack, runInWorker };
|
|
155
|
+
//# sourceMappingURL=fx-perf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fx-perf.js","sources":["../../src/components/fx2/perf3.ts"],"sourcesContent":["/**\n * 9.6 — Performance 3.0 (`motionary/fx/perf`, also `motionary/components/fx-perf`):\n *\n * - `runInWorker(fn, ...args)` — run a pure function in a throw-away Web\n * Worker (built from its source) and get a promise of its result; runs\n * inline when Workers are unavailable.\n * - `offscreenRender(canvas, program, options)` — move a canvas animation\n * off the main thread: `program` is the source of\n * `function (ctx, t, w, h, state) {…}`; with OffscreenCanvas + Worker it\n * runs in a worker (`backend: 'worker'`), otherwise on the main thread via\n * the shared frame loop (`'main'`). Returns { backend, stop, resize }.\n * - `fpsMeter()` — a rolling frames-per-second meter on the shared loop.\n *\n * Effects: `idle-reveal` (enter) waits for an idle moment before fading in\n * (keeps first paint / input snappy); `gpu-lift` (hover) a compositor-only\n * lift (transform + opacity only). Reduced motion: idle-reveal just shows,\n * gpu-lift does nothing.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\nimport { onFrame } from '../base';\n\n/** Run a pure function in a Web Worker; resolves with its (structured-cloneable) result (9.6). */\nexport function runInWorker<A extends unknown[], R>(fn: (...args: A) => R | Promise<R>, ...args: A): Promise<R> {\n if (typeof Worker === 'undefined' || typeof Blob === 'undefined' || typeof URL === 'undefined' || !URL.createObjectURL) return Promise.resolve().then(() => fn(...args));\n const src = `self.onmessage=async(e)=>{try{const r=await (${fn.toString()})(...e.data);self.postMessage({ok:true,r})}catch(err){self.postMessage({ok:false,e:String(err&&err.message||err)})}}`;\n const url = URL.createObjectURL(new Blob([src], { type: 'text/javascript' }));\n return new Promise<R>((resolve, reject) => {\n let w: Worker;\n try {\n w = new Worker(url);\n } catch (e) {\n URL.revokeObjectURL(url);\n return resolve(Promise.resolve().then(() => fn(...args)));\n }\n const done = () => {\n w.terminate();\n URL.revokeObjectURL(url);\n };\n w.onmessage = (e) => {\n done();\n if (e.data?.ok) resolve(e.data.r as R);\n else reject(new Error(e.data?.e || 'worker failed'));\n };\n w.onerror = (e) => {\n done();\n reject(new Error(e.message || 'worker error'));\n };\n w.postMessage(args);\n });\n}\n\nexport type DrawProgram = string | ((ctx: CanvasRenderingContext2D, t: number, w: number, h: number, state: Record<string, unknown>) => void);\n/** Animate `canvas` with `program` in a worker (OffscreenCanvas) when possible, else on the main thread (9.6). */\nexport function offscreenRender(canvas: HTMLCanvasElement, program: DrawProgram, opts: { worker?: boolean; paused?: boolean } = {}): { backend: 'worker' | 'main' | 'none'; stop(): void; resize(w: number, h: number): void } {\n const code = typeof program === 'string' ? program : program.toString();\n const canWorker = opts.worker !== false && typeof Worker !== 'undefined' && typeof (canvas as any).transferControlToOffscreen === 'function' && typeof Blob !== 'undefined' && !!URL.createObjectURL;\n if (canWorker) {\n try {\n const off = (canvas as any).transferControlToOffscreen();\n const src = `let c,ctx,w,h,st={},run=true,t0=0;const draw=(${code});self.onmessage=(e)=>{const d=e.data;if(d.canvas){c=d.canvas;ctx=c.getContext('2d');w=c.width;h=c.height;const loop=(t)=>{if(run){if(!t0)t0=t;draw(ctx,t-t0,w,h,st)}requestAnimationFrame(loop)};requestAnimationFrame(loop)}if(d.size){w=c.width=d.size[0];h=c.height=d.size[1]}if('run' in d)run=d.run;if(d.stop)close()}`;\n const url = URL.createObjectURL(new Blob([src], { type: 'text/javascript' }));\n const w = new Worker(url);\n w.postMessage({ canvas: off }, [off]);\n if (opts.paused) w.postMessage({ run: false });\n return {\n backend: 'worker',\n stop: () => {\n w.postMessage({ stop: true });\n w.terminate();\n URL.revokeObjectURL(url);\n },\n resize: (a, b) => w.postMessage({ size: [a, b] }),\n };\n } catch {\n /* fall back to the main thread */\n }\n }\n const ctx = canvas.getContext?.('2d');\n if (!ctx) return { backend: 'none', stop: () => undefined, resize: () => undefined };\n // eslint-disable-next-line no-new-func\n const draw = typeof program === 'function' ? program : (new Function(`return (${code})`)() as Exclude<DrawProgram, string>);\n const st: Record<string, unknown> = {};\n let t = 0;\n const stop = opts.paused\n ? () => undefined\n : onFrame((_now, dt) => {\n t += dt;\n draw(ctx, t, canvas.width, canvas.height, st);\n });\n if (opts.paused) draw(ctx, 0, canvas.width, canvas.height, st);\n return {\n backend: 'main',\n stop,\n resize: (a, b) => {\n canvas.width = a;\n canvas.height = b;\n },\n };\n}\n\n/** A rolling FPS meter on the shared frame loop: { fps, stop } (fps updates every frame) (9.6). */\nexport function fpsMeter(window = 30): { readonly fps: number; readonly samples: number[]; stop(): void } {\n const samples: number[] = [];\n let fps = 0;\n const stop = onFrame((_t, dt) => {\n if (dt <= 0) return;\n samples.push(1000 / dt);\n if (samples.length > window) samples.shift();\n fps = Math.round(samples.reduce((a, b) => a + b, 0) / samples.length);\n });\n return {\n get fps() {\n return fps;\n },\n samples,\n stop,\n };\n}\n\nexport const PERF3_FX: EffectDefinition[] = [\n {\n name: 'idle-reveal',\n kind: 'enter',\n description: 'Waits for an idle moment (requestIdleCallback, ≤ `timeout` ms) before fading in, keeping first paint and input snappy.',\n defaults: { duration: 400, timeout: 600 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n const prev = el.style.opacity;\n el.style.opacity = '0';\n ctx.onCleanup(() => (el.style.opacity = prev));\n return new Promise<void>((resolve) => {\n const go = () => {\n el.style.opacity = prev;\n const a = ctx.animate(el, [{ opacity: 0 }, { opacity: 1 }], { duration: o.duration, easing: 'ease-out' });\n if (a) a.finished.then(() => resolve(), () => resolve());\n else resolve();\n };\n const ric = (globalThis as any).requestIdleCallback as ((cb: () => void, o?: { timeout: number }) => number) | undefined;\n if (ric) ric(go, { timeout: Number(o.timeout) || 600 });\n else setTimeout(go, 1);\n });\n },\n },\n {\n name: 'gpu-lift',\n kind: 'hover',\n description: 'A compositor-only hover lift — only transform and opacity change, so it never triggers layout or paint.',\n defaults: { duration: 250, lift: 6 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n return ctx.animate(el, [{ transform: 'translateY(0) scale(1)' }, { transform: `translateY(${-Math.abs(Number(o.lift) || 6)}px) scale(1.02)` }], { duration: o.duration, easing: 'ease-out', fill: 'forwards' })?.finished.catch(() => undefined);\n },\n },\n];\n\n/** Register idle-reveal and gpu-lift (9.6). */\nexport function registerPerf3Pack(): void {\n registerEffects(PERF3_FX);\n}\n"],"names":[],"mappings":"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"}
|
package/dist/components/fx2.cjs
CHANGED
|
@@ -31,6 +31,7 @@ var components_fxLottie = require('./fx-lottie.cjs');
|
|
|
31
31
|
var components_fxGenart = require('./fx-genart.cjs');
|
|
32
32
|
var components_fxVideo = require('./fx-video.cjs');
|
|
33
33
|
var components_fxSafe = require('./fx-safe.cjs');
|
|
34
|
+
var components_fxPerf = require('./fx-perf.cjs');
|
|
34
35
|
require('../chunks/registry-BVklOepd.cjs');
|
|
35
36
|
require('../chunks/base-DoRUZBy-.cjs');
|
|
36
37
|
require('../chunks/generative-BHIj-NU0.cjs');
|
|
@@ -69,6 +70,7 @@ const EFFECT_PACKS = {
|
|
|
69
70
|
genart: components_fxGenart.GENART_FX,
|
|
70
71
|
video: components_fxVideo.VIDEO_FX,
|
|
71
72
|
safe: components_fxSafe.SAFE_FX,
|
|
73
|
+
perf3: components_fxPerf.PERF3_FX,
|
|
72
74
|
};
|
|
73
75
|
/** Register every 6.x effect pack (idempotent). */
|
|
74
76
|
function registerEffectPacks() {
|
|
@@ -102,6 +104,7 @@ function registerEffectPacks() {
|
|
|
102
104
|
components_fxGenart.registerGenArtPack();
|
|
103
105
|
components_fxVideo.registerVideoPack();
|
|
104
106
|
components_fxSafe.registerSafePack();
|
|
107
|
+
components_fxPerf.registerPerf3Pack();
|
|
105
108
|
}
|
|
106
109
|
|
|
107
110
|
exports.EFFECT_PACK_FORMAT = manifest.EFFECT_PACK_FORMAT;
|
|
@@ -225,6 +228,11 @@ exports.isFlashSafe = components_fxSafe.isFlashSafe;
|
|
|
225
228
|
exports.loadMotionPreferences = components_fxSafe.loadMotionPreferences;
|
|
226
229
|
exports.registerSafePack = components_fxSafe.registerSafePack;
|
|
227
230
|
exports.vestibularSafe = components_fxSafe.vestibularSafe;
|
|
231
|
+
exports.PERF3_FX = components_fxPerf.PERF3_FX;
|
|
232
|
+
exports.fpsMeter = components_fxPerf.fpsMeter;
|
|
233
|
+
exports.offscreenRender = components_fxPerf.offscreenRender;
|
|
234
|
+
exports.registerPerf3Pack = components_fxPerf.registerPerf3Pack;
|
|
235
|
+
exports.runInWorker = components_fxPerf.runInWorker;
|
|
228
236
|
exports.EFFECT_PACKS = EFFECT_PACKS;
|
|
229
237
|
exports.registerEffectPacks = registerEffectPacks;
|
|
230
238
|
//# sourceMappingURL=fx2.cjs.map
|