motionary 7.0.0 → 7.1.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.
Files changed (88) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/chunks/audio-DcPvT2Kh.js +333 -0
  3. package/dist/chunks/audio-DcPvT2Kh.js.map +1 -0
  4. package/dist/chunks/audio-EXUoijsG.cjs +342 -0
  5. package/dist/chunks/audio-EXUoijsG.cjs.map +1 -0
  6. package/dist/chunks/{base-DchG4q_S.js → base-2-yYc93C.js} +2 -2
  7. package/dist/chunks/{base-DchG4q_S.js.map → base-2-yYc93C.js.map} +1 -1
  8. package/dist/chunks/{core-DVyTlo9Q.js → core-D5rU0CV6.js} +2 -2
  9. package/dist/chunks/{core-DVyTlo9Q.js.map → core-D5rU0CV6.js.map} +1 -1
  10. package/dist/chunks/{core-D2vF8kZb.js → core-DuO-AVXL.js} +2 -2
  11. package/dist/chunks/{core-D2vF8kZb.js.map → core-DuO-AVXL.js.map} +1 -1
  12. package/dist/chunks/{fx-DUMVKSvg.js → fx-CMxWNwH8.js} +2 -2
  13. package/dist/chunks/{fx-DUMVKSvg.js.map → fx-CMxWNwH8.js.map} +1 -1
  14. package/dist/chunks/{gpu-Bkw605Ds.js → gpu-DLPghVWr.js} +2 -2
  15. package/dist/chunks/{gpu-Bkw605Ds.js.map → gpu-DLPghVWr.js.map} +1 -1
  16. package/dist/chunks/{player-C-TwEEy6.js → player-DxvCYo7Q.js} +4 -4
  17. package/dist/chunks/{player-C-TwEEy6.js.map → player-DxvCYo7Q.js.map} +1 -1
  18. package/dist/chunks/{registry-D23neB4M.js → registry-CyKExAmE.js} +2 -2
  19. package/dist/chunks/{registry-D23neB4M.js.map → registry-CyKExAmE.js.map} +1 -1
  20. package/dist/chunks/{spring-BhoT09Qb.js → spring-BK8DiezC.js} +2 -2
  21. package/dist/chunks/{spring-BhoT09Qb.js.map → spring-BK8DiezC.js.map} +1 -1
  22. package/dist/chunks/{variants-C_hv_s23.js → variants-BQ6bhzn4.js} +2 -2
  23. package/dist/chunks/{variants-C_hv_s23.js.map → variants-BQ6bhzn4.js.map} +1 -1
  24. package/dist/components/a11y.js +2 -2
  25. package/dist/components/angular.js +7 -7
  26. package/dist/components/background.js +2 -2
  27. package/dist/components/bridge.js +1 -1
  28. package/dist/components/cards.js +2 -2
  29. package/dist/components/click.js +3 -3
  30. package/dist/components/depth.js +3 -3
  31. package/dist/components/effects.cjs +11 -336
  32. package/dist/components/effects.cjs.map +1 -1
  33. package/dist/components/effects.js +9 -333
  34. package/dist/components/effects.js.map +1 -1
  35. package/dist/components/feedback.js +1 -1
  36. package/dist/components/fx-3d.js +2 -2
  37. package/dist/components/fx-focus.js +2 -2
  38. package/dist/components/fx-gpu.js +3 -3
  39. package/dist/components/fx-light.js +2 -2
  40. package/dist/components/fx-morph.js +2 -2
  41. package/dist/components/fx-music.cjs +179 -0
  42. package/dist/components/fx-music.cjs.map +1 -0
  43. package/dist/components/fx-music.d.cts +102 -0
  44. package/dist/components/fx-music.d.ts +102 -0
  45. package/dist/components/fx-music.js +174 -0
  46. package/dist/components/fx-music.js.map +1 -0
  47. package/dist/components/fx-physics.js +2 -2
  48. package/dist/components/fx-text.js +2 -2
  49. package/dist/components/fx-transitions.js +3 -3
  50. package/dist/components/fx-weather.js +2 -2
  51. package/dist/components/fx.js +5 -5
  52. package/dist/components/fx2.cjs +8 -0
  53. package/dist/components/fx2.cjs.map +1 -1
  54. package/dist/components/fx2.d.cts +59 -1
  55. package/dist/components/fx2.d.ts +59 -1
  56. package/dist/components/fx2.js +10 -5
  57. package/dist/components/fx2.js.map +1 -1
  58. package/dist/components/gesture.js +4 -4
  59. package/dist/components/interaction.js +1 -1
  60. package/dist/components/layout.js +1 -1
  61. package/dist/components/marketplace.js +2 -2
  62. package/dist/components/packs.js +1 -1
  63. package/dist/components/page.js +3 -3
  64. package/dist/components/perf.js +2 -2
  65. package/dist/components/physics.js +3 -3
  66. package/dist/components/reveal.js +1 -1
  67. package/dist/components/solid.js +7 -7
  68. package/dist/components/svelte.js +7 -7
  69. package/dist/components/svg.js +1 -1
  70. package/dist/components/text.js +2 -2
  71. package/dist/components/timeline.js +3 -3
  72. package/dist/components/transitions.js +1 -1
  73. package/dist/components/ui.js +4 -4
  74. package/dist/components/vue.js +7 -7
  75. package/dist/components/webgl.js +1 -1
  76. package/dist/components/widgets.cjs +542 -61
  77. package/dist/components/widgets.cjs.map +1 -1
  78. package/dist/components/widgets.d.cts +79 -2
  79. package/dist/components/widgets.d.ts +79 -2
  80. package/dist/components/widgets.js +542 -67
  81. package/dist/components/widgets.js.map +1 -1
  82. package/dist/components.js +9 -9
  83. package/dist/index.js +2 -2
  84. package/dist/widgets.umd.js +1 -1
  85. package/dist/widgets.umd.js.map +1 -1
  86. package/docs/ROADMAP.md +1 -1
  87. package/docs/components.md +25 -0
  88. package/package.json +21 -1
@@ -1,4 +1,4 @@
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';
1
+ import { u as defineElement, A as kindOf, z as EASE_OUT, k as clamp, F as FLUENT_DECELERATE, E as EASE_SPRING } from '../chunks/base-2-yYc93C.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
 
@@ -1,7 +1,7 @@
1
- import { registerEffects } from '../chunks/registry-D23neB4M.js';
1
+ import { registerEffects } from '../chunks/registry-CyKExAmE.js';
2
2
  import { a as all } from '../chunks/shared-CkKHWrtJ.js';
3
3
  import { trackPointer } from './fx-light.js';
4
- import '../chunks/base-DchG4q_S.js';
4
+ import '../chunks/base-2-yYc93C.js';
5
5
  import '../chunks/generative-2LhxG5BJ.js';
6
6
 
7
7
  const layers = (el) => {
@@ -1,5 +1,5 @@
1
- import { registerEffects } from '../chunks/registry-D23neB4M.js';
2
- import '../chunks/base-DchG4q_S.js';
1
+ import { registerEffects } from '../chunks/registry-CyKExAmE.js';
2
+ import '../chunks/base-2-yYc93C.js';
3
3
 
4
4
  const NS = 'http://www.w3.org/2000/svg';
5
5
  function overlay(el, z = 1) {
@@ -1,6 +1,6 @@
1
- import '../chunks/registry-D23neB4M.js';
1
+ import '../chunks/registry-CyKExAmE.js';
2
2
  import '../chunks/generative-2LhxG5BJ.js';
3
3
  import '../chunks/shared-CkKHWrtJ.js';
4
- export { G as GPU_FX, r as registerGpuPack } from '../chunks/gpu-Bkw605Ds.js';
5
- import '../chunks/base-DchG4q_S.js';
4
+ export { G as GPU_FX, r as registerGpuPack } from '../chunks/gpu-DLPghVWr.js';
5
+ import '../chunks/base-2-yYc93C.js';
6
6
  //# sourceMappingURL=fx-gpu.js.map
@@ -1,7 +1,7 @@
1
- import { registerEffects } from '../chunks/registry-D23neB4M.js';
1
+ import { registerEffects } from '../chunks/registry-CyKExAmE.js';
2
2
  import { c as canvasBackground, h as hexRgb } from '../chunks/generative-2LhxG5BJ.js';
3
3
  import { o as overlay } from '../chunks/shared-CkKHWrtJ.js';
4
- import '../chunks/base-DchG4q_S.js';
4
+ import '../chunks/base-2-yYc93C.js';
5
5
 
6
6
  /** Track the pointer over `el` as 0–1 coordinates (`fn(x, y, inside)`); starts at (`x0`, `y0`). Returns a remover. */
7
7
  function trackPointer(el, ctx, fn, x0 = 0.3, y0 = 0.25) {
@@ -1,6 +1,6 @@
1
- import { registerEffects } from '../chunks/registry-D23neB4M.js';
1
+ import { registerEffects } from '../chunks/registry-CyKExAmE.js';
2
2
  import { a as all } from '../chunks/shared-CkKHWrtJ.js';
3
- import '../chunks/base-DchG4q_S.js';
3
+ import '../chunks/base-2-yYc93C.js';
4
4
 
5
5
  const NS = 'http://www.w3.org/2000/svg';
6
6
  const raf = (f) => (typeof requestAnimationFrame === 'function' ? requestAnimationFrame(f) : 0);
@@ -0,0 +1,179 @@
1
+ 'use strict';
2
+
3
+ var registry = require('../chunks/registry-DehBVRDV.cjs');
4
+ var generative = require('../chunks/generative-BHIj-NU0.cjs');
5
+ var audio = require('../chunks/audio-EXUoijsG.cjs');
6
+ require('../chunks/base-BaQV-2ha.cjs');
7
+ require('../chunks/shared-jkgRH-Hx.cjs');
8
+
9
+ /** A smooth, deterministic fake analyser frame at time `t` (s). */
10
+ function syntheticSample(t, bins = 64) {
11
+ const freq = new Uint8Array(bins);
12
+ const wave = new Uint8Array(128);
13
+ const beat = Math.pow(Math.max(0, Math.sin(t * Math.PI * 2 * 1.9)), 8);
14
+ for (let i = 0; i < bins; i++) {
15
+ const k = i / bins;
16
+ const v = (0.75 - k * 0.55) * (0.55 + 0.25 * Math.sin(t * 3.1 + i * 0.45) + 0.2 * Math.sin(t * 5.3 - i * 0.9)) + (k < 0.12 ? beat * 0.45 : 0);
17
+ freq[i] = Math.max(0, Math.min(255, Math.round(v * 255)));
18
+ }
19
+ for (let i = 0; i < 128; i++)
20
+ wave[i] = Math.round(128 + 70 * (0.6 * Math.sin(i * 0.19 + t * 9) + 0.3 * Math.sin(i * 0.53 - t * 13) + 0.25 * beat * Math.sin(i * 0.05)));
21
+ const bass = Array.from(freq.slice(0, Math.max(1, Math.round(bins * 0.08)))).reduce((a, b) => a + b, 0) / (Math.max(1, Math.round(bins * 0.08)) * 255);
22
+ return { level: 0.35 + beat * 0.3, bass, freq, wave };
23
+ }
24
+ /** The live analyser frame, or the synthetic one. */
25
+ const musicSample = (t) => audio.getAudio()?.sample() ?? syntheticSample(t);
26
+ const bg = (name, description, defaults, spec) => ({
27
+ name,
28
+ kind: 'background',
29
+ description,
30
+ reduced: 'run',
31
+ defaults: { speed: 1, quality: 1, colors: ['#22d3ee', '#7c5cff', '#f472b6'], ...defaults },
32
+ run: (el, o, ctx) => {
33
+ const stop = generative.canvasBackground(el, ctx, spec, o);
34
+ ctx.onCleanup(stop);
35
+ return stop;
36
+ },
37
+ });
38
+ const grad = (ctx, x0, y0, x1, y1, colors) => {
39
+ const g = ctx.createLinearGradient(x0, y0, x1, y1);
40
+ colors.forEach((c, i) => g.addColorStop(i / Math.max(1, colors.length - 1), c));
41
+ return g;
42
+ };
43
+ /** A loop effect driven by the music sample each frame. */
44
+ const loop = (name, description, defaults, apply) => ({
45
+ name,
46
+ kind: 'loop',
47
+ description,
48
+ defaults,
49
+ reduced: 'skip',
50
+ run: (el, o, ctx) => {
51
+ const prev = el.style.transform;
52
+ const st = {};
53
+ let raf = 0;
54
+ const t0 = performance.now();
55
+ const f = (now) => {
56
+ const t = (now - t0) / 1000;
57
+ apply(el, musicSample(t), t, o, st);
58
+ raf = requestAnimationFrame(f);
59
+ };
60
+ if (typeof requestAnimationFrame === 'function')
61
+ raf = requestAnimationFrame(f);
62
+ const stop = () => {
63
+ cancelAnimationFrame(raf);
64
+ el.style.transform = prev;
65
+ };
66
+ ctx.onCleanup(stop);
67
+ return stop;
68
+ },
69
+ });
70
+ const MUSIC_FX = [
71
+ bg('waveform-scope', 'An oscilloscope line of the waveform with a soft glow (Canvas 2D; live analyser or synthetic).', { width: 2.5 }, {
72
+ draw: ({ ctx, w, h, t, o }) => {
73
+ const s = musicSample(t);
74
+ ctx.clearRect(0, 0, w, h);
75
+ ctx.lineWidth = o.width;
76
+ ctx.strokeStyle = grad(ctx, 0, 0, w, 0, o.colors);
77
+ ctx.shadowColor = o.colors[0];
78
+ ctx.shadowBlur = 10;
79
+ ctx.beginPath();
80
+ const n = s.wave.length;
81
+ for (let i = 0; i < n; i++) {
82
+ const x = (i / (n - 1)) * w;
83
+ const y = h / 2 + ((s.wave[i] - 128) / 128) * h * 0.4;
84
+ if (i)
85
+ ctx.lineTo(x, y);
86
+ else
87
+ ctx.moveTo(x, y);
88
+ }
89
+ ctx.stroke();
90
+ ctx.shadowBlur = 0;
91
+ },
92
+ }),
93
+ bg('radial-spectrum', 'Spectrum bars around a circle that breathes with the bass (Canvas 2D).', { bars: 48 }, {
94
+ draw: ({ ctx, w, h, t, o }) => {
95
+ const s = musicSample(t);
96
+ ctx.clearRect(0, 0, w, h);
97
+ const cx = w / 2;
98
+ const cy = h / 2;
99
+ const r0 = Math.min(w, h) * (0.18 + s.bass * 0.06);
100
+ const n = o.bars;
101
+ ctx.lineCap = 'round';
102
+ ctx.lineWidth = Math.max(2, (Math.PI * 2 * r0) / n / 2);
103
+ for (let i = 0; i < n; i++) {
104
+ const v = s.freq[Math.floor((i / n) * s.freq.length * 0.8)] / 255;
105
+ const a = (i / n) * Math.PI * 2 - Math.PI / 2;
106
+ const len = Math.min(w, h) * 0.28 * v + 2;
107
+ ctx.strokeStyle = o.colors[i % o.colors.length];
108
+ ctx.beginPath();
109
+ ctx.moveTo(cx + Math.cos(a) * r0, cy + Math.sin(a) * r0);
110
+ ctx.lineTo(cx + Math.cos(a) * (r0 + len), cy + Math.sin(a) * (r0 + len));
111
+ ctx.stroke();
112
+ }
113
+ },
114
+ }),
115
+ bg('spectrum-mirror', 'Mirrored spectrum bars with a reflection on the floor (Canvas 2D).', { bars: 32, gap: 3 }, {
116
+ draw: ({ ctx, w, h, t, o }) => {
117
+ const s = musicSample(t);
118
+ ctx.clearRect(0, 0, w, h);
119
+ const n = o.bars;
120
+ const bw = Math.max(1, (w - o.gap * (n - 1)) / n);
121
+ const base = h * 0.68;
122
+ ctx.fillStyle = grad(ctx, 0, base - h * 0.6, 0, base, o.colors);
123
+ for (let i = 0; i < n; i++) {
124
+ const v = s.freq[Math.floor((Math.abs(i - n / 2) / (n / 2)) * s.freq.length * 0.7)] / 255;
125
+ const bh = Math.max(2, v * h * 0.6);
126
+ const x = i * (bw + o.gap);
127
+ ctx.globalAlpha = 1;
128
+ ctx.fillRect(x, base - bh, bw, bh);
129
+ ctx.globalAlpha = 0.22;
130
+ ctx.fillRect(x, base + 2, bw, bh * 0.45);
131
+ }
132
+ ctx.globalAlpha = 1;
133
+ },
134
+ }),
135
+ bg('sound-particles', 'Particles launched upward by the bass, coloured by pitch (Canvas 2D).', { max: 140 }, {
136
+ init: () => ({ p: [] }),
137
+ draw: ({ ctx, w, h, t, state, o }) => {
138
+ const s = musicSample(t);
139
+ const dt = state.last ? Math.min(0.05, t - state.last) : 0;
140
+ state.last = t;
141
+ ctx.clearRect(0, 0, w, h);
142
+ const spawn = Math.round(s.bass * 6);
143
+ for (let i = 0; i < spawn && state.p.length < o.max; i++)
144
+ state.p.push({ x: Math.random() * w, y: h + 4, vx: (Math.random() - 0.5) * 40, vy: -(80 + s.bass * 260 + Math.random() * 60), life: 1, c: o.colors[Math.floor(Math.random() * o.colors.length)] });
145
+ state.p = state.p.filter((p) => {
146
+ p.x += p.vx * dt;
147
+ p.y += p.vy * dt;
148
+ p.vy += 120 * dt;
149
+ p.life -= dt * 0.6;
150
+ ctx.globalAlpha = Math.max(0, p.life);
151
+ ctx.fillStyle = p.c;
152
+ ctx.beginPath();
153
+ ctx.arc(p.x, p.y, 2.5, 0, Math.PI * 2);
154
+ ctx.fill();
155
+ return p.life > 0 && p.y < h + 10;
156
+ });
157
+ ctx.globalAlpha = 1;
158
+ },
159
+ }),
160
+ loop('beat-bounce', 'The element pumps with the bass (`amount`).', { amount: 0.12 }, (el, s, _t, o) => {
161
+ el.style.transform = `scale(${(1 + s.bass * o.amount).toFixed(4)})`;
162
+ }),
163
+ loop('vinyl-spin', 'The element turns like a record at 33⅓ rpm; the level speeds it up (`rpm`).', { rpm: 33.3 }, (el, s, t, o, st) => {
164
+ const dt = st.last ? Math.min(0.05, t - st.last) : 0;
165
+ st.last = t;
166
+ st.a = ((st.a || 0) + (o.rpm / 60) * 360 * dt * (0.8 + s.level * 0.6)) % 360;
167
+ el.style.transform = `rotate(${st.a.toFixed(2)}deg)`;
168
+ }),
169
+ ];
170
+ /** Register the 7.1 music visualization pack (idempotent). */
171
+ function registerMusicPack() {
172
+ registry.registerEffects(MUSIC_FX);
173
+ }
174
+
175
+ exports.MUSIC_FX = MUSIC_FX;
176
+ exports.musicSample = musicSample;
177
+ exports.registerMusicPack = registerMusicPack;
178
+ exports.syntheticSample = syntheticSample;
179
+ //# sourceMappingURL=fx-music.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-music.cjs","sources":["../../src/components/fx2/music.ts"],"sourcesContent":["/**\n * 7.1 — Music visualization (`motionary/fx/music`, also\n * `motionary/components/fx-music`), registered through `registerEffect()`.\n * Every effect reads the running analyser (`enableAudio()` / `<usa-audio>`);\n * without one it plays a gentle synthetic signal (`syntheticSample()`), so\n * the visuals work as decoration too.\n *\n * - `waveform-scope` (background) — an oscilloscope line of the waveform.\n * - `radial-spectrum` (background) — spectrum bars around a circle.\n * - `spectrum-mirror` (background) — mirrored bars with a reflection.\n * - `sound-particles` (background) — particles launched by the bass.\n * - `beat-bounce` (loop) — the element pumps with the bass.\n * - `vinyl-spin` (loop) — the element turns like a record; level speeds it.\n *\n * Reduced motion: backgrounds draw one static frame, loops do nothing.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\nimport { canvasBackground, type GenerativeSpec } from '../effects/generative';\nimport { getAudio, type AudioSample } from '../effects/audio';\n\n/** A smooth, deterministic fake analyser frame at time `t` (s). */\nexport function syntheticSample(t: number, bins = 64): AudioSample {\n const freq = new Uint8Array(bins);\n const wave = new Uint8Array(128);\n const beat = Math.pow(Math.max(0, Math.sin(t * Math.PI * 2 * 1.9)), 8);\n for (let i = 0; i < bins; i++) {\n const k = i / bins;\n const v = (0.75 - k * 0.55) * (0.55 + 0.25 * Math.sin(t * 3.1 + i * 0.45) + 0.2 * Math.sin(t * 5.3 - i * 0.9)) + (k < 0.12 ? beat * 0.45 : 0);\n freq[i] = Math.max(0, Math.min(255, Math.round(v * 255)));\n }\n for (let i = 0; i < 128; i++) wave[i] = Math.round(128 + 70 * (0.6 * Math.sin(i * 0.19 + t * 9) + 0.3 * Math.sin(i * 0.53 - t * 13) + 0.25 * beat * Math.sin(i * 0.05)));\n const bass = Array.from(freq.slice(0, Math.max(1, Math.round(bins * 0.08)))).reduce((a, b) => a + b, 0) / (Math.max(1, Math.round(bins * 0.08)) * 255);\n return { level: 0.35 + beat * 0.3, bass, freq, wave };\n}\n\n/** The live analyser frame, or the synthetic one. */\nexport const musicSample = (t: number): AudioSample => getAudio()?.sample() ?? syntheticSample(t);\n\nconst bg = (name: string, description: string, defaults: Record<string, unknown>, spec: GenerativeSpec): EffectDefinition => ({\n name,\n kind: 'background',\n description,\n reduced: 'run',\n defaults: { speed: 1, quality: 1, colors: ['#22d3ee', '#7c5cff', '#f472b6'], ...defaults },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const stop = canvasBackground(el, ctx, spec, o);\n ctx.onCleanup(stop);\n return stop;\n },\n});\n\nconst grad = (ctx: CanvasRenderingContext2D, x0: number, y0: number, x1: number, y1: number, colors: string[]) => {\n const g = ctx.createLinearGradient(x0, y0, x1, y1);\n colors.forEach((c, i) => g.addColorStop(i / Math.max(1, colors.length - 1), c));\n return g;\n};\n\n/** A loop effect driven by the music sample each frame. */\nconst loop = (name: string, description: string, defaults: Record<string, unknown>, apply: (el: HTMLElement, s: AudioSample, t: number, o: any, st: any) => void): EffectDefinition => ({\n name,\n kind: 'loop',\n description,\n defaults,\n reduced: 'skip',\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n const prev = el.style.transform;\n const st: any = {};\n let raf = 0;\n const t0 = performance.now();\n const f = (now: number) => {\n const t = (now - t0) / 1000;\n apply(el, musicSample(t), t, o, st);\n raf = requestAnimationFrame(f);\n };\n if (typeof requestAnimationFrame === 'function') raf = requestAnimationFrame(f);\n const stop = () => {\n cancelAnimationFrame(raf);\n el.style.transform = prev;\n };\n ctx.onCleanup(stop);\n return stop;\n },\n});\n\nexport const MUSIC_FX: EffectDefinition[] = [\n bg('waveform-scope', 'An oscilloscope line of the waveform with a soft glow (Canvas 2D; live analyser or synthetic).', { width: 2.5 }, {\n draw: ({ ctx, w, h, t, o }) => {\n const s = musicSample(t);\n ctx.clearRect(0, 0, w, h);\n ctx.lineWidth = o.width;\n ctx.strokeStyle = grad(ctx, 0, 0, w, 0, o.colors);\n ctx.shadowColor = o.colors[0];\n ctx.shadowBlur = 10;\n ctx.beginPath();\n const n = s.wave.length;\n for (let i = 0; i < n; i++) {\n const x = (i / (n - 1)) * w;\n const y = h / 2 + ((s.wave[i] - 128) / 128) * h * 0.4;\n if (i) ctx.lineTo(x, y);\n else ctx.moveTo(x, y);\n }\n ctx.stroke();\n ctx.shadowBlur = 0;\n },\n }),\n bg('radial-spectrum', 'Spectrum bars around a circle that breathes with the bass (Canvas 2D).', { bars: 48 }, {\n draw: ({ ctx, w, h, t, o }) => {\n const s = musicSample(t);\n ctx.clearRect(0, 0, w, h);\n const cx = w / 2;\n const cy = h / 2;\n const r0 = Math.min(w, h) * (0.18 + s.bass * 0.06);\n const n = o.bars;\n ctx.lineCap = 'round';\n ctx.lineWidth = Math.max(2, (Math.PI * 2 * r0) / n / 2);\n for (let i = 0; i < n; i++) {\n const v = s.freq[Math.floor((i / n) * s.freq.length * 0.8)] / 255;\n const a = (i / n) * Math.PI * 2 - Math.PI / 2;\n const len = Math.min(w, h) * 0.28 * v + 2;\n ctx.strokeStyle = o.colors[i % o.colors.length];\n ctx.beginPath();\n ctx.moveTo(cx + Math.cos(a) * r0, cy + Math.sin(a) * r0);\n ctx.lineTo(cx + Math.cos(a) * (r0 + len), cy + Math.sin(a) * (r0 + len));\n ctx.stroke();\n }\n },\n }),\n bg('spectrum-mirror', 'Mirrored spectrum bars with a reflection on the floor (Canvas 2D).', { bars: 32, gap: 3 }, {\n draw: ({ ctx, w, h, t, o }) => {\n const s = musicSample(t);\n ctx.clearRect(0, 0, w, h);\n const n = o.bars;\n const bw = Math.max(1, (w - o.gap * (n - 1)) / n);\n const base = h * 0.68;\n ctx.fillStyle = grad(ctx, 0, base - h * 0.6, 0, base, o.colors);\n for (let i = 0; i < n; i++) {\n const v = s.freq[Math.floor((Math.abs(i - n / 2) / (n / 2)) * s.freq.length * 0.7)] / 255;\n const bh = Math.max(2, v * h * 0.6);\n const x = i * (bw + o.gap);\n ctx.globalAlpha = 1;\n ctx.fillRect(x, base - bh, bw, bh);\n ctx.globalAlpha = 0.22;\n ctx.fillRect(x, base + 2, bw, bh * 0.45);\n }\n ctx.globalAlpha = 1;\n },\n }),\n bg('sound-particles', 'Particles launched upward by the bass, coloured by pitch (Canvas 2D).', { max: 140 }, {\n init: () => ({ p: [] as { x: number; y: number; vx: number; vy: number; life: number; c: string }[] }),\n draw: ({ ctx, w, h, t, state, o }) => {\n const s = musicSample(t);\n const dt = state.last ? Math.min(0.05, t - state.last) : 0;\n state.last = t;\n ctx.clearRect(0, 0, w, h);\n const spawn = Math.round(s.bass * 6);\n for (let i = 0; i < spawn && state.p.length < o.max; i++) state.p.push({ x: Math.random() * w, y: h + 4, vx: (Math.random() - 0.5) * 40, vy: -(80 + s.bass * 260 + Math.random() * 60), life: 1, c: o.colors[Math.floor(Math.random() * o.colors.length)] });\n state.p = state.p.filter((p: any) => {\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += 120 * dt;\n p.life -= dt * 0.6;\n ctx.globalAlpha = Math.max(0, p.life);\n ctx.fillStyle = p.c;\n ctx.beginPath();\n ctx.arc(p.x, p.y, 2.5, 0, Math.PI * 2);\n ctx.fill();\n return p.life > 0 && p.y < h + 10;\n });\n ctx.globalAlpha = 1;\n },\n }),\n loop('beat-bounce', 'The element pumps with the bass (`amount`).', { amount: 0.12 }, (el, s, _t, o) => {\n el.style.transform = `scale(${(1 + s.bass * o.amount).toFixed(4)})`;\n }),\n loop('vinyl-spin', 'The element turns like a record at 33⅓ rpm; the level speeds it up (`rpm`).', { rpm: 33.3 }, (el, s, t, o, st) => {\n const dt = st.last ? Math.min(0.05, t - st.last) : 0;\n st.last = t;\n st.a = ((st.a || 0) + (o.rpm / 60) * 360 * dt * (0.8 + s.level * 0.6)) % 360;\n el.style.transform = `rotate(${st.a.toFixed(2)}deg)`;\n }),\n];\n\n/** Register the 7.1 music visualization pack (idempotent). */\nexport function registerMusicPack(): void {\n registerEffects(MUSIC_FX);\n}\n"],"names":["getAudio","canvasBackground","registerEffects"],"mappings":"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"}
@@ -0,0 +1,102 @@
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
+ * 5.6 — sound-reactive effects (Web Audio).
46
+ *
47
+ * - `enableAudio(input)` — start analysing the microphone (`'mic'`), an
48
+ * `<audio>` / `<video>` element (or a selector for one) or a `MediaStream`.
49
+ * Browsers only allow an `AudioContext` to start inside a user gesture, so
50
+ * call it from a click handler (or use `<usa-audio>`, which renders the
51
+ * toggle button for you).
52
+ * - Background effects (kind `background`, Canvas 2D through
53
+ * `canvasBackground()`): `spectrum-bars`, `pulse-ring`, `wave-ring`. Before
54
+ * audio is enabled they idle gently.
55
+ * - Beat detection: `createBeatDetector()` (pure: energy → beat?), `onBeat(cb)`
56
+ * and `bindBeat(el, effect, options)`, which plays any registered effect on
57
+ * every beat. `<usa-audio>` does the same for `[data-usa-beat="effect"]`
58
+ * children and emits `usa-beat`.
59
+ * - While audio runs, `--usa-audio-level` and `--usa-audio-bass` (0–1) are set
60
+ * on `<html>` for CSS-driven reactions.
61
+ *
62
+ * Reduced motion: the visual effects are skipped, beats play no effects and
63
+ * the CSS variables stay at 0 — audio itself keeps playing.
64
+ */
65
+
66
+ interface AudioSample {
67
+ /** Overall loudness (RMS of the waveform), 0–1. */
68
+ level: number;
69
+ /** Low-frequency energy (first ~8 % of the spectrum), 0–1. */
70
+ bass: number;
71
+ /** Frequency bins, 0–255 each. */
72
+ freq: Uint8Array;
73
+ /** Time-domain waveform, 0–255 (128 = silence). */
74
+ wave: Uint8Array;
75
+ }
76
+
77
+ /**
78
+ * 7.1 — Music visualization (`motionary/fx/music`, also
79
+ * `motionary/components/fx-music`), registered through `registerEffect()`.
80
+ * Every effect reads the running analyser (`enableAudio()` / `<usa-audio>`);
81
+ * without one it plays a gentle synthetic signal (`syntheticSample()`), so
82
+ * the visuals work as decoration too.
83
+ *
84
+ * - `waveform-scope` (background) — an oscilloscope line of the waveform.
85
+ * - `radial-spectrum` (background) — spectrum bars around a circle.
86
+ * - `spectrum-mirror` (background) — mirrored bars with a reflection.
87
+ * - `sound-particles` (background) — particles launched by the bass.
88
+ * - `beat-bounce` (loop) — the element pumps with the bass.
89
+ * - `vinyl-spin` (loop) — the element turns like a record; level speeds it.
90
+ *
91
+ * Reduced motion: backgrounds draw one static frame, loops do nothing.
92
+ */
93
+
94
+ /** A smooth, deterministic fake analyser frame at time `t` (s). */
95
+ declare function syntheticSample(t: number, bins?: number): AudioSample;
96
+ /** The live analyser frame, or the synthetic one. */
97
+ declare const musicSample: (t: number) => AudioSample;
98
+ declare const MUSIC_FX: EffectDefinition[];
99
+ /** Register the 7.1 music visualization pack (idempotent). */
100
+ declare function registerMusicPack(): void;
101
+
102
+ export { MUSIC_FX, musicSample, registerMusicPack, syntheticSample };
@@ -0,0 +1,102 @@
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
+ * 5.6 — sound-reactive effects (Web Audio).
46
+ *
47
+ * - `enableAudio(input)` — start analysing the microphone (`'mic'`), an
48
+ * `<audio>` / `<video>` element (or a selector for one) or a `MediaStream`.
49
+ * Browsers only allow an `AudioContext` to start inside a user gesture, so
50
+ * call it from a click handler (or use `<usa-audio>`, which renders the
51
+ * toggle button for you).
52
+ * - Background effects (kind `background`, Canvas 2D through
53
+ * `canvasBackground()`): `spectrum-bars`, `pulse-ring`, `wave-ring`. Before
54
+ * audio is enabled they idle gently.
55
+ * - Beat detection: `createBeatDetector()` (pure: energy → beat?), `onBeat(cb)`
56
+ * and `bindBeat(el, effect, options)`, which plays any registered effect on
57
+ * every beat. `<usa-audio>` does the same for `[data-usa-beat="effect"]`
58
+ * children and emits `usa-beat`.
59
+ * - While audio runs, `--usa-audio-level` and `--usa-audio-bass` (0–1) are set
60
+ * on `<html>` for CSS-driven reactions.
61
+ *
62
+ * Reduced motion: the visual effects are skipped, beats play no effects and
63
+ * the CSS variables stay at 0 — audio itself keeps playing.
64
+ */
65
+
66
+ interface AudioSample {
67
+ /** Overall loudness (RMS of the waveform), 0–1. */
68
+ level: number;
69
+ /** Low-frequency energy (first ~8 % of the spectrum), 0–1. */
70
+ bass: number;
71
+ /** Frequency bins, 0–255 each. */
72
+ freq: Uint8Array;
73
+ /** Time-domain waveform, 0–255 (128 = silence). */
74
+ wave: Uint8Array;
75
+ }
76
+
77
+ /**
78
+ * 7.1 — Music visualization (`motionary/fx/music`, also
79
+ * `motionary/components/fx-music`), registered through `registerEffect()`.
80
+ * Every effect reads the running analyser (`enableAudio()` / `<usa-audio>`);
81
+ * without one it plays a gentle synthetic signal (`syntheticSample()`), so
82
+ * the visuals work as decoration too.
83
+ *
84
+ * - `waveform-scope` (background) — an oscilloscope line of the waveform.
85
+ * - `radial-spectrum` (background) — spectrum bars around a circle.
86
+ * - `spectrum-mirror` (background) — mirrored bars with a reflection.
87
+ * - `sound-particles` (background) — particles launched by the bass.
88
+ * - `beat-bounce` (loop) — the element pumps with the bass.
89
+ * - `vinyl-spin` (loop) — the element turns like a record; level speeds it.
90
+ *
91
+ * Reduced motion: backgrounds draw one static frame, loops do nothing.
92
+ */
93
+
94
+ /** A smooth, deterministic fake analyser frame at time `t` (s). */
95
+ declare function syntheticSample(t: number, bins?: number): AudioSample;
96
+ /** The live analyser frame, or the synthetic one. */
97
+ declare const musicSample: (t: number) => AudioSample;
98
+ declare const MUSIC_FX: EffectDefinition[];
99
+ /** Register the 7.1 music visualization pack (idempotent). */
100
+ declare function registerMusicPack(): void;
101
+
102
+ export { MUSIC_FX, musicSample, registerMusicPack, syntheticSample };