use-scroll-animate 6.1.1 → 6.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 +33 -0
- package/dist/chunks/{base-Yno7N2eC.js → base-DchG4q_S.js} +2 -2
- package/dist/chunks/{base-Yno7N2eC.js.map → base-DchG4q_S.js.map} +1 -1
- package/dist/chunks/{core-BIOaYdgN.js → core-D2vF8kZb.js} +2 -2
- package/dist/chunks/{core-BIOaYdgN.js.map → core-D2vF8kZb.js.map} +1 -1
- package/dist/chunks/{core-CUGCsMsJ.js → core-DVyTlo9Q.js} +2 -2
- package/dist/chunks/{core-CUGCsMsJ.js.map → core-DVyTlo9Q.js.map} +1 -1
- package/dist/chunks/{fx-BqDeFywO.js → fx-DUMVKSvg.js} +2 -2
- package/dist/chunks/{fx-BqDeFywO.js.map → fx-DUMVKSvg.js.map} +1 -1
- package/dist/chunks/generative-BHIj-NU0.cjs +295 -0
- package/dist/chunks/generative-BHIj-NU0.cjs.map +1 -0
- package/dist/chunks/generative-BRUZaIsX.js +290 -0
- package/dist/chunks/generative-BRUZaIsX.js.map +1 -0
- package/dist/chunks/gpu-BBRLgEzM.cjs +388 -0
- package/dist/chunks/gpu-BBRLgEzM.cjs.map +1 -0
- package/dist/chunks/gpu-XHWzeNb5.js +381 -0
- package/dist/chunks/gpu-XHWzeNb5.js.map +1 -0
- package/dist/chunks/registry-Bu5NrAyA.js +121 -0
- package/dist/chunks/registry-Bu5NrAyA.js.map +1 -0
- package/dist/chunks/registry-DehBVRDV.cjs +131 -0
- package/dist/chunks/registry-DehBVRDV.cjs.map +1 -0
- package/dist/chunks/shared-eweTlzxv.js +50 -0
- package/dist/chunks/shared-eweTlzxv.js.map +1 -0
- package/dist/chunks/shared-jkgRH-Hx.cjs +58 -0
- package/dist/chunks/shared-jkgRH-Hx.cjs.map +1 -0
- package/dist/chunks/{spring-DfQO5USi.js → spring-BhoT09Qb.js} +2 -2
- package/dist/chunks/{spring-DfQO5USi.js.map → spring-BhoT09Qb.js.map} +1 -1
- package/dist/chunks/{variants-VNscPeTD.js → variants-C_hv_s23.js} +2 -2
- package/dist/chunks/{variants-VNscPeTD.js.map → variants-C_hv_s23.js.map} +1 -1
- package/dist/components/a11y.js +2 -2
- package/dist/components/angular.cjs +1 -0
- package/dist/components/angular.cjs.map +1 -1
- package/dist/components/angular.js +7 -6
- package/dist/components/angular.js.map +1 -1
- package/dist/components/background.js +2 -2
- package/dist/components/bridge.js +1 -1
- package/dist/components/cards.js +2 -2
- package/dist/components/click.js +3 -3
- package/dist/components/depth.js +3 -3
- package/dist/components/effects.cjs +72 -403
- package/dist/components/effects.cjs.map +1 -1
- package/dist/components/effects.js +9 -339
- package/dist/components/effects.js.map +1 -1
- package/dist/components/feedback.js +1 -1
- package/dist/components/fx-gpu.cjs +13 -0
- package/dist/components/fx-gpu.cjs.map +1 -0
- package/dist/components/fx-gpu.d.cts +63 -0
- package/dist/components/fx-gpu.d.ts +63 -0
- package/dist/components/fx-gpu.js +6 -0
- package/dist/components/fx-gpu.js.map +1 -0
- package/dist/components/fx-text.cjs +267 -0
- package/dist/components/fx-text.cjs.map +1 -0
- package/dist/components/fx-text.d.cts +70 -0
- package/dist/components/fx-text.d.ts +70 -0
- package/dist/components/fx-text.js +263 -0
- package/dist/components/fx-text.js.map +1 -0
- package/dist/components/fx.cjs +13 -133
- package/dist/components/fx.cjs.map +1 -1
- package/dist/components/fx.js +6 -125
- package/dist/components/fx.js.map +1 -1
- package/dist/components/fx2.cjs +32 -0
- package/dist/components/fx2.cjs.map +1 -0
- package/dist/components/fx2.d.cts +162 -0
- package/dist/components/fx2.d.ts +162 -0
- package/dist/components/fx2.js +22 -0
- package/dist/components/fx2.js.map +1 -0
- package/dist/components/gesture.js +4 -4
- package/dist/components/interaction.js +1 -1
- package/dist/components/layout.js +1 -1
- package/dist/components/lite.cjs +5 -9
- package/dist/components/lite.cjs.map +1 -1
- package/dist/components/lite.js +5 -9
- package/dist/components/lite.js.map +1 -1
- package/dist/components/packs.js +1 -1
- package/dist/components/page.js +3 -3
- package/dist/components/perf.js +2 -2
- package/dist/components/physics.js +3 -3
- package/dist/components/reveal.js +1 -1
- package/dist/components/solid.cjs +1 -0
- package/dist/components/solid.cjs.map +1 -1
- package/dist/components/solid.js +7 -6
- 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 +7 -6
- package/dist/components/svelte.js.map +1 -1
- package/dist/components/svg.js +1 -1
- package/dist/components/text.js +2 -2
- package/dist/components/timeline.js +3 -3
- package/dist/components/transitions.js +1 -1
- package/dist/components/ui.js +4 -4
- package/dist/components/vue.cjs +1 -0
- package/dist/components/vue.cjs.map +1 -1
- package/dist/components/vue.js +7 -6
- package/dist/components/vue.js.map +1 -1
- package/dist/components/webgl.js +1 -1
- package/dist/components/widgets.cjs +1174 -0
- package/dist/components/widgets.cjs.map +1 -0
- package/dist/components/widgets.d.cts +206 -0
- package/dist/components/widgets.d.ts +206 -0
- package/dist/components/widgets.js +1155 -0
- package/dist/components/widgets.js.map +1 -0
- package/dist/components.cjs +10 -9
- package/dist/components.cjs.map +1 -1
- package/dist/components.js +10 -9
- package/dist/components.js.map +1 -1
- package/dist/components.umd.js +2 -2
- package/dist/components.umd.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/widgets.umd.js +2 -0
- package/dist/widgets.umd.js.map +1 -0
- package/docs/ROADMAP.md +10 -11
- package/docs/components.md +61 -0
- package/package.json +41 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { y as defineElement, A as kindOf, z as EASE_OUT, k as clamp, F as FLUENT_DECELERATE, E as EASE_SPRING } from '../chunks/base-DchG4q_S.js';
|
|
2
2
|
|
|
3
3
|
var css$4 = "usa-spinner{--usa-spinner-size:32px;--usa-spinner-color:currentColor;position:relative;display:inline-block;vertical-align:middle;flex:none;width:var(--usa-spinner-size);height:var(--usa-spinner-size);color:var(--usa-spinner-color)}usa-spinner i{position:absolute;display:block}usa-spinner[paused] *,usa-spinner[paused] *::after{animation-play-state:paused !important}usa-spinner svg{width:100%;height:100%;animation:usa-spin 2s linear infinite;overflow:visible}usa-spinner svg circle{fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-dasharray:0.5 100;stroke-dashoffset:0;animation:usa-ring-arc 1.6s ease-in-out infinite}@keyframes usa-spin{to{transform:rotate(360deg)}}@keyframes usa-ring-arc{0%{stroke-dasharray:0.5 100;stroke-dashoffset:0}50%{stroke-dasharray:62 100;stroke-dashoffset:-20}100%{stroke-dasharray:0.5 100;stroke-dashoffset:-99}}usa-spinner[data-kind=\"windows\"] i{inset:0;opacity:0;animation:usa-orbit 5.5s infinite}usa-spinner[data-kind=\"windows\"] i::after{content:\"\";position:absolute;left:50%;top:0;width:12%;height:12%;margin-left:-6%;border-radius:50%;background:currentColor}usa-spinner[data-kind=\"windows\"] i:nth-child(2){animation-delay:240ms;--n:1}usa-spinner[data-kind=\"windows\"] i:nth-child(3){animation-delay:480ms;--n:2}usa-spinner[data-kind=\"windows\"] i:nth-child(4){animation-delay:720ms;--n:3}usa-spinner[data-kind=\"windows\"] i:nth-child(5){animation-delay:960ms;--n:4}@keyframes usa-orbit{0%{transform:rotate(225deg);opacity:1;animation-timing-function:ease-out}7%{transform:rotate(345deg);animation-timing-function:linear}30%{transform:rotate(455deg);animation-timing-function:ease-in-out}39%{transform:rotate(690deg);animation-timing-function:linear}70%{transform:rotate(815deg);opacity:1;animation-timing-function:ease-out}75%{transform:rotate(945deg);animation-timing-function:ease-out}76%,100%{transform:rotate(945deg);opacity:0}}usa-spinner[data-kind=\"ring\"] i{inset:0;border-radius:50%;border:calc(var(--usa-spinner-size) / 9) solid color-mix(in srgb,currentColor 20%,transparent);border-top-color:currentColor;animation:usa-spin 0.8s linear infinite}usa-spinner[data-kind=\"dots\"]{display:inline-flex;align-items:center;justify-content:space-between;height:calc(var(--usa-spinner-size) / 2.5)}usa-spinner[data-kind=\"dots\"] i{position:static;width:22%;aspect-ratio:1;border-radius:50%;background:currentColor;animation:usa-dot 1.2s ease-in-out infinite}usa-spinner[data-kind=\"dots\"] i:nth-child(2){animation-delay:0.15s}usa-spinner[data-kind=\"dots\"] i:nth-child(3){animation-delay:0.3s}@keyframes usa-dot{0%,60%,100%{transform:translateY(0);opacity:0.35}30%{transform:translateY(-70%);opacity:1}}usa-spinner[data-kind=\"pulse\"] i{inset:0;border-radius:50%;background:currentColor;opacity:0;animation:usa-pulse 1.6s cubic-bezier(0.22,1,0.36,1) infinite}usa-spinner[data-kind=\"pulse\"] i:nth-child(2){animation-delay:0.8s}@keyframes usa-pulse{from{transform:scale(0.1);opacity:0.8}to{transform:scale(1);opacity:0}}usa-spinner[data-kind=\"bars\"]{display:inline-flex;align-items:center;justify-content:space-between}usa-spinner[data-kind=\"bars\"] i{position:static;width:16%;height:100%;border-radius:2px;background:currentColor;transform:scaleY(0.35);animation:usa-bar 1s ease-in-out infinite}usa-spinner[data-kind=\"bars\"] i:nth-child(2){animation-delay:0.12s}usa-spinner[data-kind=\"bars\"] i:nth-child(3){animation-delay:0.24s}usa-spinner[data-kind=\"bars\"] i:nth-child(4){animation-delay:0.36s}@keyframes usa-bar{0%,100%{transform:scaleY(0.35)}40%{transform:scaleY(1)}}@media (prefers-reduced-motion:reduce){usa-spinner svg,usa-spinner i,usa-spinner i::after{animation:usa-calm 2.4s ease-in-out infinite !important}usa-spinner[data-kind=\"windows\"] i{transform:rotate(calc(var(--n,0) * 72deg))}usa-spinner svg circle{animation:none;stroke-dasharray:30 100}}@keyframes usa-calm{0%,100%{opacity:1}50%{opacity:0.4}}";
|
|
4
4
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('../chunks/registry-DehBVRDV.cjs');
|
|
4
|
+
require('../chunks/generative-BHIj-NU0.cjs');
|
|
5
|
+
require('../chunks/shared-jkgRH-Hx.cjs');
|
|
6
|
+
var components_fxGpu = require('../chunks/gpu-BBRLgEzM.cjs');
|
|
7
|
+
require('../chunks/base-BaQV-2ha.cjs');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
exports.GPU_FX = components_fxGpu.GPU_FX;
|
|
12
|
+
exports.registerGpuEffects = components_fxGpu.registerGpuEffects;
|
|
13
|
+
//# sourceMappingURL=fx-gpu.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fx-gpu.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';
|
|
2
|
+
type Cleanup = () => void;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 5.0 — unified plugin-style effect registration. Every effect (built-in or
|
|
6
|
+
* yours) is a plain object registered once and played the same way:
|
|
7
|
+
* `playEffect(el, name)`, `bindEffect(el, name, { trigger })` or
|
|
8
|
+
* `<usa-fx effect="name" trigger="click">`. Effects get a context that
|
|
9
|
+
* already applies reduced motion, motion sensitivity, intensity and the
|
|
10
|
+
* animation budget.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
declare const EFFECT_KINDS: readonly ["enter", "exit", "attention", "click", "hover", "card", "loop", "page", "background", "text", "cursor", "scroll"];
|
|
14
|
+
type EffectKind = (typeof EFFECT_KINDS)[number];
|
|
15
|
+
interface EffectContext {
|
|
16
|
+
/** Reduced motion applies (OS setting, `minimal` / `static` sensitivity). */
|
|
17
|
+
readonly reduced: boolean;
|
|
18
|
+
readonly sensitivity: MotionSensitivity;
|
|
19
|
+
/** The triggering event (pointer position for click effects), if any. */
|
|
20
|
+
readonly event?: Event;
|
|
21
|
+
/** `el.animate()` with the library's motion rules (may return `null`). */
|
|
22
|
+
animate(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null;
|
|
23
|
+
/** Register teardown for long-running effects (loops, listeners). */
|
|
24
|
+
onCleanup(fn: Cleanup): void;
|
|
25
|
+
}
|
|
26
|
+
interface EffectDefinition<O extends Record<string, unknown> = Record<string, any>> {
|
|
27
|
+
/** Unique, kebab-case. */
|
|
28
|
+
name: string;
|
|
29
|
+
kind: EffectKind;
|
|
30
|
+
/** One line for docs and the gallery. */
|
|
31
|
+
description?: string;
|
|
32
|
+
/** Option defaults (merged under the caller's options). */
|
|
33
|
+
defaults?: Partial<O>;
|
|
34
|
+
/**
|
|
35
|
+
* Under reduced motion: `'skip'` (do nothing — default for loop, background
|
|
36
|
+
* and cursor effects) or `'run'` (run with `ctx.reduced === true`, the
|
|
37
|
+
* effect degrades itself — default for everything else).
|
|
38
|
+
*/
|
|
39
|
+
reduced?: 'skip' | 'run';
|
|
40
|
+
/** Play the effect. Return an Animation / Promise to be awaited, or a cleanup. */
|
|
41
|
+
run(el: HTMLElement, options: O, ctx: EffectContext): void | Cleanup | Animation | null | Promise<unknown>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 6.2 — GPU effect pack (`motionary/components/fx-gpu`), registered through
|
|
46
|
+
* `registerEffect()`:
|
|
47
|
+
*
|
|
48
|
+
* - WebGL2 shaders with a Canvas 2D fallback (kind `background`): `fluid`
|
|
49
|
+
* (domain-warped fluid that swirls around the pointer), `smoke`, `fire`,
|
|
50
|
+
* `ink` (ink blooming in water), `fireflies`.
|
|
51
|
+
* - Canvas 2D particles (kind `background`): `sakura` (falling cherry
|
|
52
|
+
* petals), `leaves` (tumbling autumn leaves).
|
|
53
|
+
* - `splash` (kind `click`): droplets + a ring burst from the pointer.
|
|
54
|
+
*
|
|
55
|
+
* Every background renders only while visible, lowers its resolution when
|
|
56
|
+
* frames are slow, and draws one static frame under reduced motion.
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
declare const GPU_FX: EffectDefinition[];
|
|
60
|
+
/** Register the 6.2 GPU pack (idempotent). */
|
|
61
|
+
declare function registerGpuEffects(): void;
|
|
62
|
+
|
|
63
|
+
export { GPU_FX, registerGpuEffects };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';
|
|
2
|
+
type Cleanup = () => void;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 5.0 — unified plugin-style effect registration. Every effect (built-in or
|
|
6
|
+
* yours) is a plain object registered once and played the same way:
|
|
7
|
+
* `playEffect(el, name)`, `bindEffect(el, name, { trigger })` or
|
|
8
|
+
* `<usa-fx effect="name" trigger="click">`. Effects get a context that
|
|
9
|
+
* already applies reduced motion, motion sensitivity, intensity and the
|
|
10
|
+
* animation budget.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
declare const EFFECT_KINDS: readonly ["enter", "exit", "attention", "click", "hover", "card", "loop", "page", "background", "text", "cursor", "scroll"];
|
|
14
|
+
type EffectKind = (typeof EFFECT_KINDS)[number];
|
|
15
|
+
interface EffectContext {
|
|
16
|
+
/** Reduced motion applies (OS setting, `minimal` / `static` sensitivity). */
|
|
17
|
+
readonly reduced: boolean;
|
|
18
|
+
readonly sensitivity: MotionSensitivity;
|
|
19
|
+
/** The triggering event (pointer position for click effects), if any. */
|
|
20
|
+
readonly event?: Event;
|
|
21
|
+
/** `el.animate()` with the library's motion rules (may return `null`). */
|
|
22
|
+
animate(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null;
|
|
23
|
+
/** Register teardown for long-running effects (loops, listeners). */
|
|
24
|
+
onCleanup(fn: Cleanup): void;
|
|
25
|
+
}
|
|
26
|
+
interface EffectDefinition<O extends Record<string, unknown> = Record<string, any>> {
|
|
27
|
+
/** Unique, kebab-case. */
|
|
28
|
+
name: string;
|
|
29
|
+
kind: EffectKind;
|
|
30
|
+
/** One line for docs and the gallery. */
|
|
31
|
+
description?: string;
|
|
32
|
+
/** Option defaults (merged under the caller's options). */
|
|
33
|
+
defaults?: Partial<O>;
|
|
34
|
+
/**
|
|
35
|
+
* Under reduced motion: `'skip'` (do nothing — default for loop, background
|
|
36
|
+
* and cursor effects) or `'run'` (run with `ctx.reduced === true`, the
|
|
37
|
+
* effect degrades itself — default for everything else).
|
|
38
|
+
*/
|
|
39
|
+
reduced?: 'skip' | 'run';
|
|
40
|
+
/** Play the effect. Return an Animation / Promise to be awaited, or a cleanup. */
|
|
41
|
+
run(el: HTMLElement, options: O, ctx: EffectContext): void | Cleanup | Animation | null | Promise<unknown>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 6.2 — GPU effect pack (`motionary/components/fx-gpu`), registered through
|
|
46
|
+
* `registerEffect()`:
|
|
47
|
+
*
|
|
48
|
+
* - WebGL2 shaders with a Canvas 2D fallback (kind `background`): `fluid`
|
|
49
|
+
* (domain-warped fluid that swirls around the pointer), `smoke`, `fire`,
|
|
50
|
+
* `ink` (ink blooming in water), `fireflies`.
|
|
51
|
+
* - Canvas 2D particles (kind `background`): `sakura` (falling cherry
|
|
52
|
+
* petals), `leaves` (tumbling autumn leaves).
|
|
53
|
+
* - `splash` (kind `click`): droplets + a ring burst from the pointer.
|
|
54
|
+
*
|
|
55
|
+
* Every background renders only while visible, lowers its resolution when
|
|
56
|
+
* frames are slow, and draws one static frame under reduced motion.
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
declare const GPU_FX: EffectDefinition[];
|
|
60
|
+
/** Register the 6.2 GPU pack (idempotent). */
|
|
61
|
+
declare function registerGpuEffects(): void;
|
|
62
|
+
|
|
63
|
+
export { GPU_FX, registerGpuEffects };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import '../chunks/registry-Bu5NrAyA.js';
|
|
2
|
+
import '../chunks/generative-BRUZaIsX.js';
|
|
3
|
+
import '../chunks/shared-eweTlzxv.js';
|
|
4
|
+
export { G as GPU_FX, r as registerGpuEffects } from '../chunks/gpu-XHWzeNb5.js';
|
|
5
|
+
import '../chunks/base-DchG4q_S.js';
|
|
6
|
+
//# sourceMappingURL=fx-gpu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fx-gpu.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var registry = require('../chunks/registry-DehBVRDV.cjs');
|
|
4
|
+
var base = require('../chunks/base-BaQV-2ha.cjs');
|
|
5
|
+
var shared = require('../chunks/shared-jkgRH-Hx.cjs');
|
|
6
|
+
|
|
7
|
+
/** Split `el`'s text into `aria-hidden` inline-block characters (idempotent). Returns them. */
|
|
8
|
+
function splitChars(el) {
|
|
9
|
+
if (el.dataset.usaChars)
|
|
10
|
+
return Array.from(el.querySelectorAll(':scope > .usa-ch'));
|
|
11
|
+
const text = el.textContent || '';
|
|
12
|
+
el.textContent = '';
|
|
13
|
+
for (const ch of Array.from(text)) {
|
|
14
|
+
const s = document.createElement('span');
|
|
15
|
+
s.className = 'usa-ch';
|
|
16
|
+
s.setAttribute('aria-hidden', 'true');
|
|
17
|
+
s.style.cssText = 'display:inline-block;white-space:pre';
|
|
18
|
+
s.textContent = ch;
|
|
19
|
+
el.appendChild(s);
|
|
20
|
+
}
|
|
21
|
+
el.appendChild(base.srText(text.trim()));
|
|
22
|
+
el.dataset.usaChars = '1';
|
|
23
|
+
return Array.from(el.querySelectorAll(':scope > .usa-ch'));
|
|
24
|
+
}
|
|
25
|
+
const raf = (fn) => (typeof requestAnimationFrame === 'function' ? requestAnimationFrame(fn) : 0);
|
|
26
|
+
const caf = (h) => {
|
|
27
|
+
if (h && typeof cancelAnimationFrame === 'function')
|
|
28
|
+
cancelAnimationFrame(h);
|
|
29
|
+
};
|
|
30
|
+
let fid = 0;
|
|
31
|
+
const TEXT3_FX = [
|
|
32
|
+
{
|
|
33
|
+
name: 'liquid-text',
|
|
34
|
+
kind: 'loop',
|
|
35
|
+
description: 'The text ripples like liquid: an animated SVG turbulence + displacement filter (`strength`, `speed`).',
|
|
36
|
+
defaults: { strength: 7, speed: 1 },
|
|
37
|
+
run: (el, o) => {
|
|
38
|
+
const id = `usa-liquid-${++fid}`;
|
|
39
|
+
const ns = 'http://www.w3.org/2000/svg';
|
|
40
|
+
const svg = document.createElementNS(ns, 'svg');
|
|
41
|
+
svg.setAttribute('aria-hidden', 'true');
|
|
42
|
+
svg.setAttribute('width', '0');
|
|
43
|
+
svg.setAttribute('height', '0');
|
|
44
|
+
svg.style.cssText = 'position:absolute;width:0;height:0;overflow:hidden';
|
|
45
|
+
svg.innerHTML = `<filter id="${id}" x="-10%" y="-20%" width="120%" height="140%"><feTurbulence type="fractalNoise" baseFrequency="0.012 0.06" numOctaves="2" seed="3" result="n"/><feDisplacementMap in="SourceGraphic" in2="n" scale="${Number(o.strength) || 7}" xChannelSelector="R" yChannelSelector="G"/></filter>`;
|
|
46
|
+
document.body.appendChild(svg);
|
|
47
|
+
const turb = svg.querySelector('feTurbulence');
|
|
48
|
+
const prev = el.style.filter;
|
|
49
|
+
el.style.filter = `url(#${id})`;
|
|
50
|
+
let h = 0;
|
|
51
|
+
const t0 = performance.now();
|
|
52
|
+
const tick = (now) => {
|
|
53
|
+
const t = ((now - t0) / 1000) * (Number(o.speed) || 1);
|
|
54
|
+
turb?.setAttribute('baseFrequency', `${(0.012 + 0.004 * Math.sin(t * 1.3)).toFixed(4)} ${(0.06 + 0.02 * Math.cos(t)).toFixed(4)}`);
|
|
55
|
+
h = raf(tick);
|
|
56
|
+
};
|
|
57
|
+
h = raf(tick);
|
|
58
|
+
return () => {
|
|
59
|
+
caf(h);
|
|
60
|
+
el.style.filter = prev;
|
|
61
|
+
svg.remove();
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'neon-write',
|
|
67
|
+
kind: 'text',
|
|
68
|
+
description: 'Letters flicker on one by one like a neon sign being switched on, then keep a soft glow (`color`, `stagger`).',
|
|
69
|
+
defaults: { color: '#ff4fd8', stagger: 70, duration: 520 },
|
|
70
|
+
run: (el, o, ctx) => {
|
|
71
|
+
var _a;
|
|
72
|
+
const glow = `0 0 4px #fff,0 0 10px ${o.color},0 0 22px ${o.color},0 0 42px ${o.color}`;
|
|
73
|
+
el.style.textShadow = glow;
|
|
74
|
+
(_a = el.style).color || (_a.color = '#fff');
|
|
75
|
+
if (ctx.reduced)
|
|
76
|
+
return;
|
|
77
|
+
const cs = splitChars(el);
|
|
78
|
+
return shared.all(cs.map((c, i) => ctx.animate(c, [
|
|
79
|
+
{ opacity: 0.08, textShadow: 'none' },
|
|
80
|
+
{ opacity: 1, textShadow: glow, offset: 0.2 },
|
|
81
|
+
{ opacity: 0.2, textShadow: 'none', offset: 0.32 },
|
|
82
|
+
{ opacity: 1, textShadow: glow, offset: 0.46 },
|
|
83
|
+
{ opacity: 0.55, offset: 0.6 },
|
|
84
|
+
{ opacity: 1, textShadow: glow },
|
|
85
|
+
], { duration: o.duration, delay: i * o.stagger + shared.rand(0, 60), easing: 'steps(6, end)', fill: 'backwards' })));
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'particle-text',
|
|
90
|
+
kind: 'text',
|
|
91
|
+
description: 'Particles fly in from around the element and assemble into the glyphs, then hand over to the real text (`gap` px between samples, `duration`, `colors`).',
|
|
92
|
+
defaults: { gap: 3, duration: 1300, colors: ['#7c5cff', '#22d3ee', '#ff5c8a'], spread: 120 },
|
|
93
|
+
reduced: 'skip',
|
|
94
|
+
run: (el, o) => {
|
|
95
|
+
const cs = splitChars(el);
|
|
96
|
+
const r = el.getBoundingClientRect();
|
|
97
|
+
if (!r.width || !r.height)
|
|
98
|
+
return;
|
|
99
|
+
const pad = Number(o.spread) || 120;
|
|
100
|
+
const W = Math.ceil(r.width + pad * 2);
|
|
101
|
+
const H = Math.ceil(r.height + pad * 2);
|
|
102
|
+
const canvas = document.createElement('canvas');
|
|
103
|
+
canvas.setAttribute('aria-hidden', 'true');
|
|
104
|
+
canvas.width = W;
|
|
105
|
+
canvas.height = H;
|
|
106
|
+
canvas.style.cssText = `position:absolute;left:${r.left - pad}px;top:${r.top - pad}px;width:${W}px;height:${H}px`;
|
|
107
|
+
const g = canvas.getContext('2d');
|
|
108
|
+
if (!g)
|
|
109
|
+
return;
|
|
110
|
+
// rasterise each character where the browser laid it out
|
|
111
|
+
const cs0 = getComputedStyle(el);
|
|
112
|
+
g.font = `${cs0.fontStyle} ${cs0.fontWeight} ${cs0.fontSize} ${cs0.fontFamily}`;
|
|
113
|
+
g.textBaseline = 'middle';
|
|
114
|
+
g.fillStyle = '#000';
|
|
115
|
+
for (const c of cs) {
|
|
116
|
+
const b = c.getBoundingClientRect();
|
|
117
|
+
g.fillText(c.textContent || '', b.left - r.left + pad, b.top - r.top + pad + b.height / 2);
|
|
118
|
+
}
|
|
119
|
+
const img = g.getImageData(0, 0, W, H);
|
|
120
|
+
const gap = Math.max(2, Math.round(Number(o.gap) || 3));
|
|
121
|
+
const pts = [];
|
|
122
|
+
for (let y = 0; y < H; y += gap)
|
|
123
|
+
for (let x = 0; x < W; x += gap)
|
|
124
|
+
if (img.data[(y * W + x) * 4 + 3] > 128) {
|
|
125
|
+
const a = shared.rand(0, Math.PI * 2);
|
|
126
|
+
const rr = shared.rand(pad * 0.6, pad * 1.4);
|
|
127
|
+
pts.push({ x, y, sx: W / 2 + Math.cos(a) * (W / 2 + rr * 0.3), sy: H / 2 + Math.sin(a) * (H / 2 + rr * 0.3), c: o.colors[pts.length % o.colors.length], d: shared.rand(0, 0.35) });
|
|
128
|
+
}
|
|
129
|
+
shared.fxLayer().appendChild(canvas);
|
|
130
|
+
cs.forEach((c) => (c.style.opacity = '0'));
|
|
131
|
+
const t0 = performance.now();
|
|
132
|
+
const dur = Number(o.duration) || 1300;
|
|
133
|
+
return new Promise((done) => {
|
|
134
|
+
const finish = () => {
|
|
135
|
+
canvas.remove();
|
|
136
|
+
cs.forEach((c) => (c.style.opacity = ''));
|
|
137
|
+
done();
|
|
138
|
+
};
|
|
139
|
+
const tick = (now) => {
|
|
140
|
+
const k = (now - t0) / dur;
|
|
141
|
+
g.clearRect(0, 0, W, H);
|
|
142
|
+
for (const p of pts) {
|
|
143
|
+
const e = Math.min(1, Math.max(0, (k - p.d) / (1 - p.d)));
|
|
144
|
+
const q = 1 - Math.pow(1 - e, 3);
|
|
145
|
+
g.globalAlpha = k > 1 ? Math.max(0, 1 - (k - 1) * 4) : 0.25 + 0.75 * q;
|
|
146
|
+
g.fillStyle = p.c;
|
|
147
|
+
g.fillRect(p.sx + (p.x - p.sx) * q, p.sy + (p.y - p.sy) * q, gap - 0.5, gap - 0.5);
|
|
148
|
+
}
|
|
149
|
+
if (k > 1)
|
|
150
|
+
cs.forEach((c) => (c.style.opacity = String(Math.min(1, (k - 1) * 4))));
|
|
151
|
+
if (k < 1.25)
|
|
152
|
+
raf(tick);
|
|
153
|
+
else
|
|
154
|
+
finish();
|
|
155
|
+
};
|
|
156
|
+
if (!raf(tick))
|
|
157
|
+
finish();
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: 'glitch-text',
|
|
163
|
+
kind: 'text',
|
|
164
|
+
description: 'RGB-split slices of the text jump sideways for a moment (`duration`, `colors` of the two channels).',
|
|
165
|
+
defaults: { duration: 650, colors: ['#22d3ee', '#ff3d81'] },
|
|
166
|
+
run: (el, o, ctx) => {
|
|
167
|
+
if (ctx.reduced)
|
|
168
|
+
return ctx.animate(el, [{ opacity: 1 }, { opacity: 0.6 }, { opacity: 1 }], { duration: 200 });
|
|
169
|
+
if (getComputedStyle(el).position === 'static')
|
|
170
|
+
el.style.position = 'relative';
|
|
171
|
+
const text = el.textContent || '';
|
|
172
|
+
const steps = 8;
|
|
173
|
+
const mk = (color, dir) => {
|
|
174
|
+
const s = document.createElement('span');
|
|
175
|
+
s.setAttribute('aria-hidden', 'true');
|
|
176
|
+
s.textContent = text;
|
|
177
|
+
s.style.cssText = `position:absolute;inset:0;color:${color};mix-blend-mode:screen;pointer-events:none;white-space:inherit`;
|
|
178
|
+
el.appendChild(s);
|
|
179
|
+
const frames = [];
|
|
180
|
+
for (let i = 0; i <= steps; i++) {
|
|
181
|
+
const top = Math.round(shared.rand(0, 80));
|
|
182
|
+
frames.push({ clipPath: `inset(${top}% 0 ${Math.max(0, 100 - top - shared.rand(8, 30)).toFixed(0)}% 0)`, transform: `translateX(${(dir * shared.rand(2, 9)).toFixed(1)}px)` });
|
|
183
|
+
}
|
|
184
|
+
frames.push({ clipPath: 'inset(50% 0 50% 0)', transform: 'none' });
|
|
185
|
+
const a = ctx.animate(s, frames, { duration: o.duration, easing: `steps(${steps}, end)` });
|
|
186
|
+
const rm = () => s.remove();
|
|
187
|
+
if (a)
|
|
188
|
+
a.finished.then(rm, rm);
|
|
189
|
+
else
|
|
190
|
+
rm();
|
|
191
|
+
return a;
|
|
192
|
+
};
|
|
193
|
+
return shared.all([
|
|
194
|
+
mk(o.colors[0], -1),
|
|
195
|
+
mk(o.colors[1], 1),
|
|
196
|
+
ctx.animate(el, [{ transform: 'none' }, { transform: 'translate(-2px,1px) skewX(-4deg)' }, { transform: 'translate(2px,-1px)' }, { transform: 'skewX(3deg)' }, { transform: 'none' }], { duration: o.duration, easing: 'steps(5, end)' }),
|
|
197
|
+
]);
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
name: 'text-trail',
|
|
202
|
+
kind: 'cursor',
|
|
203
|
+
description: 'The letters of a word fall off the pointer as it moves over the element (persistent; `text`, `color`, `spacing` px).',
|
|
204
|
+
defaults: { text: 'MOTIONARY', color: '#7c5cff', spacing: 22, size: 18 },
|
|
205
|
+
run: (el, o, ctx) => {
|
|
206
|
+
const word = Array.from(String(o.text || '✦'));
|
|
207
|
+
let i = 0;
|
|
208
|
+
let lx = -1e4;
|
|
209
|
+
let ly = -1e4;
|
|
210
|
+
const move = (e) => {
|
|
211
|
+
if (Math.hypot(e.clientX - lx, e.clientY - ly) < o.spacing)
|
|
212
|
+
return;
|
|
213
|
+
lx = e.clientX;
|
|
214
|
+
ly = e.clientY;
|
|
215
|
+
const ch = word[i++ % word.length];
|
|
216
|
+
shared.spawn(e.clientX - o.size / 2, e.clientY - o.size / 2, `font:800 ${o.size}px/1 system-ui,sans-serif;color:${o.color};text-shadow:0 2px 8px rgba(0,0,0,.25)`, ctx, [
|
|
217
|
+
{ transform: 'translateY(0) rotate(0) scale(1)', opacity: 1 },
|
|
218
|
+
{ transform: `translateY(${shared.rand(30, 60).toFixed(0)}px) rotate(${shared.rand(-60, 60).toFixed(0)}deg) scale(.6)`, opacity: 0 },
|
|
219
|
+
], { duration: shared.rand(700, 1000), easing: 'cubic-bezier(.3,.1,.7,1)' }, ch);
|
|
220
|
+
};
|
|
221
|
+
el.addEventListener('pointermove', move);
|
|
222
|
+
return () => el.removeEventListener('pointermove', move);
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
name: 'font-breathe',
|
|
227
|
+
kind: 'loop',
|
|
228
|
+
description: 'A variable-font weight wave breathes through the text (`min` / `max` weight, `period` ms, `stagger`). Best with a variable font.',
|
|
229
|
+
defaults: { min: 200, max: 900, period: 2400, stagger: 90 },
|
|
230
|
+
run: (el, o, ctx) => {
|
|
231
|
+
const cs = splitChars(el);
|
|
232
|
+
const anims = cs.map((c, i) => ctx.animate(c, [
|
|
233
|
+
{ fontWeight: o.min, fontVariationSettings: `'wght' ${o.min}` },
|
|
234
|
+
{ fontWeight: o.max, fontVariationSettings: `'wght' ${o.max}` },
|
|
235
|
+
], { duration: o.period / 2, delay: i * o.stagger, iterations: Infinity, direction: 'alternate', easing: 'ease-in-out' }));
|
|
236
|
+
return () => anims.forEach((a) => a?.cancel());
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
name: 'flip-chars',
|
|
241
|
+
kind: 'text',
|
|
242
|
+
description: 'Every character flips up in 3D around its baseline, staggered (`stagger`, `duration`, `axis` x | y).',
|
|
243
|
+
defaults: { stagger: 45, duration: 700, axis: 'x' },
|
|
244
|
+
run: (el, o, ctx) => {
|
|
245
|
+
var _a;
|
|
246
|
+
const cs = splitChars(el);
|
|
247
|
+
(_a = el.style).perspective || (_a.perspective = '600px');
|
|
248
|
+
const rot = o.axis === 'y' ? 'rotateY' : 'rotateX';
|
|
249
|
+
return shared.all(cs.map((c, i) => {
|
|
250
|
+
c.style.transformOrigin = '50% 70% -0.4em';
|
|
251
|
+
c.style.backfaceVisibility = 'hidden';
|
|
252
|
+
return ctx.reduced
|
|
253
|
+
? ctx.animate(c, [{ opacity: 0 }, { opacity: 1 }], { duration: 200, delay: i * 10, fill: 'backwards' })
|
|
254
|
+
: ctx.animate(c, [{ transform: `${rot}(-100deg)`, opacity: 0 }, { transform: `${rot}(12deg)`, opacity: 1, offset: 0.7 }, { transform: `${rot}(0)`, opacity: 1 }], { duration: o.duration, delay: i * o.stagger, easing: 'cubic-bezier(.2,.8,.3,1)', fill: 'backwards' });
|
|
255
|
+
}));
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
];
|
|
259
|
+
/** Register the 6.3 text pack (idempotent). */
|
|
260
|
+
function registerTextEffects3() {
|
|
261
|
+
registry.registerEffects(TEXT3_FX);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
exports.TEXT3_FX = TEXT3_FX;
|
|
265
|
+
exports.registerTextEffects3 = registerTextEffects3;
|
|
266
|
+
exports.splitChars = splitChars;
|
|
267
|
+
//# sourceMappingURL=fx-text.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fx-text.cjs","sources":["../../src/components/fx2/text3.ts"],"sourcesContent":["/**\n * 6.3 — Text effects 3.0 (`motionary/components/fx-text`), registered through\n * `registerEffect()`:\n *\n * - `liquid-text` (loop) — the text ripples like liquid (animated SVG\n * turbulence + displacement filter).\n * - `neon-write` (text) — letters flicker on one by one like a neon sign\n * being switched on, then keep a soft glow.\n * - `particle-text` (text) — particles fly in from around the element and\n * assemble into the glyphs, then hand over to the real text.\n * - `glitch-text` (text) — RGB-split slices jump sideways for a moment.\n * - `text-trail` (cursor) — the letters of a word fall off the pointer.\n * - `font-breathe` (loop) — a variable-font weight wave breathes through the text.\n * - `flip-chars` (text) — every character flips up in 3D, staggered.\n *\n * Splitting keeps a visually hidden copy for screen readers (the animated\n * characters are `aria-hidden`). Reduced motion: loops and the trail are\n * skipped, one-shot effects show the final state without movement.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\nimport { srText } from '../base';\nimport { fxLayer, spawn, rand, all } from '../effects/shared';\n\n/** Split `el`'s text into `aria-hidden` inline-block characters (idempotent). Returns them. */\nexport function splitChars(el: HTMLElement): HTMLElement[] {\n if (el.dataset.usaChars) return Array.from(el.querySelectorAll<HTMLElement>(':scope > .usa-ch'));\n const text = el.textContent || '';\n el.textContent = '';\n for (const ch of Array.from(text)) {\n const s = document.createElement('span');\n s.className = 'usa-ch';\n s.setAttribute('aria-hidden', 'true');\n s.style.cssText = 'display:inline-block;white-space:pre';\n s.textContent = ch;\n el.appendChild(s);\n }\n el.appendChild(srText(text.trim()));\n el.dataset.usaChars = '1';\n return Array.from(el.querySelectorAll<HTMLElement>(':scope > .usa-ch'));\n}\n\nconst raf = (fn: FrameRequestCallback): number => (typeof requestAnimationFrame === 'function' ? requestAnimationFrame(fn) : 0);\nconst caf = (h: number): void => {\n if (h && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(h);\n};\nlet fid = 0;\n\nexport const TEXT3_FX: EffectDefinition[] = [\n {\n name: 'liquid-text',\n kind: 'loop',\n description: 'The text ripples like liquid: an animated SVG turbulence + displacement filter (`strength`, `speed`).',\n defaults: { strength: 7, speed: 1 },\n run: (el: HTMLElement, o: any) => {\n const id = `usa-liquid-${++fid}`;\n const ns = 'http://www.w3.org/2000/svg';\n const svg = document.createElementNS(ns, 'svg');\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('width', '0');\n svg.setAttribute('height', '0');\n svg.style.cssText = 'position:absolute;width:0;height:0;overflow:hidden';\n svg.innerHTML = `<filter id=\"${id}\" x=\"-10%\" y=\"-20%\" width=\"120%\" height=\"140%\"><feTurbulence type=\"fractalNoise\" baseFrequency=\"0.012 0.06\" numOctaves=\"2\" seed=\"3\" result=\"n\"/><feDisplacementMap in=\"SourceGraphic\" in2=\"n\" scale=\"${Number(o.strength) || 7}\" xChannelSelector=\"R\" yChannelSelector=\"G\"/></filter>`;\n document.body.appendChild(svg);\n const turb = svg.querySelector('feTurbulence');\n const prev = el.style.filter;\n el.style.filter = `url(#${id})`;\n let h = 0;\n const t0 = performance.now();\n const tick = (now: number) => {\n const t = ((now - t0) / 1000) * (Number(o.speed) || 1);\n turb?.setAttribute('baseFrequency', `${(0.012 + 0.004 * Math.sin(t * 1.3)).toFixed(4)} ${(0.06 + 0.02 * Math.cos(t)).toFixed(4)}`);\n h = raf(tick);\n };\n h = raf(tick);\n return () => {\n caf(h);\n el.style.filter = prev;\n svg.remove();\n };\n },\n },\n {\n name: 'neon-write',\n kind: 'text',\n description: 'Letters flicker on one by one like a neon sign being switched on, then keep a soft glow (`color`, `stagger`).',\n defaults: { color: '#ff4fd8', stagger: 70, duration: 520 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const glow = `0 0 4px #fff,0 0 10px ${o.color},0 0 22px ${o.color},0 0 42px ${o.color}`;\n el.style.textShadow = glow;\n el.style.color ||= '#fff';\n if (ctx.reduced) return;\n const cs = splitChars(el);\n return all(cs.map((c, i) => ctx.animate(c, [\n { opacity: 0.08, textShadow: 'none' },\n { opacity: 1, textShadow: glow, offset: 0.2 },\n { opacity: 0.2, textShadow: 'none', offset: 0.32 },\n { opacity: 1, textShadow: glow, offset: 0.46 },\n { opacity: 0.55, offset: 0.6 },\n { opacity: 1, textShadow: glow },\n ], { duration: o.duration, delay: i * o.stagger + rand(0, 60), easing: 'steps(6, end)', fill: 'backwards' })));\n },\n },\n {\n name: 'particle-text',\n kind: 'text',\n description: 'Particles fly in from around the element and assemble into the glyphs, then hand over to the real text (`gap` px between samples, `duration`, `colors`).',\n defaults: { gap: 3, duration: 1300, colors: ['#7c5cff', '#22d3ee', '#ff5c8a'], spread: 120 },\n reduced: 'skip',\n run: (el: HTMLElement, o: any) => {\n const cs = splitChars(el);\n const r = el.getBoundingClientRect();\n if (!r.width || !r.height) return;\n const pad = Number(o.spread) || 120;\n const W = Math.ceil(r.width + pad * 2);\n const H = Math.ceil(r.height + pad * 2);\n const canvas = document.createElement('canvas');\n canvas.setAttribute('aria-hidden', 'true');\n canvas.width = W;\n canvas.height = H;\n canvas.style.cssText = `position:absolute;left:${r.left - pad}px;top:${r.top - pad}px;width:${W}px;height:${H}px`;\n const g = canvas.getContext('2d');\n if (!g) return;\n // rasterise each character where the browser laid it out\n const cs0 = getComputedStyle(el);\n g.font = `${cs0.fontStyle} ${cs0.fontWeight} ${cs0.fontSize} ${cs0.fontFamily}`;\n g.textBaseline = 'middle';\n g.fillStyle = '#000';\n for (const c of cs) {\n const b = c.getBoundingClientRect();\n g.fillText(c.textContent || '', b.left - r.left + pad, b.top - r.top + pad + b.height / 2);\n }\n const img = g.getImageData(0, 0, W, H);\n const gap = Math.max(2, Math.round(Number(o.gap) || 3));\n const pts: { x: number; y: number; sx: number; sy: number; c: string; d: number }[] = [];\n for (let y = 0; y < H; y += gap) for (let x = 0; x < W; x += gap) if (img.data[(y * W + x) * 4 + 3] > 128) {\n const a = rand(0, Math.PI * 2);\n const rr = rand(pad * 0.6, pad * 1.4);\n pts.push({ x, y, sx: W / 2 + Math.cos(a) * (W / 2 + rr * 0.3), sy: H / 2 + Math.sin(a) * (H / 2 + rr * 0.3), c: o.colors[pts.length % o.colors.length], d: rand(0, 0.35) });\n }\n fxLayer().appendChild(canvas);\n cs.forEach((c) => (c.style.opacity = '0'));\n const t0 = performance.now();\n const dur = Number(o.duration) || 1300;\n return new Promise<void>((done) => {\n const finish = () => {\n canvas.remove();\n cs.forEach((c) => (c.style.opacity = ''));\n done();\n };\n const tick = (now: number) => {\n const k = (now - t0) / dur;\n g.clearRect(0, 0, W, H);\n for (const p of pts) {\n const e = Math.min(1, Math.max(0, (k - p.d) / (1 - p.d)));\n const q = 1 - Math.pow(1 - e, 3);\n g.globalAlpha = k > 1 ? Math.max(0, 1 - (k - 1) * 4) : 0.25 + 0.75 * q;\n g.fillStyle = p.c;\n g.fillRect(p.sx + (p.x - p.sx) * q, p.sy + (p.y - p.sy) * q, gap - 0.5, gap - 0.5);\n }\n if (k > 1) cs.forEach((c) => (c.style.opacity = String(Math.min(1, (k - 1) * 4))));\n if (k < 1.25) raf(tick);\n else finish();\n };\n if (!raf(tick)) finish();\n });\n },\n },\n {\n name: 'glitch-text',\n kind: 'text',\n description: 'RGB-split slices of the text jump sideways for a moment (`duration`, `colors` of the two channels).',\n defaults: { duration: 650, colors: ['#22d3ee', '#ff3d81'] },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return ctx.animate(el, [{ opacity: 1 }, { opacity: 0.6 }, { opacity: 1 }], { duration: 200 });\n if (getComputedStyle(el).position === 'static') el.style.position = 'relative';\n const text = el.textContent || '';\n const steps = 8;\n const mk = (color: string, dir: number) => {\n const s = document.createElement('span');\n s.setAttribute('aria-hidden', 'true');\n s.textContent = text;\n s.style.cssText = `position:absolute;inset:0;color:${color};mix-blend-mode:screen;pointer-events:none;white-space:inherit`;\n el.appendChild(s);\n const frames: Keyframe[] = [];\n for (let i = 0; i <= steps; i++) {\n const top = Math.round(rand(0, 80));\n frames.push({ clipPath: `inset(${top}% 0 ${Math.max(0, 100 - top - rand(8, 30)).toFixed(0)}% 0)`, transform: `translateX(${(dir * rand(2, 9)).toFixed(1)}px)` });\n }\n frames.push({ clipPath: 'inset(50% 0 50% 0)', transform: 'none' });\n const a = ctx.animate(s, frames, { duration: o.duration, easing: `steps(${steps}, end)` });\n const rm = () => s.remove();\n if (a) a.finished.then(rm, rm);\n else rm();\n return a;\n };\n return all([\n mk(o.colors[0], -1),\n mk(o.colors[1], 1),\n ctx.animate(el, [{ transform: 'none' }, { transform: 'translate(-2px,1px) skewX(-4deg)' }, { transform: 'translate(2px,-1px)' }, { transform: 'skewX(3deg)' }, { transform: 'none' }], { duration: o.duration, easing: 'steps(5, end)' }),\n ]);\n },\n },\n {\n name: 'text-trail',\n kind: 'cursor',\n description: 'The letters of a word fall off the pointer as it moves over the element (persistent; `text`, `color`, `spacing` px).',\n defaults: { text: 'MOTIONARY', color: '#7c5cff', spacing: 22, size: 18 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const word = Array.from(String(o.text || '✦'));\n let i = 0;\n let lx = -1e4;\n let ly = -1e4;\n const move = (e: PointerEvent) => {\n if (Math.hypot(e.clientX - lx, e.clientY - ly) < o.spacing) return;\n lx = e.clientX;\n ly = e.clientY;\n const ch = word[i++ % word.length];\n spawn(e.clientX - o.size / 2, e.clientY - o.size / 2, `font:800 ${o.size}px/1 system-ui,sans-serif;color:${o.color};text-shadow:0 2px 8px rgba(0,0,0,.25)`, ctx, [\n { transform: 'translateY(0) rotate(0) scale(1)', opacity: 1 },\n { transform: `translateY(${rand(30, 60).toFixed(0)}px) rotate(${rand(-60, 60).toFixed(0)}deg) scale(.6)`, opacity: 0 },\n ], { duration: rand(700, 1000), easing: 'cubic-bezier(.3,.1,.7,1)' }, ch);\n };\n el.addEventListener('pointermove', move);\n return () => el.removeEventListener('pointermove', move);\n },\n },\n {\n name: 'font-breathe',\n kind: 'loop',\n description: 'A variable-font weight wave breathes through the text (`min` / `max` weight, `period` ms, `stagger`). Best with a variable font.',\n defaults: { min: 200, max: 900, period: 2400, stagger: 90 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const cs = splitChars(el);\n const anims = cs.map((c, i) => ctx.animate(c, [\n { fontWeight: o.min, fontVariationSettings: `'wght' ${o.min}` },\n { fontWeight: o.max, fontVariationSettings: `'wght' ${o.max}` },\n ], { duration: o.period / 2, delay: i * o.stagger, iterations: Infinity, direction: 'alternate', easing: 'ease-in-out' }));\n return () => anims.forEach((a) => a?.cancel());\n },\n },\n {\n name: 'flip-chars',\n kind: 'text',\n description: 'Every character flips up in 3D around its baseline, staggered (`stagger`, `duration`, `axis` x | y).',\n defaults: { stagger: 45, duration: 700, axis: 'x' },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const cs = splitChars(el);\n el.style.perspective ||= '600px';\n const rot = o.axis === 'y' ? 'rotateY' : 'rotateX';\n return all(cs.map((c, i) => {\n c.style.transformOrigin = '50% 70% -0.4em';\n c.style.backfaceVisibility = 'hidden';\n return ctx.reduced\n ? ctx.animate(c, [{ opacity: 0 }, { opacity: 1 }], { duration: 200, delay: i * 10, fill: 'backwards' })\n : ctx.animate(c, [{ transform: `${rot}(-100deg)`, opacity: 0 }, { transform: `${rot}(12deg)`, opacity: 1, offset: 0.7 }, { transform: `${rot}(0)`, opacity: 1 }], { duration: o.duration, delay: i * o.stagger, easing: 'cubic-bezier(.2,.8,.3,1)', fill: 'backwards' });\n }));\n },\n },\n];\n\n/** Register the 6.3 text pack (idempotent). */\nexport function registerTextEffects3(): void {\n registerEffects(TEXT3_FX);\n}\n\n"],"names":["srText","all","rand","fxLayer","spawn","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
|
+
* 6.3 — Text effects 3.0 (`motionary/components/fx-text`), registered through
|
|
46
|
+
* `registerEffect()`:
|
|
47
|
+
*
|
|
48
|
+
* - `liquid-text` (loop) — the text ripples like liquid (animated SVG
|
|
49
|
+
* turbulence + displacement filter).
|
|
50
|
+
* - `neon-write` (text) — letters flicker on one by one like a neon sign
|
|
51
|
+
* being switched on, then keep a soft glow.
|
|
52
|
+
* - `particle-text` (text) — particles fly in from around the element and
|
|
53
|
+
* assemble into the glyphs, then hand over to the real text.
|
|
54
|
+
* - `glitch-text` (text) — RGB-split slices jump sideways for a moment.
|
|
55
|
+
* - `text-trail` (cursor) — the letters of a word fall off the pointer.
|
|
56
|
+
* - `font-breathe` (loop) — a variable-font weight wave breathes through the text.
|
|
57
|
+
* - `flip-chars` (text) — every character flips up in 3D, staggered.
|
|
58
|
+
*
|
|
59
|
+
* Splitting keeps a visually hidden copy for screen readers (the animated
|
|
60
|
+
* characters are `aria-hidden`). Reduced motion: loops and the trail are
|
|
61
|
+
* skipped, one-shot effects show the final state without movement.
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
/** Split `el`'s text into `aria-hidden` inline-block characters (idempotent). Returns them. */
|
|
65
|
+
declare function splitChars(el: HTMLElement): HTMLElement[];
|
|
66
|
+
declare const TEXT3_FX: EffectDefinition[];
|
|
67
|
+
/** Register the 6.3 text pack (idempotent). */
|
|
68
|
+
declare function registerTextEffects3(): void;
|
|
69
|
+
|
|
70
|
+
export { TEXT3_FX, registerTextEffects3, splitChars };
|
|
@@ -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
|
+
* 6.3 — Text effects 3.0 (`motionary/components/fx-text`), registered through
|
|
46
|
+
* `registerEffect()`:
|
|
47
|
+
*
|
|
48
|
+
* - `liquid-text` (loop) — the text ripples like liquid (animated SVG
|
|
49
|
+
* turbulence + displacement filter).
|
|
50
|
+
* - `neon-write` (text) — letters flicker on one by one like a neon sign
|
|
51
|
+
* being switched on, then keep a soft glow.
|
|
52
|
+
* - `particle-text` (text) — particles fly in from around the element and
|
|
53
|
+
* assemble into the glyphs, then hand over to the real text.
|
|
54
|
+
* - `glitch-text` (text) — RGB-split slices jump sideways for a moment.
|
|
55
|
+
* - `text-trail` (cursor) — the letters of a word fall off the pointer.
|
|
56
|
+
* - `font-breathe` (loop) — a variable-font weight wave breathes through the text.
|
|
57
|
+
* - `flip-chars` (text) — every character flips up in 3D, staggered.
|
|
58
|
+
*
|
|
59
|
+
* Splitting keeps a visually hidden copy for screen readers (the animated
|
|
60
|
+
* characters are `aria-hidden`). Reduced motion: loops and the trail are
|
|
61
|
+
* skipped, one-shot effects show the final state without movement.
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
/** Split `el`'s text into `aria-hidden` inline-block characters (idempotent). Returns them. */
|
|
65
|
+
declare function splitChars(el: HTMLElement): HTMLElement[];
|
|
66
|
+
declare const TEXT3_FX: EffectDefinition[];
|
|
67
|
+
/** Register the 6.3 text pack (idempotent). */
|
|
68
|
+
declare function registerTextEffects3(): void;
|
|
69
|
+
|
|
70
|
+
export { TEXT3_FX, registerTextEffects3, splitChars };
|