use-scroll-animate 10.2.0 → 10.4.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/AGENTS.md +4 -0
- package/CHANGELOG.md +35 -0
- package/README.md +67 -0
- package/bin/motionary-mcp.mjs +265 -0
- package/dist/chunks/anim-image-DDdb9q3X.js +166 -0
- package/dist/chunks/anim-image-DDdb9q3X.js.map +1 -0
- package/dist/chunks/anim-image-blQgPFFS.cjs +174 -0
- package/dist/chunks/anim-image-blQgPFFS.cjs.map +1 -0
- package/dist/chunks/audio-BpU-A1m1.cjs.map +1 -1
- package/dist/chunks/{audio-D95jwlOh.js → audio-CWt1xdZB.js} +3 -3
- package/dist/chunks/{audio-D95jwlOh.js.map → audio-CWt1xdZB.js.map} +1 -1
- package/dist/chunks/{base-BnRyfuyM.js → base-BTev8qxg.js} +2 -2
- package/dist/chunks/{base-BnRyfuyM.js.map → base-BTev8qxg.js.map} +1 -1
- package/dist/chunks/base-DBheNxJu.cjs.map +1 -1
- package/dist/chunks/bind-B_CTL6Qn.js.map +1 -1
- package/dist/chunks/bind-Ui43-n2d.cjs.map +1 -1
- package/dist/chunks/builtins-CKKZNR95.cjs.map +1 -1
- package/dist/chunks/{builtins-CqIq1zBv.js → builtins-CPmS6aDB.js} +3 -3
- package/dist/chunks/{builtins-CqIq1zBv.js.map → builtins-CPmS6aDB.js.map} +1 -1
- package/dist/chunks/core-B5T0dhFH.cjs.map +1 -1
- package/dist/chunks/{core-DsGoL9EY.js → core-BviA7nFa.js} +2 -2
- package/dist/chunks/{core-DsGoL9EY.js.map → core-BviA7nFa.js.map} +1 -1
- package/dist/chunks/core-D74Fz-dL.cjs.map +1 -1
- package/dist/chunks/core-D7cVumUu.js.map +1 -1
- package/dist/chunks/{core-XA2yhn1b.js → core-KiM7MXjL.js} +2 -2
- package/dist/chunks/{core-XA2yhn1b.js.map → core-KiM7MXjL.js.map} +1 -1
- package/dist/chunks/core-MQlXZKUG.cjs.map +1 -1
- package/dist/chunks/ease-HwYZnZat.cjs +94 -0
- package/dist/chunks/ease-HwYZnZat.cjs.map +1 -0
- package/dist/chunks/ease-XN8_0sXu.js +89 -0
- package/dist/chunks/ease-XN8_0sXu.js.map +1 -0
- package/dist/chunks/fx-B_pbhpDp.cjs.map +1 -1
- package/dist/chunks/{fx-CtnrFEg9.js → fx-CgWKqVsn.js} +2 -2
- package/dist/chunks/{fx-CtnrFEg9.js.map → fx-CgWKqVsn.js.map} +1 -1
- package/dist/chunks/generative-2LhxG5BJ.js.map +1 -1
- package/dist/chunks/generative-BHIj-NU0.cjs.map +1 -1
- package/dist/chunks/{gpu-CDcXiNA8.js → gpu-BWfgYWMY.js} +2 -2
- package/dist/chunks/{gpu-CDcXiNA8.js.map → gpu-BWfgYWMY.js.map} +1 -1
- package/dist/chunks/gpu-cUixt7kT.cjs.map +1 -1
- package/dist/chunks/index-tags-B-JBecYg.js.map +1 -1
- package/dist/chunks/index-tags-hLIF2Clq.cjs.map +1 -1
- package/dist/chunks/{keyframes-W-474DMc.js → keyframes-B5PWe5bU.js} +3 -2
- package/dist/chunks/keyframes-B5PWe5bU.js.map +1 -0
- package/dist/chunks/{keyframes-ZheOkpt0.cjs → keyframes-tC3I7anQ.cjs} +4 -3
- package/dist/chunks/keyframes-tC3I7anQ.cjs.map +1 -0
- package/dist/chunks/{manifest-D58HXVY-.js → manifest-BHx5yPN6.js} +2 -2
- package/dist/chunks/{manifest-D58HXVY-.js.map → manifest-BHx5yPN6.js.map} +1 -1
- package/dist/chunks/manifest-PaF9B8Vt.cjs.map +1 -1
- package/dist/chunks/{player-48Zy_NBG.js → player-BfHMNtiM.js} +4 -4
- package/dist/chunks/{player-48Zy_NBG.js.map → player-BfHMNtiM.js.map} +1 -1
- package/dist/chunks/player-C4y4jXSv.cjs.map +1 -1
- package/dist/chunks/presets-BYBVJVeP.js.map +1 -1
- package/dist/chunks/presets-CUHys3sK.cjs.map +1 -1
- package/dist/chunks/{registry-gFJRpPES.js → registry-BKzyg1JV.js} +2 -2
- package/dist/chunks/{registry-gFJRpPES.js.map → registry-BKzyg1JV.js.map} +1 -1
- package/dist/chunks/{registry-BIEjKngP.js → registry-CT-TT_bx.js} +3 -3
- package/dist/chunks/{registry-BIEjKngP.js.map → registry-CT-TT_bx.js.map} +1 -1
- package/dist/chunks/{registry-eJgpFAzI.cjs → registry-tzwKkldE.cjs} +2 -2
- package/dist/chunks/{registry-eJgpFAzI.cjs.map → registry-tzwKkldE.cjs.map} +1 -1
- package/dist/chunks/registry-xQZnSqqV.cjs.map +1 -1
- package/dist/chunks/shared-CkKHWrtJ.js.map +1 -1
- package/dist/chunks/shared-jkgRH-Hx.cjs.map +1 -1
- package/dist/chunks/{spring-CZDNyqWp.js → spring-BHuP55DR.js} +2 -2
- package/dist/chunks/{spring-CZDNyqWp.js.map → spring-BHuP55DR.js.map} +1 -1
- package/dist/chunks/spring-BlTQD2AV.cjs.map +1 -1
- package/dist/chunks/stagger-CCFyhzSw.cjs.map +1 -1
- package/dist/chunks/stagger-DtMKo2SK.js.map +1 -1
- package/dist/chunks/{ticker-CM_56oVy.js → ticker-C8lSGml9.js} +2 -2
- package/dist/chunks/{ticker-CM_56oVy.js.map → ticker-C8lSGml9.js.map} +1 -1
- package/dist/chunks/{ticker-D4o6enH0.cjs → ticker-Un0bvTWR.cjs} +2 -2
- package/dist/chunks/{ticker-D4o6enH0.cjs.map → ticker-Un0bvTWR.cjs.map} +1 -1
- package/dist/chunks/{tween-CqX1JBuj.js → tween-BcejKpsx.js} +15 -91
- package/dist/chunks/tween-BcejKpsx.js.map +1 -0
- package/dist/chunks/{tween-CBuWYpI-.cjs → tween-CwLLC3Ko.cjs} +15 -95
- package/dist/chunks/tween-CwLLC3Ko.cjs.map +1 -0
- package/dist/chunks/variants-CrDDJoYK.cjs.map +1 -1
- package/dist/chunks/{variants-GU3yIL4F.js → variants-CsRGUIyA.js} +2 -2
- package/dist/chunks/{variants-GU3yIL4F.js.map → variants-CsRGUIyA.js.map} +1 -1
- package/dist/components/a11y.cjs.map +1 -1
- package/dist/components/a11y.js +2 -2
- package/dist/components/a11y.js.map +1 -1
- package/dist/components/angular.cjs.map +1 -1
- package/dist/components/angular.js +8 -8
- package/dist/components/angular.js.map +1 -1
- package/dist/components/background.cjs.map +1 -1
- package/dist/components/background.js +2 -2
- package/dist/components/background.js.map +1 -1
- package/dist/components/bridge.cjs.map +1 -1
- package/dist/components/bridge.js +1 -1
- package/dist/components/bridge.js.map +1 -1
- package/dist/components/cards.cjs.map +1 -1
- package/dist/components/cards.js +2 -2
- package/dist/components/cards.js.map +1 -1
- package/dist/components/click.cjs.map +1 -1
- package/dist/components/click.js +3 -3
- package/dist/components/click.js.map +1 -1
- package/dist/components/core.cjs.map +1 -1
- package/dist/components/core.js.map +1 -1
- package/dist/components/depth.cjs.map +1 -1
- package/dist/components/depth.js +3 -3
- package/dist/components/depth.js.map +1 -1
- package/dist/components/design.cjs.map +1 -1
- package/dist/components/design.js +3 -3
- package/dist/components/design.js.map +1 -1
- package/dist/components/dsl.cjs.map +1 -1
- package/dist/components/dsl.js +2 -2
- package/dist/components/dsl.js.map +1 -1
- package/dist/components/effects.cjs.map +1 -1
- package/dist/components/effects.js +9 -9
- package/dist/components/effects.js.map +1 -1
- package/dist/components/engine.cjs.map +1 -1
- package/dist/components/engine.js +2 -2
- package/dist/components/engine.js.map +1 -1
- package/dist/components/feedback.cjs.map +1 -1
- package/dist/components/feedback.js +1 -1
- package/dist/components/feedback.js.map +1 -1
- package/dist/components/fx-3d.cjs.map +1 -1
- package/dist/components/fx-3d.js +2 -2
- package/dist/components/fx-3d.js.map +1 -1
- package/dist/components/fx-ai.cjs.map +1 -1
- package/dist/components/fx-ai.js +2 -2
- package/dist/components/fx-ai.js.map +1 -1
- package/dist/components/fx-chart.cjs.map +1 -1
- package/dist/components/fx-chart.js +2 -2
- package/dist/components/fx-chart.js.map +1 -1
- package/dist/components/fx-cinema.cjs.map +1 -1
- package/dist/components/fx-cinema.js +2 -2
- package/dist/components/fx-cinema.js.map +1 -1
- package/dist/components/fx-cyber.cjs.map +1 -1
- package/dist/components/fx-cyber.js +2 -2
- package/dist/components/fx-cyber.js.map +1 -1
- package/dist/components/fx-festival.cjs.map +1 -1
- package/dist/components/fx-festival.js +2 -2
- package/dist/components/fx-festival.js.map +1 -1
- package/dist/components/fx-focus.cjs.map +1 -1
- package/dist/components/fx-focus.js +2 -2
- package/dist/components/fx-focus.js.map +1 -1
- package/dist/components/fx-form.cjs.map +1 -1
- package/dist/components/fx-form.js +2 -2
- package/dist/components/fx-form.js.map +1 -1
- package/dist/components/fx-game.cjs.map +1 -1
- package/dist/components/fx-game.js +2 -2
- package/dist/components/fx-game.js.map +1 -1
- package/dist/components/fx-genart.cjs.map +1 -1
- package/dist/components/fx-genart.js +2 -2
- package/dist/components/fx-genart.js.map +1 -1
- package/dist/components/fx-geo.cjs.map +1 -1
- package/dist/components/fx-geo.js +2 -2
- package/dist/components/fx-geo.js.map +1 -1
- package/dist/components/fx-gesture.cjs.map +1 -1
- package/dist/components/fx-gesture.js +2 -2
- package/dist/components/fx-gesture.js.map +1 -1
- package/dist/components/fx-gpu.js +3 -3
- package/dist/components/fx-light.cjs.map +1 -1
- package/dist/components/fx-light.js +2 -2
- package/dist/components/fx-light.js.map +1 -1
- package/dist/components/fx-lottie.cjs.map +1 -1
- package/dist/components/fx-lottie.js +2 -2
- package/dist/components/fx-lottie.js.map +1 -1
- package/dist/components/fx-morph.cjs.map +1 -1
- package/dist/components/fx-morph.js +2 -2
- package/dist/components/fx-morph.js.map +1 -1
- package/dist/components/fx-music.cjs.map +1 -1
- package/dist/components/fx-music.js +3 -3
- package/dist/components/fx-music.js.map +1 -1
- package/dist/components/fx-organic.cjs.map +1 -1
- package/dist/components/fx-organic.js +2 -2
- package/dist/components/fx-organic.js.map +1 -1
- package/dist/components/fx-paper.cjs.map +1 -1
- package/dist/components/fx-paper.js +2 -2
- package/dist/components/fx-paper.js.map +1 -1
- package/dist/components/fx-perf.cjs.map +1 -1
- package/dist/components/fx-perf.js +2 -2
- package/dist/components/fx-perf.js.map +1 -1
- package/dist/components/fx-physics.cjs.map +1 -1
- package/dist/components/fx-physics.js +2 -2
- package/dist/components/fx-physics.js.map +1 -1
- package/dist/components/fx-retro.cjs.map +1 -1
- package/dist/components/fx-retro.js +2 -2
- package/dist/components/fx-retro.js.map +1 -1
- package/dist/components/fx-safe.cjs.map +1 -1
- package/dist/components/fx-safe.js +2 -2
- package/dist/components/fx-safe.js.map +1 -1
- package/dist/components/fx-shop.cjs.map +1 -1
- package/dist/components/fx-shop.js +2 -2
- package/dist/components/fx-shop.js.map +1 -1
- package/dist/components/fx-social.cjs.map +1 -1
- package/dist/components/fx-social.js +2 -2
- package/dist/components/fx-social.js.map +1 -1
- package/dist/components/fx-spatial.cjs.map +1 -1
- package/dist/components/fx-spatial.js +2 -2
- package/dist/components/fx-spatial.js.map +1 -1
- package/dist/components/fx-surface.cjs.map +1 -1
- package/dist/components/fx-surface.js +2 -2
- package/dist/components/fx-surface.js.map +1 -1
- package/dist/components/fx-text.cjs.map +1 -1
- package/dist/components/fx-text.js +2 -2
- package/dist/components/fx-text.js.map +1 -1
- package/dist/components/fx-transitions.cjs.map +1 -1
- package/dist/components/fx-transitions.js +3 -3
- package/dist/components/fx-transitions.js.map +1 -1
- package/dist/components/fx-video.cjs.map +1 -1
- package/dist/components/fx-video.js +2 -2
- package/dist/components/fx-video.js.map +1 -1
- package/dist/components/fx-weather.cjs.map +1 -1
- package/dist/components/fx-weather.js +2 -2
- package/dist/components/fx-weather.js.map +1 -1
- package/dist/components/fx.cjs.map +1 -1
- package/dist/components/fx.js +6 -6
- package/dist/components/fx.js.map +1 -1
- package/dist/components/fx2.cjs.map +1 -1
- package/dist/components/fx2.js +6 -6
- package/dist/components/fx2.js.map +1 -1
- package/dist/components/gesture.cjs.map +1 -1
- package/dist/components/gesture.js +4 -4
- package/dist/components/gesture.js.map +1 -1
- package/dist/components/interaction.cjs.map +1 -1
- package/dist/components/interaction.js +1 -1
- package/dist/components/interaction.js.map +1 -1
- package/dist/components/layout.cjs.map +1 -1
- package/dist/components/layout.js +1 -1
- package/dist/components/layout.js.map +1 -1
- package/dist/components/lazy.cjs.map +1 -1
- package/dist/components/lazy.js.map +1 -1
- package/dist/components/lite.cjs.map +1 -1
- package/dist/components/lite.js.map +1 -1
- package/dist/components/marketplace.cjs.map +1 -1
- package/dist/components/marketplace.js +4 -4
- package/dist/components/marketplace.js.map +1 -1
- package/dist/components/native.cjs.map +1 -1
- package/dist/components/native.js +3 -3
- package/dist/components/native.js.map +1 -1
- package/dist/components/packs.cjs.map +1 -1
- package/dist/components/packs.js +1 -1
- package/dist/components/packs.js.map +1 -1
- package/dist/components/page.cjs.map +1 -1
- package/dist/components/page.js +3 -3
- package/dist/components/page.js.map +1 -1
- package/dist/components/perf.cjs.map +1 -1
- package/dist/components/perf.js +2 -2
- package/dist/components/perf.js.map +1 -1
- package/dist/components/physics.cjs.map +1 -1
- package/dist/components/physics.js +3 -3
- package/dist/components/physics.js.map +1 -1
- package/dist/components/plugins.cjs.map +1 -1
- package/dist/components/plugins.js +4 -4
- package/dist/components/plugins.js.map +1 -1
- package/dist/components/react.cjs.map +1 -1
- package/dist/components/react.js.map +1 -1
- package/dist/components/reveal.cjs.map +1 -1
- package/dist/components/reveal.js +1 -1
- package/dist/components/reveal.js.map +1 -1
- package/dist/components/solid.cjs.map +1 -1
- package/dist/components/solid.js +8 -8
- package/dist/components/solid.js.map +1 -1
- package/dist/components/svelte.cjs.map +1 -1
- package/dist/components/svelte.js +8 -8
- package/dist/components/svelte.js.map +1 -1
- package/dist/components/svg.cjs.map +1 -1
- package/dist/components/svg.js +1 -1
- package/dist/components/svg.js.map +1 -1
- package/dist/components/text.cjs.map +1 -1
- package/dist/components/text.js +2 -2
- package/dist/components/text.js.map +1 -1
- package/dist/components/timeline.cjs.map +1 -1
- package/dist/components/timeline.js +3 -3
- package/dist/components/timeline.js.map +1 -1
- package/dist/components/tokens.cjs.map +1 -1
- package/dist/components/tokens.js.map +1 -1
- package/dist/components/transitions.cjs.map +1 -1
- package/dist/components/transitions.js +1 -1
- package/dist/components/transitions.js.map +1 -1
- package/dist/components/ui.cjs.map +1 -1
- package/dist/components/ui.js +4 -4
- package/dist/components/ui.js.map +1 -1
- package/dist/components/vue.cjs.map +1 -1
- package/dist/components/vue.js +8 -8
- package/dist/components/vue.js.map +1 -1
- package/dist/components/webgl.cjs.map +1 -1
- package/dist/components/webgl.js +1 -1
- package/dist/components/webgl.js.map +1 -1
- package/dist/components/widgets.cjs +766 -212
- package/dist/components/widgets.cjs.map +1 -1
- package/dist/components/widgets.d.cts +207 -2
- package/dist/components/widgets.d.ts +207 -2
- package/dist/components/widgets.js +770 -221
- package/dist/components/widgets.js.map +1 -1
- package/dist/components.cjs.map +1 -1
- package/dist/components.js +10 -10
- package/dist/components.js.map +1 -1
- package/dist/element.cjs.map +1 -1
- package/dist/element.js.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +250 -1
- package/dist/llms.txt +13 -2
- package/dist/manifest.json +646 -1
- package/dist/presets/extended.cjs.map +1 -1
- package/dist/presets/extended.js.map +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.js.map +1 -1
- package/dist/runtime/format-apng.cjs +131 -0
- package/dist/runtime/format-apng.cjs.map +1 -0
- package/dist/runtime/format-apng.d.cts +250 -0
- package/dist/runtime/format-apng.d.ts +250 -0
- package/dist/runtime/format-apng.iife.js +2 -0
- package/dist/runtime/format-apng.iife.js.map +1 -0
- package/dist/runtime/format-apng.js +123 -0
- package/dist/runtime/format-apng.js.map +1 -0
- package/dist/runtime/format-css.cjs +5 -4
- package/dist/runtime/format-css.cjs.map +1 -1
- package/dist/runtime/format-css.js +5 -4
- package/dist/runtime/format-css.js.map +1 -1
- package/dist/runtime/format-gif.cjs +206 -0
- package/dist/runtime/format-gif.cjs.map +1 -0
- package/dist/runtime/format-gif.d.cts +223 -0
- package/dist/runtime/format-gif.d.ts +223 -0
- package/dist/runtime/format-gif.iife.js +2 -0
- package/dist/runtime/format-gif.iife.js.map +1 -0
- package/dist/runtime/format-gif.js +199 -0
- package/dist/runtime/format-gif.js.map +1 -0
- package/dist/runtime/format-motion.cjs +9 -8
- package/dist/runtime/format-motion.cjs.map +1 -1
- package/dist/runtime/format-motion.js +5 -4
- package/dist/runtime/format-motion.js.map +1 -1
- package/dist/runtime/format-sprite.cjs +226 -0
- package/dist/runtime/format-sprite.cjs.map +1 -0
- package/dist/runtime/format-sprite.d.cts +224 -0
- package/dist/runtime/format-sprite.d.ts +224 -0
- package/dist/runtime/format-sprite.iife.js +2 -0
- package/dist/runtime/format-sprite.iife.js.map +1 -0
- package/dist/runtime/format-sprite.js +216 -0
- package/dist/runtime/format-sprite.js.map +1 -0
- package/dist/runtime/format-svg.cjs +5 -4
- package/dist/runtime/format-svg.cjs.map +1 -1
- package/dist/runtime/format-svg.iife.js.map +1 -1
- package/dist/runtime/format-svg.js +4 -3
- package/dist/runtime/format-svg.js.map +1 -1
- package/dist/runtime/format-webp.cjs +123 -0
- package/dist/runtime/format-webp.cjs.map +1 -0
- package/dist/runtime/format-webp.d.cts +245 -0
- package/dist/runtime/format-webp.d.ts +245 -0
- package/dist/runtime/format-webp.iife.js +2 -0
- package/dist/runtime/format-webp.iife.js.map +1 -0
- package/dist/runtime/format-webp.js +115 -0
- package/dist/runtime/format-webp.js.map +1 -0
- package/dist/runtime/scroll.cjs +2 -2
- package/dist/runtime/scroll.cjs.map +1 -1
- package/dist/runtime/scroll.js +2 -2
- package/dist/runtime/scroll.js.map +1 -1
- package/dist/runtime/smooth.cjs +284 -0
- package/dist/runtime/smooth.cjs.map +1 -0
- package/dist/runtime/smooth.d.cts +137 -0
- package/dist/runtime/smooth.d.ts +137 -0
- package/dist/runtime/smooth.iife.js +2 -0
- package/dist/runtime/smooth.iife.js.map +1 -0
- package/dist/runtime/smooth.js +279 -0
- package/dist/runtime/smooth.js.map +1 -0
- package/dist/runtime/text.cjs +147 -0
- package/dist/runtime/text.cjs.map +1 -0
- package/dist/runtime/text.d.cts +65 -0
- package/dist/runtime/text.d.ts +65 -0
- package/dist/runtime/text.iife.js +2 -0
- package/dist/runtime/text.iife.js.map +1 -0
- package/dist/runtime/text.js +143 -0
- package/dist/runtime/text.js.map +1 -0
- package/dist/runtime.cjs +9 -8
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +9 -2
- package/dist/runtime.d.ts +9 -2
- package/dist/runtime.iife.js +1 -1
- package/dist/runtime.iife.js.map +1 -1
- package/dist/runtime.js +6 -5
- package/dist/runtime.js.map +1 -1
- package/dist/solid.cjs.map +1 -1
- package/dist/solid.js.map +1 -1
- package/dist/svelte.cjs.map +1 -1
- package/dist/svelte.js.map +1 -1
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js.map +1 -1
- package/dist/widgets.umd.js +1 -1
- package/dist/widgets.umd.js.map +1 -1
- package/docs/ROADMAP.md +2 -2
- package/docs/components/README.md +12 -7
- package/docs/components/usa-parallax-layers.md +38 -0
- package/docs/components/usa-route-transition.md +38 -0
- package/docs/components/usa-scroll-ring.md +32 -0
- package/docs/components/usa-smooth-scroll.md +60 -0
- package/docs/components/usa-text-splitter.md +60 -0
- package/docs/components.md +94 -0
- package/docs/mcp.md +50 -0
- package/docs/runtime/format-apng.md +59 -0
- package/docs/runtime/format-gif.md +60 -0
- package/docs/runtime/format-sprite.md +60 -0
- package/docs/runtime/format-webp.md +58 -0
- package/docs/runtime/smooth.md +60 -0
- package/docs/runtime/text.md +59 -0
- package/package.json +64 -2
- package/dist/chunks/keyframes-W-474DMc.js.map +0 -1
- package/dist/chunks/keyframes-ZheOkpt0.cjs.map +0 -1
- package/dist/chunks/tween-CBuWYpI-.cjs.map +0 -1
- package/dist/chunks/tween-CqX1JBuj.js.map +0 -1
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var tween = require('./tween-CwLLC3Ko.cjs');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Shared internals of the animated-image loaders (`format-gif`, `format-apng`,
|
|
7
|
+
* `format-webp`, 10.4): the decoded-animation shape, frame compositing in
|
|
8
|
+
* plain RGBA arrays (no DOM — works in workers and on the server), the
|
|
9
|
+
* browser image decoder used for APNG / WebP frames, and the canvas player
|
|
10
|
+
* (a runtime `Playable`, so it can be paused, reversed, scrubbed and driven
|
|
11
|
+
* by a scroll scene). Bundled into each loader; not a public module.
|
|
12
|
+
*/
|
|
13
|
+
/** Browsers clamp tiny delays (0–10 ms) to 100 ms; we do the same. */
|
|
14
|
+
const fixDelay = (ms) => (ms <= 10 ? 100 : ms);
|
|
15
|
+
/** Composite frame parts onto a `width × height` canvas (pure; RGBA in, RGBA out). */
|
|
16
|
+
function composeFrames(width, height, parts, background) {
|
|
17
|
+
const canvas = new Uint8ClampedArray(width * height * 4);
|
|
18
|
+
const out = [];
|
|
19
|
+
for (const p of parts) {
|
|
20
|
+
const before = p.dispose === 'previous' ? canvas.slice() : null;
|
|
21
|
+
const { width: w, height: h, data } = p.image;
|
|
22
|
+
for (let y = 0; y < h; y++) {
|
|
23
|
+
const cy = p.y + y;
|
|
24
|
+
if (cy < 0 || cy >= height)
|
|
25
|
+
continue;
|
|
26
|
+
for (let x = 0; x < w; x++) {
|
|
27
|
+
const cx = p.x + x;
|
|
28
|
+
if (cx < 0 || cx >= width)
|
|
29
|
+
continue;
|
|
30
|
+
const s = (y * w + x) * 4, d = (cy * width + cx) * 4;
|
|
31
|
+
const a = data[s + 3];
|
|
32
|
+
if (p.blend === 'source' || a === 255) {
|
|
33
|
+
canvas[d] = data[s];
|
|
34
|
+
canvas[d + 1] = data[s + 1];
|
|
35
|
+
canvas[d + 2] = data[s + 2];
|
|
36
|
+
canvas[d + 3] = a;
|
|
37
|
+
}
|
|
38
|
+
else if (a) {
|
|
39
|
+
// straight-alpha "over"
|
|
40
|
+
const da = canvas[d + 3] / 255, sa = a / 255, oa = sa + da * (1 - sa);
|
|
41
|
+
for (let c = 0; c < 3; c++)
|
|
42
|
+
canvas[d + c] = (data[s + c] * sa + canvas[d + c] * da * (1 - sa)) / oa;
|
|
43
|
+
canvas[d + 3] = oa * 255;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
out.push({ delay: p.delay, image: { width, height, data: canvas.slice() } });
|
|
48
|
+
if (p.dispose === 'background') {
|
|
49
|
+
for (let y = Math.max(0, p.y); y < Math.min(height, p.y + h); y++)
|
|
50
|
+
for (let x = Math.max(0, p.x); x < Math.min(width, p.x + w); x++)
|
|
51
|
+
canvas.set(background || [0, 0, 0, 0], (y * width + x) * 4);
|
|
52
|
+
}
|
|
53
|
+
else if (before)
|
|
54
|
+
canvas.set(before);
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
/** Default decoder: the browser's own (`createImageBitmap` + a 2D canvas; OffscreenCanvas in workers). */
|
|
59
|
+
const browserDecode = async (bytes, mime) => {
|
|
60
|
+
const g = globalThis;
|
|
61
|
+
if (typeof g.createImageBitmap !== 'function')
|
|
62
|
+
throw new Error('[motionary] no image decoder here (createImageBitmap is missing) — pass { decode } to the loader');
|
|
63
|
+
const bmp = await g.createImageBitmap(new Blob([bytes], { type: mime }));
|
|
64
|
+
const w = bmp.width, h = bmp.height; // read before close(): a closed ImageBitmap reports 0 × 0
|
|
65
|
+
const c = typeof g.OffscreenCanvas === 'function' ? new g.OffscreenCanvas(w, h) : Object.assign(document.createElement('canvas'), { width: w, height: h });
|
|
66
|
+
const ctx = c.getContext('2d', { willReadFrequently: true });
|
|
67
|
+
ctx.drawImage(bmp, 0, 0);
|
|
68
|
+
bmp.close?.();
|
|
69
|
+
const id = ctx.getImageData(0, 0, w, h);
|
|
70
|
+
return { width: id.width, height: id.height, data: id.data };
|
|
71
|
+
};
|
|
72
|
+
/** Read a `src` (URL, ArrayBuffer, typed array or Blob) into bytes. */
|
|
73
|
+
async function bytesOf(src) {
|
|
74
|
+
if (typeof src === 'string') {
|
|
75
|
+
const r = await fetch(src);
|
|
76
|
+
if (!r.ok)
|
|
77
|
+
throw new Error(`[motionary] could not load ${src} (${r.status})`);
|
|
78
|
+
return new Uint8Array(await r.arrayBuffer());
|
|
79
|
+
}
|
|
80
|
+
if (src instanceof ArrayBuffer)
|
|
81
|
+
return new Uint8Array(src);
|
|
82
|
+
if (ArrayBuffer.isView(src))
|
|
83
|
+
return new Uint8Array(src.buffer, src.byteOffset, src.byteLength);
|
|
84
|
+
return new Uint8Array(await src.arrayBuffer());
|
|
85
|
+
}
|
|
86
|
+
class AnimImagePlayer extends tween.Playable {
|
|
87
|
+
constructor(canvas, anim, o) {
|
|
88
|
+
super({ repeat: o.repeat ?? (anim.plays === 0 ? -1 : Math.max(0, anim.plays - 1)), yoyo: o.yoyo });
|
|
89
|
+
this.canvas = canvas;
|
|
90
|
+
this.anim = anim;
|
|
91
|
+
this.times = [0];
|
|
92
|
+
this.cur = -1;
|
|
93
|
+
this.timeScale = o.speed || 1;
|
|
94
|
+
for (const f of anim.frames)
|
|
95
|
+
this.times.push(this.times[this.times.length - 1] + f.delay);
|
|
96
|
+
if (canvas.width !== anim.width)
|
|
97
|
+
canvas.width = anim.width;
|
|
98
|
+
if (canvas.height !== anim.height)
|
|
99
|
+
canvas.height = anim.height;
|
|
100
|
+
this.ctx = canvas.getContext('2d');
|
|
101
|
+
this.datas = anim.frames.map(() => null);
|
|
102
|
+
this.show(0);
|
|
103
|
+
if (!o.paused)
|
|
104
|
+
this.play();
|
|
105
|
+
}
|
|
106
|
+
get duration() {
|
|
107
|
+
return this.times[this.times.length - 1];
|
|
108
|
+
}
|
|
109
|
+
get frame() {
|
|
110
|
+
return this.cur;
|
|
111
|
+
}
|
|
112
|
+
get frameCount() {
|
|
113
|
+
return this.anim.frames.length;
|
|
114
|
+
}
|
|
115
|
+
renderLocal(ms) {
|
|
116
|
+
const t = Math.min(ms, this.duration - 0.001);
|
|
117
|
+
let lo = 0, hi = this.anim.frames.length - 1;
|
|
118
|
+
while (lo < hi) {
|
|
119
|
+
const mid = (lo + hi + 1) >> 1;
|
|
120
|
+
if (this.times[mid] <= t)
|
|
121
|
+
lo = mid;
|
|
122
|
+
else
|
|
123
|
+
hi = mid - 1;
|
|
124
|
+
}
|
|
125
|
+
this.show(lo);
|
|
126
|
+
}
|
|
127
|
+
show(i) {
|
|
128
|
+
if (i === this.cur || !this.ctx)
|
|
129
|
+
return;
|
|
130
|
+
this.cur = i;
|
|
131
|
+
const f = this.anim.frames[i];
|
|
132
|
+
if (!f)
|
|
133
|
+
return;
|
|
134
|
+
let d = this.datas[i];
|
|
135
|
+
if (!d && typeof ImageData === 'function')
|
|
136
|
+
d = this.datas[i] = new ImageData(new Uint8ClampedArray(f.image.data), f.image.width, f.image.height);
|
|
137
|
+
if (d)
|
|
138
|
+
this.ctx.putImageData(d, 0, 0);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** Play a decoded animation on a canvas as a runtime timeline (seek / reverse / `progress` scrub). */
|
|
142
|
+
function animatedImagePlayer(canvas, anim, o = {}) {
|
|
143
|
+
if (!anim.frames.length)
|
|
144
|
+
throw new Error('[motionary] animatedImagePlayer: the animation has no frames');
|
|
145
|
+
return new AnimImagePlayer(canvas, anim, o);
|
|
146
|
+
}
|
|
147
|
+
/** A plain Uint8Array view (Node Buffers' `slice()` shares memory — normalise them away). */
|
|
148
|
+
const u8 = (x) => (x instanceof ArrayBuffer ? new Uint8Array(x) : new Uint8Array(x.buffer, x.byteOffset, x.byteLength));
|
|
149
|
+
/** CRC-32 (PNG chunks). */
|
|
150
|
+
let CRC = null;
|
|
151
|
+
function crc32(bytes, start = 0, end = bytes.length) {
|
|
152
|
+
if (!CRC) {
|
|
153
|
+
CRC = new Uint32Array(256);
|
|
154
|
+
for (let n = 0; n < 256; n++) {
|
|
155
|
+
let c = n;
|
|
156
|
+
for (let k = 0; k < 8; k++)
|
|
157
|
+
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
158
|
+
CRC[n] = c >>> 0;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
let c = 0xffffffff;
|
|
162
|
+
for (let i = start; i < end; i++)
|
|
163
|
+
c = CRC[(c ^ bytes[i]) & 0xff] ^ (c >>> 8);
|
|
164
|
+
return (c ^ 0xffffffff) >>> 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
exports.animatedImagePlayer = animatedImagePlayer;
|
|
168
|
+
exports.browserDecode = browserDecode;
|
|
169
|
+
exports.bytesOf = bytesOf;
|
|
170
|
+
exports.composeFrames = composeFrames;
|
|
171
|
+
exports.crc32 = crc32;
|
|
172
|
+
exports.fixDelay = fixDelay;
|
|
173
|
+
exports.u8 = u8;
|
|
174
|
+
//# sourceMappingURL=anim-image-blQgPFFS.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anim-image-blQgPFFS.cjs","sources":["../../src/runtime/anim-image.ts"],"sourcesContent":["/**\n * Shared internals of the animated-image loaders (`format-gif`, `format-apng`,\n * `format-webp`, 10.4): the decoded-animation shape, frame compositing in\n * plain RGBA arrays (no DOM — works in workers and on the server), the\n * browser image decoder used for APNG / WebP frames, and the canvas player\n * (a runtime `Playable`, so it can be paused, reversed, scrubbed and driven\n * by a scroll scene). Bundled into each loader; not a public module.\n */\nimport { Playable } from './tween';\n\n/** An RGBA bitmap (the shape of `ImageData`, without needing the DOM). */\nexport interface Rgba {\n width: number;\n height: number;\n data: Uint8ClampedArray;\n}\n\n/** One frame of an animation, already composited to the full canvas size. */\nexport interface AnimFrame {\n /** Display time, ms. */\n delay: number;\n image: Rgba;\n}\n\nexport interface AnimatedImage {\n format: 'gif' | 'apng' | 'webp';\n width: number;\n height: number;\n /** Number of plays: 0 = forever, 1 = once, … */\n plays: number;\n frames: AnimFrame[];\n}\n\n/** A frame region before compositing (APNG fcTL / WebP ANMF / GIF descriptor). */\nexport interface FramePart {\n x: number;\n y: number;\n image: Rgba;\n delay: number;\n /** 'over' alpha-blends onto the canvas, 'source' replaces the region. */\n blend: 'over' | 'source';\n /** What happens to the region after the frame is shown. */\n dispose: 'none' | 'background' | 'previous';\n}\n\n/** Browsers clamp tiny delays (0–10 ms) to 100 ms; we do the same. */\nexport const fixDelay = (ms: number): number => (ms <= 10 ? 100 : ms);\n\n/** Composite frame parts onto a `width × height` canvas (pure; RGBA in, RGBA out). */\nexport function composeFrames(width: number, height: number, parts: FramePart[], background?: [number, number, number, number]): AnimFrame[] {\n const canvas = new Uint8ClampedArray(width * height * 4);\n const out: AnimFrame[] = [];\n for (const p of parts) {\n const before = p.dispose === 'previous' ? canvas.slice() : null;\n const { width: w, height: h, data } = p.image;\n for (let y = 0; y < h; y++) {\n const cy = p.y + y;\n if (cy < 0 || cy >= height) continue;\n for (let x = 0; x < w; x++) {\n const cx = p.x + x;\n if (cx < 0 || cx >= width) continue;\n const s = (y * w + x) * 4, d = (cy * width + cx) * 4;\n const a = data[s + 3];\n if (p.blend === 'source' || a === 255) {\n canvas[d] = data[s]; canvas[d + 1] = data[s + 1]; canvas[d + 2] = data[s + 2]; canvas[d + 3] = a;\n } else if (a) {\n // straight-alpha \"over\"\n const da = canvas[d + 3] / 255, sa = a / 255, oa = sa + da * (1 - sa);\n for (let c = 0; c < 3; c++) canvas[d + c] = (data[s + c] * sa + canvas[d + c] * da * (1 - sa)) / oa;\n canvas[d + 3] = oa * 255;\n }\n }\n }\n out.push({ delay: p.delay, image: { width, height, data: canvas.slice() } });\n if (p.dispose === 'background') {\n for (let y = Math.max(0, p.y); y < Math.min(height, p.y + h); y++)\n for (let x = Math.max(0, p.x); x < Math.min(width, p.x + w); x++) canvas.set(background || [0, 0, 0, 0], (y * width + x) * 4);\n } else if (before) canvas.set(before);\n }\n return out;\n}\n\n/** Image decoder for one frame file (PNG / WebP bytes) → RGBA. Replaceable (workers, tests, servers). */\nexport type FrameDecoder = (bytes: Uint8Array, mime: string) => Promise<Rgba>;\n\n/** Default decoder: the browser's own (`createImageBitmap` + a 2D canvas; OffscreenCanvas in workers). */\nexport const browserDecode: FrameDecoder = async (bytes, mime) => {\n const g = globalThis as any;\n if (typeof g.createImageBitmap !== 'function') throw new Error('[motionary] no image decoder here (createImageBitmap is missing) — pass { decode } to the loader');\n const bmp = await g.createImageBitmap(new Blob([bytes as BlobPart], { type: mime }));\n const w = bmp.width, h = bmp.height; // read before close(): a closed ImageBitmap reports 0 × 0\n const c = typeof g.OffscreenCanvas === 'function' ? new g.OffscreenCanvas(w, h) : Object.assign(document.createElement('canvas'), { width: w, height: h });\n const ctx = c.getContext('2d', { willReadFrequently: true });\n ctx.drawImage(bmp, 0, 0);\n bmp.close?.();\n const id = ctx.getImageData(0, 0, w, h);\n return { width: id.width, height: id.height, data: id.data };\n};\n\n/** Read a `src` (URL, ArrayBuffer, typed array or Blob) into bytes. */\nexport async function bytesOf(src: string | ArrayBuffer | ArrayBufferView | Blob): Promise<Uint8Array> {\n if (typeof src === 'string') {\n const r = await fetch(src);\n if (!r.ok) throw new Error(`[motionary] could not load ${src} (${r.status})`);\n return new Uint8Array(await r.arrayBuffer());\n }\n if (src instanceof ArrayBuffer) return new Uint8Array(src);\n if (ArrayBuffer.isView(src)) return new Uint8Array(src.buffer, src.byteOffset, src.byteLength);\n return new Uint8Array(await (src as Blob).arrayBuffer());\n}\n\nexport interface AnimPlayerOptions {\n /** Extra repeats; default from the file (`plays`: 0 → forever). */\n repeat?: number;\n yoyo?: boolean;\n paused?: boolean;\n /** Playback speed (default 1). */\n speed?: number;\n}\n\nexport type AnimPlayer = Playable & { readonly frame: number; readonly frameCount: number };\n\nclass AnimImagePlayer extends Playable {\n private times: number[] = [0];\n private cur = -1;\n private ctx: CanvasRenderingContext2D | null;\n private datas: (ImageData | null)[];\n constructor(private canvas: HTMLCanvasElement | OffscreenCanvas, private anim: AnimatedImage, o: AnimPlayerOptions) {\n super({ repeat: o.repeat ?? (anim.plays === 0 ? -1 : Math.max(0, anim.plays - 1)), yoyo: o.yoyo });\n this.timeScale = o.speed || 1;\n for (const f of anim.frames) this.times.push(this.times[this.times.length - 1] + f.delay);\n if (canvas.width !== anim.width) canvas.width = anim.width;\n if (canvas.height !== anim.height) canvas.height = anim.height;\n this.ctx = canvas.getContext('2d') as CanvasRenderingContext2D | null;\n this.datas = anim.frames.map(() => null);\n this.show(0);\n if (!o.paused) this.play();\n }\n get duration(): number {\n return this.times[this.times.length - 1];\n }\n get frame(): number {\n return this.cur;\n }\n get frameCount(): number {\n return this.anim.frames.length;\n }\n protected renderLocal(ms: number): void {\n const t = Math.min(ms, this.duration - 0.001);\n let lo = 0, hi = this.anim.frames.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (this.times[mid] <= t) lo = mid;\n else hi = mid - 1;\n }\n this.show(lo);\n }\n private show(i: number): void {\n if (i === this.cur || !this.ctx) return;\n this.cur = i;\n const f = this.anim.frames[i];\n if (!f) return;\n let d = this.datas[i];\n if (!d && typeof ImageData === 'function') d = this.datas[i] = new ImageData(new Uint8ClampedArray(f.image.data), f.image.width, f.image.height);\n if (d) this.ctx.putImageData(d, 0, 0);\n }\n}\n\n/** Play a decoded animation on a canvas as a runtime timeline (seek / reverse / `progress` scrub). */\nexport function animatedImagePlayer(canvas: HTMLCanvasElement | OffscreenCanvas, anim: AnimatedImage, o: AnimPlayerOptions = {}): AnimPlayer {\n if (!anim.frames.length) throw new Error('[motionary] animatedImagePlayer: the animation has no frames');\n return new AnimImagePlayer(canvas, anim, o);\n}\n\n/** A plain Uint8Array view (Node Buffers' `slice()` shares memory — normalise them away). */\nexport const u8 = (x: Uint8Array | ArrayBuffer): Uint8Array => (x instanceof ArrayBuffer ? new Uint8Array(x) : new Uint8Array(x.buffer, x.byteOffset, x.byteLength));\n\n/** CRC-32 (PNG chunks). */\nlet CRC: Uint32Array | null = null;\nexport function crc32(bytes: Uint8Array, start = 0, end = bytes.length): number {\n if (!CRC) {\n CRC = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n CRC[n] = c >>> 0;\n }\n }\n let c = 0xffffffff;\n for (let i = start; i < end; i++) c = CRC[(c ^ bytes[i]) & 0xff] ^ (c >>> 8);\n return (c ^ 0xffffffff) >>> 0;\n}\n"],"names":["Playable"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-BpU-A1m1.cjs","sources":["../../src/components/effects/audio.ts"],"sourcesContent":["/**\n * 5.6 — sound-reactive effects (Web Audio).\n *\n * - `enableAudio(input)` — start analysing the microphone (`'mic'`), an\n * `<audio>` / `<video>` element (or a selector for one) or a `MediaStream`.\n * Browsers only allow an `AudioContext` to start inside a user gesture, so\n * call it from a click handler (or use `<usa-audio>`, which renders the\n * toggle button for you).\n * - Background effects (kind `background`, Canvas 2D through\n * `canvasBackground()`): `spectrum-bars`, `pulse-ring`, `wave-ring`. Before\n * audio is enabled they idle gently.\n * - Beat detection: `createBeatDetector()` (pure: energy → beat?), `onBeat(cb)`\n * and `bindBeat(el, effect, options)`, which plays any registered effect on\n * every beat. `<usa-audio>` does the same for `[data-usa-beat=\"effect\"]`\n * children and emits `usa-beat`.\n * - While audio runs, `--usa-audio-level` and `--usa-audio-bass` (0–1) are set\n * on `<html>` for CSS-driven reactions.\n *\n * Reduced motion: the visual effects are skipped, beats play no effects and\n * the CSS variables stay at 0 — audio itself keeps playing.\n */\nimport type { EffectDefinition } from '../fx/registry';\nimport { playEffect } from '../fx/registry';\nimport { defineElement, prefersReducedMotion, type UsaElement } from '../base';\nimport { canvasBackground, hexRgb, type GenerativeSpec } from './generative';\nimport { PALETTE } from './shared';\n\nexport type AudioInput = 'mic' | HTMLMediaElement | MediaStream | string;\n\nexport interface AudioSample {\n /** Overall loudness (RMS of the waveform), 0–1. */\n level: number;\n /** Low-frequency energy (first ~8 % of the spectrum), 0–1. */\n bass: number;\n /** Frequency bins, 0–255 each. */\n freq: Uint8Array;\n /** Time-domain waveform, 0–255 (128 = silence). */\n wave: Uint8Array;\n}\n\nexport interface AudioReactive {\n readonly context: AudioContext;\n readonly analyser: AnalyserNode;\n /** Read the analyser now. */\n sample(): AudioSample;\n /** Stop analysing (media keeps playing; the microphone is released). */\n stop(): void;\n}\n\nexport interface BeatOptions {\n /** A beat is energy above `threshold` × the recent average (default 1.35). */\n threshold?: number;\n /** Minimum ms between beats (default 250). */\n cooldown?: number;\n /** Frames of history for the average (default 43 ≈ 0.7 s). */\n history?: number;\n /** Ignore energy below this floor, 0–1 (default 0.08). */\n floor?: number;\n}\n\nlet actx: AudioContext | null = null;\nlet current: AudioReactive | null = null;\nconst mediaSources = new WeakMap<HTMLMediaElement, MediaElementAudioSourceNode>();\n\n/** The running analyser, if `enableAudio()` was called. */\nexport const getAudio = (): AudioReactive | null => current;\n\nfunction audioContext(): AudioContext {\n const AC = (globalThis as any).AudioContext || (globalThis as any).webkitAudioContext;\n if (!AC) throw new Error('[motionary] Web Audio is not available');\n if (!actx || actx.state === 'closed') actx = new AC() as AudioContext;\n return actx;\n}\n\n/**\n * Start analysing `input` and make it the source of every sound-reactive\n * effect. Call from a user gesture. Replaces a previous source.\n */\nexport async function enableAudio(input: AudioInput = 'mic', opts: { fftSize?: number; smoothing?: number } = {}): Promise<AudioReactive> {\n current?.stop();\n const ac = audioContext();\n if (ac.state === 'suspended') await ac.resume().catch(() => undefined);\n const analyser = ac.createAnalyser();\n analyser.fftSize = opts.fftSize || 512;\n analyser.smoothingTimeConstant = opts.smoothing ?? 0.8;\n let src: AudioNode;\n let release = () => {};\n const media = typeof input === 'string' && input !== 'mic' ? document.querySelector<HTMLMediaElement>(input) : input;\n if (media === 'mic') {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n src = ac.createMediaStreamSource(stream);\n src.connect(analyser); // never to the speakers: no feedback\n release = () => stream.getTracks().forEach((t) => t.stop());\n } else if (media && typeof (media as HTMLMediaElement).play === 'function') {\n const m = media as HTMLMediaElement;\n let node = mediaSources.get(m);\n if (!node) mediaSources.set(m, (node = ac.createMediaElementSource(m)));\n try {\n node.disconnect();\n } catch {\n /* not connected */\n }\n src = node;\n src.connect(analyser);\n analyser.connect(ac.destination);\n release = () => {\n try {\n node!.disconnect();\n } catch {\n /* already */\n }\n node!.connect(ac.destination); // keep the media audible\n };\n if (m.paused) await m.play()?.catch?.(() => undefined);\n } else if (media && typeof (media as MediaStream).getTracks === 'function') {\n src = ac.createMediaStreamSource(media as MediaStream);\n src.connect(analyser);\n } else throw new Error(`[motionary] enableAudio: no audio source for ${String(input)}`);\n const freq = new Uint8Array(analyser.frequencyBinCount);\n const wave = new Uint8Array(analyser.fftSize);\n const self: AudioReactive = {\n context: ac,\n analyser,\n sample: () => {\n analyser.getByteFrequencyData(freq);\n analyser.getByteTimeDomainData(wave);\n let sq = 0;\n for (let i = 0; i < wave.length; i++) sq += ((wave[i] - 128) / 128) ** 2;\n const n = Math.max(1, Math.round(freq.length * 0.08));\n let b = 0;\n for (let i = 0; i < n; i++) b += freq[i];\n return { level: Math.min(1, Math.sqrt(sq / wave.length) * 2), bass: b / n / 255, freq, wave };\n },\n stop: () => {\n if (current === self) {\n current = null;\n if (raf && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(raf);\n raf = 0;\n }\n try {\n src.disconnect();\n analyser.disconnect();\n } catch {\n /* already */\n }\n release();\n setVars(0, 0);\n },\n };\n current = self;\n kick();\n return self;\n}\n\n/** Stop the current audio source (if any). */\nexport function disableAudio(): void {\n current?.stop();\n}\n\n/** A pure beat detector: feed it energy (0–1) and a timestamp per frame; it answers \"beat?\". */\nexport function createBeatDetector(o: BeatOptions = {}): (energy: number, now: number) => boolean {\n const { threshold = 1.35, cooldown = 250, history = 43, floor = 0.08 } = o;\n const hist: number[] = [];\n let last = -Infinity;\n return (energy, now) => {\n const avg = hist.length ? hist.reduce((a, b) => a + b, 0) / hist.length : energy;\n const ready = hist.length >= 8;\n hist.push(energy);\n if (hist.length > history) hist.shift();\n if (ready && energy > floor && energy > avg * threshold && now - last >= cooldown) {\n last = now;\n return true;\n }\n return false;\n };\n}\n\ntype BeatListener = { detect: (e: number, t: number) => boolean; cb: (detail: { energy: number; time: number }) => void };\nconst listeners = new Set<BeatListener>();\nlet raf = 0;\n\nfunction setVars(level: number, bass: number): void {\n if (typeof document === 'undefined') return;\n const s = document.documentElement.style;\n s.setProperty('--usa-audio-level', level.toFixed(3));\n s.setProperty('--usa-audio-bass', bass.toFixed(3));\n}\n\nfunction loop(now: number): void {\n raf = 0;\n if (!current) return;\n const { level, bass } = current.sample();\n const reduced = prefersReducedMotion();\n setVars(reduced ? 0 : level, reduced ? 0 : bass);\n for (const l of Array.from(listeners)) if (l.detect(bass, now)) l.cb({ energy: bass, time: now });\n kick();\n}\n\nfunction kick(): void {\n if (!raf && current && typeof requestAnimationFrame === 'function') raf = requestAnimationFrame(loop);\n}\n\n/** Call `cb` on every detected beat of the current audio source. Returns an unsubscribe. */\nexport function onBeat(cb: (detail: { energy: number; time: number }) => void, o: BeatOptions = {}): () => void {\n const l: BeatListener = { detect: createBeatDetector(o), cb };\n listeners.add(l);\n kick();\n return () => void listeners.delete(l);\n}\n\n/** Play the registered effect `name` on `el` at every beat (not under reduced motion). Returns an unbind. */\nexport function bindBeat(el: HTMLElement, name: string, options: Record<string, unknown> & BeatOptions = {}): () => void {\n const { threshold, cooldown, history, floor, ...fx } = options;\n return onBeat(() => {\n if (!prefersReducedMotion()) playEffect(el, name, fx).catch(() => undefined);\n }, { threshold, cooldown, history, floor } as BeatOptions);\n}\n\n// --- visual effects ----------------------------------------------------------\n\n/** The current sample, or a gentle synthetic one while no audio is enabled. */\nfunction read(t: number, bins: number): AudioSample & { idle: boolean } {\n if (current) return { ...current.sample(), idle: false };\n const freq = new Uint8Array(bins);\n const wave = new Uint8Array(bins * 2);\n for (let i = 0; i < bins; i++) freq[i] = 70 + 50 * Math.sin(t * 2 + i * 0.35) * Math.cos(t * 0.7 + i * 0.11) * (1 - i / bins);\n for (let i = 0; i < wave.length; i++) wave[i] = 128 + 22 * Math.sin(t * 3 + i * 0.12);\n return { level: 0.25 + 0.1 * Math.sin(t * 2), bass: 0.35 + 0.2 * Math.sin(t * 2.4), freq, wave, idle: true };\n}\n\nconst audioFx = (name: string, description: string, defaults: Record<string, unknown>, spec: GenerativeSpec): EffectDefinition => ({\n name,\n kind: 'background',\n description,\n reduced: 'skip',\n defaults: { colors: PALETTE, background: '#0b0d12', speed: 1, quality: 1, ...defaults },\n run: (el, o: any, ctx) => canvasBackground(el, ctx, spec, o),\n});\n\nexport const AUDIO_FX: EffectDefinition[] = [\n audioFx('spectrum-bars', 'Frequency bars dance to the audio (mirror them with `mirror: true`).', { bars: 48, gap: 2, mirror: false }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, o.bars);\n const per = Math.max(1, Math.floor((s.freq.length * 0.7) / o.bars));\n const bw = w / o.bars;\n for (let i = 0; i < o.bars; i++) {\n let v = 0;\n for (let k = 0; k < per; k++) v += s.freq[Math.min(s.freq.length - 1, i * per + k)];\n const bh = (v / per / 255) * h * (o.mirror ? 0.5 : 0.9);\n ctx.fillStyle = o.colors[i % o.colors.length];\n ctx.fillRect(i * bw + o.gap / 2, o.mirror ? h / 2 - bh : h - bh, Math.max(1, bw - o.gap), o.mirror ? bh * 2 : bh);\n }\n },\n }),\n audioFx('pulse-ring', 'Glowing rings pulse with the bass.', { rings: 3, color: '#7c5cff' }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, 32);\n const [r, g, b] = hexRgb(o.color);\n const base = Math.min(w, h) * 0.18;\n for (let i = 0; i < o.rings; i++) {\n const rad = base * (1 + i * 0.55) * (1 + s.bass * 0.6);\n ctx.strokeStyle = `rgba(${r},${g},${b},${(0.9 - i * 0.25) * (0.4 + s.level)})`;\n ctx.lineWidth = 3 + s.bass * 10 - i;\n ctx.beginPath();\n ctx.arc(w / 2, h / 2, rad, 0, Math.PI * 2);\n ctx.stroke();\n }\n },\n }),\n audioFx('wave-ring', 'The live waveform wrapped into a circle.', { color: '#22d3ee', amplitude: 0.35 }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, 64);\n const n = s.wave.length;\n const base = Math.min(w, h) * 0.28;\n ctx.strokeStyle = o.color;\n ctx.lineWidth = 2;\n ctx.beginPath();\n for (let i = 0; i <= n; i++) {\n const a = (i / n) * Math.PI * 2;\n const rad = base * (1 + ((s.wave[i % n] - 128) / 128) * o.amplitude * 2);\n const x = w / 2 + Math.cos(a) * rad;\n const y = h / 2 + Math.sin(a) * rad;\n if (i) ctx.lineTo(x, y);\n else ctx.moveTo(x, y);\n }\n ctx.closePath();\n ctx.stroke();\n },\n }),\n];\n\n// --- <usa-audio> -----------------------------------------------------------\n\nexport interface UsaAudioElement extends UsaElement {\n /** `true` while this element's audio source is being analysed. */\n readonly active: boolean;\n /** Start (from a user gesture) or stop analysing. */\n toggle(): Promise<void>;\n}\n\n/**\n * `<usa-audio source=\"#track | mic\" label=\"…\">` — a toggle button (yours, as\n * `[data-audio-toggle]`, or one it renders) that enables the audio source on\n * click; children with `data-usa-beat=\"effect\"` play that effect on every\n * beat (`data-usa-beat-options` JSON; `threshold` / `cooldown` attributes).\n * Emits `usa-beat` and `usa-audio-error`.\n */\nexport function defineAudio(tag = 'usa-audio'): CustomElementConstructor | undefined {\n return defineElement(\n tag,\n (Base) =>\n class UsaAudio extends Base {\n static get observedAttributes(): string[] {\n return ['source'];\n }\n active = false;\n private audio: AudioReactive | null = null;\n private off: (() => void) | null = null;\n private button(): HTMLButtonElement {\n let b = this.querySelector<HTMLButtonElement>('[data-audio-toggle]');\n if (!b) {\n b = document.createElement('button');\n b.type = 'button';\n b.setAttribute('data-audio-toggle', '');\n b.textContent = this.str('label', '🔊 Enable sound-reactive effects');\n this.prepend(b);\n this.onCleanup(() => b!.remove());\n }\n return b;\n }\n async toggle(): Promise<void> {\n const b = this.button();\n if (this.active) return this.stop();\n try {\n this.audio = await enableAudio(this.str('source', 'mic'));\n this.active = true;\n this.removeAttribute('data-audio-error');\n b.setAttribute('aria-pressed', 'true');\n this.off = onBeat((d) => {\n this.dispatchEvent(new CustomEvent('usa-beat', { detail: d, bubbles: true }));\n if (prefersReducedMotion()) return;\n this.querySelectorAll<HTMLElement>('[data-usa-beat]').forEach((el) => {\n let opts = {};\n try {\n opts = JSON.parse(el.dataset.usaBeatOptions || '{}') || {};\n } catch {\n /* ignore bad JSON */\n }\n playEffect(el, el.dataset.usaBeat || 'pulse', opts).catch(() => undefined);\n });\n }, { threshold: this.num('threshold', 1.35), cooldown: this.num('cooldown', 250) });\n } catch (err) {\n this.setAttribute('data-audio-error', '');\n this.dispatchEvent(new CustomEvent('usa-audio-error', { detail: { error: err }, bubbles: true }));\n }\n }\n private stop(): void {\n this.off?.();\n this.off = null;\n if (this.audio && current === this.audio) this.audio.stop();\n this.audio = null;\n this.active = false;\n this.querySelector('[data-audio-toggle]')?.setAttribute('aria-pressed', 'false');\n }\n mount(): void {\n const b = this.button();\n b.setAttribute('aria-pressed', 'false');\n this.listen(b, 'click', () => void this.toggle());\n this.onCleanup(() => this.stop());\n }\n },\n { id: 'usa-audio', text: 'usa-audio{display:block}usa-audio[data-audio-error] [data-audio-toggle]{outline:2px solid #ff5c8a}' }\n );\n}\n"],"names":["prefersReducedMotion","playEffect","PALETTE","canvasBackground","hexRgb","defineElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"audio-BpU-A1m1.cjs","sources":["../../src/components/effects/audio.ts"],"sourcesContent":["/**\n * 5.6 — sound-reactive effects (Web Audio).\n *\n * - `enableAudio(input)` — start analysing the microphone (`'mic'`), an\n * `<audio>` / `<video>` element (or a selector for one) or a `MediaStream`.\n * Browsers only allow an `AudioContext` to start inside a user gesture, so\n * call it from a click handler (or use `<usa-audio>`, which renders the\n * toggle button for you).\n * - Background effects (kind `background`, Canvas 2D through\n * `canvasBackground()`): `spectrum-bars`, `pulse-ring`, `wave-ring`. Before\n * audio is enabled they idle gently.\n * - Beat detection: `createBeatDetector()` (pure: energy → beat?), `onBeat(cb)`\n * and `bindBeat(el, effect, options)`, which plays any registered effect on\n * every beat. `<usa-audio>` does the same for `[data-usa-beat=\"effect\"]`\n * children and emits `usa-beat`.\n * - While audio runs, `--usa-audio-level` and `--usa-audio-bass` (0–1) are set\n * on `<html>` for CSS-driven reactions.\n *\n * Reduced motion: the visual effects are skipped, beats play no effects and\n * the CSS variables stay at 0 — audio itself keeps playing.\n */\nimport type { EffectDefinition } from '../fx/registry';\nimport { playEffect } from '../fx/registry';\nimport { defineElement, prefersReducedMotion, type UsaElement } from '../base';\nimport { canvasBackground, hexRgb, type GenerativeSpec } from './generative';\nimport { PALETTE } from './shared';\n\nexport type AudioInput = 'mic' | HTMLMediaElement | MediaStream | string;\n\nexport interface AudioSample {\n /** Overall loudness (RMS of the waveform), 0–1. */\n level: number;\n /** Low-frequency energy (first ~8 % of the spectrum), 0–1. */\n bass: number;\n /** Frequency bins, 0–255 each. */\n freq: Uint8Array;\n /** Time-domain waveform, 0–255 (128 = silence). */\n wave: Uint8Array;\n}\n\nexport interface AudioReactive {\n readonly context: AudioContext;\n readonly analyser: AnalyserNode;\n /** Read the analyser now. */\n sample(): AudioSample;\n /** Stop analysing (media keeps playing; the microphone is released). */\n stop(): void;\n}\n\nexport interface BeatOptions {\n /** A beat is energy above `threshold` × the recent average (default 1.35). */\n threshold?: number;\n /** Minimum ms between beats (default 250). */\n cooldown?: number;\n /** Frames of history for the average (default 43 ≈ 0.7 s). */\n history?: number;\n /** Ignore energy below this floor, 0–1 (default 0.08). */\n floor?: number;\n}\n\nlet actx: AudioContext | null = null;\nlet current: AudioReactive | null = null;\nconst mediaSources = new WeakMap<HTMLMediaElement, MediaElementAudioSourceNode>();\n\n/** The running analyser, if `enableAudio()` was called. */\nexport const getAudio = (): AudioReactive | null => current;\n\nfunction audioContext(): AudioContext {\n const AC = (globalThis as any).AudioContext || (globalThis as any).webkitAudioContext;\n if (!AC) throw new Error('[motionary] Web Audio is not available');\n if (!actx || actx.state === 'closed') actx = new AC() as AudioContext;\n return actx;\n}\n\n/**\n * Start analysing `input` and make it the source of every sound-reactive\n * effect. Call from a user gesture. Replaces a previous source.\n */\nexport async function enableAudio(input: AudioInput = 'mic', opts: { fftSize?: number; smoothing?: number } = {}): Promise<AudioReactive> {\n current?.stop();\n const ac = audioContext();\n if (ac.state === 'suspended') await ac.resume().catch(() => undefined);\n const analyser = ac.createAnalyser();\n analyser.fftSize = opts.fftSize || 512;\n analyser.smoothingTimeConstant = opts.smoothing ?? 0.8;\n let src: AudioNode;\n let release = () => {};\n const media = typeof input === 'string' && input !== 'mic' ? document.querySelector<HTMLMediaElement>(input) : input;\n if (media === 'mic') {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n src = ac.createMediaStreamSource(stream);\n src.connect(analyser); // never to the speakers: no feedback\n release = () => stream.getTracks().forEach((t) => t.stop());\n } else if (media && typeof (media as HTMLMediaElement).play === 'function') {\n const m = media as HTMLMediaElement;\n let node = mediaSources.get(m);\n if (!node) mediaSources.set(m, (node = ac.createMediaElementSource(m)));\n try {\n node.disconnect();\n } catch {\n /* not connected */\n }\n src = node;\n src.connect(analyser);\n analyser.connect(ac.destination);\n release = () => {\n try {\n node!.disconnect();\n } catch {\n /* already */\n }\n node!.connect(ac.destination); // keep the media audible\n };\n if (m.paused) await m.play()?.catch?.(() => undefined);\n } else if (media && typeof (media as MediaStream).getTracks === 'function') {\n src = ac.createMediaStreamSource(media as MediaStream);\n src.connect(analyser);\n } else throw new Error(`[motionary] enableAudio: no audio source for ${String(input)}`);\n const freq = new Uint8Array(analyser.frequencyBinCount);\n const wave = new Uint8Array(analyser.fftSize);\n const self: AudioReactive = {\n context: ac,\n analyser,\n sample: () => {\n analyser.getByteFrequencyData(freq);\n analyser.getByteTimeDomainData(wave);\n let sq = 0;\n for (let i = 0; i < wave.length; i++) sq += ((wave[i] - 128) / 128) ** 2;\n const n = Math.max(1, Math.round(freq.length * 0.08));\n let b = 0;\n for (let i = 0; i < n; i++) b += freq[i];\n return { level: Math.min(1, Math.sqrt(sq / wave.length) * 2), bass: b / n / 255, freq, wave };\n },\n stop: () => {\n if (current === self) {\n current = null;\n if (raf && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(raf);\n raf = 0;\n }\n try {\n src.disconnect();\n analyser.disconnect();\n } catch {\n /* already */\n }\n release();\n setVars(0, 0);\n },\n };\n current = self;\n kick();\n return self;\n}\n\n/** Stop the current audio source (if any). */\nexport function disableAudio(): void {\n current?.stop();\n}\n\n/** A pure beat detector: feed it energy (0–1) and a timestamp per frame; it answers \"beat?\". */\nexport function createBeatDetector(o: BeatOptions = {}): (energy: number, now: number) => boolean {\n const { threshold = 1.35, cooldown = 250, history = 43, floor = 0.08 } = o;\n const hist: number[] = [];\n let last = -Infinity;\n return (energy, now) => {\n const avg = hist.length ? hist.reduce((a, b) => a + b, 0) / hist.length : energy;\n const ready = hist.length >= 8;\n hist.push(energy);\n if (hist.length > history) hist.shift();\n if (ready && energy > floor && energy > avg * threshold && now - last >= cooldown) {\n last = now;\n return true;\n }\n return false;\n };\n}\n\ntype BeatListener = { detect: (e: number, t: number) => boolean; cb: (detail: { energy: number; time: number }) => void };\nconst listeners = new Set<BeatListener>();\nlet raf = 0;\n\nfunction setVars(level: number, bass: number): void {\n if (typeof document === 'undefined') return;\n const s = document.documentElement.style;\n s.setProperty('--usa-audio-level', level.toFixed(3));\n s.setProperty('--usa-audio-bass', bass.toFixed(3));\n}\n\nfunction loop(now: number): void {\n raf = 0;\n if (!current) return;\n const { level, bass } = current.sample();\n const reduced = prefersReducedMotion();\n setVars(reduced ? 0 : level, reduced ? 0 : bass);\n for (const l of Array.from(listeners)) if (l.detect(bass, now)) l.cb({ energy: bass, time: now });\n kick();\n}\n\nfunction kick(): void {\n if (!raf && current && typeof requestAnimationFrame === 'function') raf = requestAnimationFrame(loop);\n}\n\n/** Call `cb` on every detected beat of the current audio source. Returns an unsubscribe. */\nexport function onBeat(cb: (detail: { energy: number; time: number }) => void, o: BeatOptions = {}): () => void {\n const l: BeatListener = { detect: createBeatDetector(o), cb };\n listeners.add(l);\n kick();\n return () => void listeners.delete(l);\n}\n\n/** Play the registered effect `name` on `el` at every beat (not under reduced motion). Returns an unbind. */\nexport function bindBeat(el: HTMLElement, name: string, options: Record<string, unknown> & BeatOptions = {}): () => void {\n const { threshold, cooldown, history, floor, ...fx } = options;\n return onBeat(() => {\n if (!prefersReducedMotion()) playEffect(el, name, fx).catch(() => undefined);\n }, { threshold, cooldown, history, floor } as BeatOptions);\n}\n\n// --- visual effects ----------------------------------------------------------\n\n/** The current sample, or a gentle synthetic one while no audio is enabled. */\nfunction read(t: number, bins: number): AudioSample & { idle: boolean } {\n if (current) return { ...current.sample(), idle: false };\n const freq = new Uint8Array(bins);\n const wave = new Uint8Array(bins * 2);\n for (let i = 0; i < bins; i++) freq[i] = 70 + 50 * Math.sin(t * 2 + i * 0.35) * Math.cos(t * 0.7 + i * 0.11) * (1 - i / bins);\n for (let i = 0; i < wave.length; i++) wave[i] = 128 + 22 * Math.sin(t * 3 + i * 0.12);\n return { level: 0.25 + 0.1 * Math.sin(t * 2), bass: 0.35 + 0.2 * Math.sin(t * 2.4), freq, wave, idle: true };\n}\n\nconst audioFx = (name: string, description: string, defaults: Record<string, unknown>, spec: GenerativeSpec): EffectDefinition => ({\n name,\n kind: 'background',\n description,\n reduced: 'skip',\n defaults: { colors: PALETTE, background: '#0b0d12', speed: 1, quality: 1, ...defaults },\n run: (el, o: any, ctx) => canvasBackground(el, ctx, spec, o),\n});\n\nexport const AUDIO_FX: EffectDefinition[] = [\n audioFx('spectrum-bars', 'Frequency bars dance to the audio (mirror them with `mirror: true`).', { bars: 48, gap: 2, mirror: false }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, o.bars);\n const per = Math.max(1, Math.floor((s.freq.length * 0.7) / o.bars));\n const bw = w / o.bars;\n for (let i = 0; i < o.bars; i++) {\n let v = 0;\n for (let k = 0; k < per; k++) v += s.freq[Math.min(s.freq.length - 1, i * per + k)];\n const bh = (v / per / 255) * h * (o.mirror ? 0.5 : 0.9);\n ctx.fillStyle = o.colors[i % o.colors.length];\n ctx.fillRect(i * bw + o.gap / 2, o.mirror ? h / 2 - bh : h - bh, Math.max(1, bw - o.gap), o.mirror ? bh * 2 : bh);\n }\n },\n }),\n audioFx('pulse-ring', 'Glowing rings pulse with the bass.', { rings: 3, color: '#7c5cff' }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, 32);\n const [r, g, b] = hexRgb(o.color);\n const base = Math.min(w, h) * 0.18;\n for (let i = 0; i < o.rings; i++) {\n const rad = base * (1 + i * 0.55) * (1 + s.bass * 0.6);\n ctx.strokeStyle = `rgba(${r},${g},${b},${(0.9 - i * 0.25) * (0.4 + s.level)})`;\n ctx.lineWidth = 3 + s.bass * 10 - i;\n ctx.beginPath();\n ctx.arc(w / 2, h / 2, rad, 0, Math.PI * 2);\n ctx.stroke();\n }\n },\n }),\n audioFx('wave-ring', 'The live waveform wrapped into a circle.', { color: '#22d3ee', amplitude: 0.35 }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, 64);\n const n = s.wave.length;\n const base = Math.min(w, h) * 0.28;\n ctx.strokeStyle = o.color;\n ctx.lineWidth = 2;\n ctx.beginPath();\n for (let i = 0; i <= n; i++) {\n const a = (i / n) * Math.PI * 2;\n const rad = base * (1 + ((s.wave[i % n] - 128) / 128) * o.amplitude * 2);\n const x = w / 2 + Math.cos(a) * rad;\n const y = h / 2 + Math.sin(a) * rad;\n if (i) ctx.lineTo(x, y);\n else ctx.moveTo(x, y);\n }\n ctx.closePath();\n ctx.stroke();\n },\n }),\n];\n\n// --- <usa-audio> -----------------------------------------------------------\n\nexport interface UsaAudioElement extends UsaElement {\n /** `true` while this element's audio source is being analysed. */\n readonly active: boolean;\n /** Start (from a user gesture) or stop analysing. */\n toggle(): Promise<void>;\n}\n\n/**\n * `<usa-audio source=\"#track | mic\" label=\"…\">` — a toggle button (yours, as\n * `[data-audio-toggle]`, or one it renders) that enables the audio source on\n * click; children with `data-usa-beat=\"effect\"` play that effect on every\n * beat (`data-usa-beat-options` JSON; `threshold` / `cooldown` attributes).\n * Emits `usa-beat` and `usa-audio-error`.\n */\nexport function defineAudio(tag = 'usa-audio'): CustomElementConstructor | undefined {\n return defineElement(\n tag,\n (Base) =>\n class UsaAudio extends Base {\n static get observedAttributes(): string[] {\n return ['source'];\n }\n active = false;\n private audio: AudioReactive | null = null;\n private off: (() => void) | null = null;\n private button(): HTMLButtonElement {\n let b = this.querySelector<HTMLButtonElement>('[data-audio-toggle]');\n if (!b) {\n b = document.createElement('button');\n b.type = 'button';\n b.setAttribute('data-audio-toggle', '');\n b.textContent = this.str('label', '🔊 Enable sound-reactive effects');\n this.prepend(b);\n this.onCleanup(() => b!.remove());\n }\n return b;\n }\n async toggle(): Promise<void> {\n const b = this.button();\n if (this.active) return this.stop();\n try {\n this.audio = await enableAudio(this.str('source', 'mic'));\n this.active = true;\n this.removeAttribute('data-audio-error');\n b.setAttribute('aria-pressed', 'true');\n this.off = onBeat((d) => {\n this.dispatchEvent(new CustomEvent('usa-beat', { detail: d, bubbles: true }));\n if (prefersReducedMotion()) return;\n this.querySelectorAll<HTMLElement>('[data-usa-beat]').forEach((el) => {\n let opts = {};\n try {\n opts = JSON.parse(el.dataset.usaBeatOptions || '{}') || {};\n } catch {\n /* ignore bad JSON */\n }\n playEffect(el, el.dataset.usaBeat || 'pulse', opts).catch(() => undefined);\n });\n }, { threshold: this.num('threshold', 1.35), cooldown: this.num('cooldown', 250) });\n } catch (err) {\n this.setAttribute('data-audio-error', '');\n this.dispatchEvent(new CustomEvent('usa-audio-error', { detail: { error: err }, bubbles: true }));\n }\n }\n private stop(): void {\n this.off?.();\n this.off = null;\n if (this.audio && current === this.audio) this.audio.stop();\n this.audio = null;\n this.active = false;\n this.querySelector('[data-audio-toggle]')?.setAttribute('aria-pressed', 'false');\n }\n mount(): void {\n const b = this.button();\n b.setAttribute('aria-pressed', 'false');\n this.listen(b, 'click', () => void this.toggle());\n this.onCleanup(() => this.stop());\n }\n },\n { id: 'usa-audio', text: 'usa-audio{display:block}usa-audio[data-audio-error] [data-audio-toggle]{outline:2px solid #ff5c8a}' }\n );\n}\n"],"names":["prefersReducedMotion","playEffect","PALETTE","canvasBackground","hexRgb","defineElement"],"mappings":";;;;;;;AA4DA,IAAI,IAAI,GAAwB,IAAI;AACpC,IAAI,OAAO,GAAyB,IAAI;AACxC,MAAM,YAAY,GAAG,IAAI,OAAO,EAAiD;AAEjF;MACa,QAAQ,GAAG,MAA4B;AAEpD,SAAS,YAAY,GAAA;IACnB,MAAM,EAAE,GAAI,UAAkB,CAAC,YAAY,IAAK,UAAkB,CAAC,kBAAkB;AACrF,IAAA,IAAI,CAAC,EAAE;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC;AAClE,IAAA,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ;AAAE,QAAA,IAAI,GAAG,IAAI,EAAE,EAAkB;AACrE,IAAA,OAAO,IAAI;AACb;AAEA;;;AAGG;AACI,eAAe,WAAW,CAAC,KAAA,GAAoB,KAAK,EAAE,IAAA,GAAiD,EAAE,EAAA;IAC9G,OAAO,EAAE,IAAI,EAAE;AACf,IAAA,MAAM,EAAE,GAAG,YAAY,EAAE;AACzB,IAAA,IAAI,EAAE,CAAC,KAAK,KAAK,WAAW;AAAE,QAAA,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC;AACtE,IAAA,MAAM,QAAQ,GAAG,EAAE,CAAC,cAAc,EAAE;IACpC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,GAAG;IACtC,QAAQ,CAAC,qBAAqB,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG;AACtD,IAAA,IAAI,GAAc;AAClB,IAAA,IAAI,OAAO,GAAG,MAAK,EAAE,CAAC;IACtB,MAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAmB,KAAK,CAAC,GAAG,KAAK;AACpH,IAAA,IAAI,KAAK,KAAK,KAAK,EAAE;AACnB,QAAA,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzE,QAAA,GAAG,GAAG,EAAE,CAAC,uBAAuB,CAAC,MAAM,CAAC;AACxC,QAAA,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtB,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7D;SAAO,IAAI,KAAK,IAAI,OAAQ,KAA0B,CAAC,IAAI,KAAK,UAAU,EAAE;QAC1E,MAAM,CAAC,GAAG,KAAyB;QACnC,IAAI,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;AAC9B,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE;AACvE,QAAA,IAAI;YACF,IAAI,CAAC,UAAU,EAAE;QACnB;AAAE,QAAA,MAAM;;QAER;QACA,GAAG,GAAG,IAAI;AACV,QAAA,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC;AACrB,QAAA,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC;QAChC,OAAO,GAAG,MAAK;AACb,YAAA,IAAI;gBACF,IAAK,CAAC,UAAU,EAAE;YACpB;AAAE,YAAA,MAAM;;YAER;YACA,IAAK,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;AAChC,QAAA,CAAC;QACD,IAAI,CAAC,CAAC,MAAM;AAAE,YAAA,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,GAAG,MAAM,SAAS,CAAC;IACxD;SAAO,IAAI,KAAK,IAAI,OAAQ,KAAqB,CAAC,SAAS,KAAK,UAAU,EAAE;AAC1E,QAAA,GAAG,GAAG,EAAE,CAAC,uBAAuB,CAAC,KAAoB,CAAC;AACtD,QAAA,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC;IACvB;;QAAO,MAAM,IAAI,KAAK,CAAC,CAAA,6CAAA,EAAgD,MAAM,CAAC,KAAK,CAAC,CAAA,CAAE,CAAC;IACvF,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACvD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;AAC7C,IAAA,MAAM,IAAI,GAAkB;AAC1B,QAAA,OAAO,EAAE,EAAE;QACX,QAAQ;QACR,MAAM,EAAE,MAAK;AACX,YAAA,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC;AACnC,YAAA,QAAQ,CAAC,qBAAqB,CAAC,IAAI,CAAC;YACpC,IAAI,EAAE,GAAG,CAAC;AACV,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;AAAE,gBAAA,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC;AACxE,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;YACrD,IAAI,CAAC,GAAG,CAAC;YACT,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;AAAE,gBAAA,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;AACxC,YAAA,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE;QAC/F,CAAC;QACD,IAAI,EAAE,MAAK;AACT,YAAA,IAAI,OAAO,KAAK,IAAI,EAAE;gBACpB,OAAO,GAAG,IAAI;AACd,gBAAA,IAAI,GAAG,IAAI,OAAO,oBAAoB,KAAK,UAAU;oBAAE,oBAAoB,CAAC,GAAG,CAAC;gBAChF,GAAG,GAAG,CAAC;YACT;AACA,YAAA,IAAI;gBACF,GAAG,CAAC,UAAU,EAAE;gBAChB,QAAQ,CAAC,UAAU,EAAE;YACvB;AAAE,YAAA,MAAM;;YAER;AACA,YAAA,OAAO,EAAE;AACT,YAAA,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;QACf,CAAC;KACF;IACD,OAAO,GAAG,IAAI;AACd,IAAA,IAAI,EAAE;AACN,IAAA,OAAO,IAAI;AACb;AAEA;SACgB,YAAY,GAAA;IAC1B,OAAO,EAAE,IAAI,EAAE;AACjB;AAEA;AACM,SAAU,kBAAkB,CAAC,CAAA,GAAiB,EAAE,EAAA;AACpD,IAAA,MAAM,EAAE,SAAS,GAAG,IAAI,EAAE,QAAQ,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC;IAC1E,MAAM,IAAI,GAAa,EAAE;AACzB,IAAA,IAAI,IAAI,GAAG,CAAC,QAAQ;AACpB,IAAA,OAAO,CAAC,MAAM,EAAE,GAAG,KAAI;AACrB,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,MAAM;AAChF,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC;AAC9B,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;AACjB,QAAA,IAAI,IAAI,CAAC,MAAM,GAAG,OAAO;YAAE,IAAI,CAAC,KAAK,EAAE;AACvC,QAAA,IAAI,KAAK,IAAI,MAAM,GAAG,KAAK,IAAI,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,GAAG,GAAG,IAAI,IAAI,QAAQ,EAAE;YACjF,IAAI,GAAG,GAAG;AACV,YAAA,OAAO,IAAI;QACb;AACA,QAAA,OAAO,KAAK;AACd,IAAA,CAAC;AACH;AAGA,MAAM,SAAS,GAAG,IAAI,GAAG,EAAgB;AACzC,IAAI,GAAG,GAAG,CAAC;AAEX,SAAS,OAAO,CAAC,KAAa,EAAE,IAAY,EAAA;IAC1C,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE;AACrC,IAAA,MAAM,CAAC,GAAG,QAAQ,CAAC,eAAe,CAAC,KAAK;AACxC,IAAA,CAAC,CAAC,WAAW,CAAC,mBAAmB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACpD,IAAA,CAAC,CAAC,WAAW,CAAC,kBAAkB,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACpD;AAEA,SAAS,IAAI,CAAC,GAAW,EAAA;IACvB,GAAG,GAAG,CAAC;AACP,IAAA,IAAI,CAAC,OAAO;QAAE;IACd,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE;AACxC,IAAA,MAAM,OAAO,GAAGA,yBAAoB,EAAE;IACtC,OAAO,CAAC,OAAO,GAAG,CAAC,GAAG,KAAK,EAAE,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;AAAE,QAAA,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC;AAAE,YAAA,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACjG,IAAA,IAAI,EAAE;AACR;AAEA,SAAS,IAAI,GAAA;IACX,IAAI,CAAC,GAAG,IAAI,OAAO,IAAI,OAAO,qBAAqB,KAAK,UAAU;AAAE,QAAA,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC;AACvG;AAEA;SACgB,MAAM,CAAC,EAAsD,EAAE,IAAiB,EAAE,EAAA;AAChG,IAAA,MAAM,CAAC,GAAiB,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE;AAC7D,IAAA,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AAChB,IAAA,IAAI,EAAE;IACN,OAAO,MAAM,KAAK,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;AACvC;AAEA;AACM,SAAU,QAAQ,CAAC,EAAe,EAAE,IAAY,EAAE,UAAiD,EAAE,EAAA;AACzG,IAAA,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO;IAC9D,OAAO,MAAM,CAAC,MAAK;QACjB,IAAI,CAACA,yBAAoB,EAAE;AAAE,YAAAC,mBAAU,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC;IAC9E,CAAC,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAiB,CAAC;AAC5D;AAEA;AAEA;AACA,SAAS,IAAI,CAAC,CAAS,EAAE,IAAY,EAAA;AACnC,IAAA,IAAI,OAAO;QAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;AACxD,IAAA,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;AAAE,QAAA,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;AAC7H,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;AACrF,IAAA,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAC9G;AAEA,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,WAAmB,EAAE,QAAiC,EAAE,IAAoB,MAAwB;IACjI,IAAI;AACJ,IAAA,IAAI,EAAE,YAAY;IAClB,WAAW;AACX,IAAA,OAAO,EAAE,MAAM;IACf,QAAQ,EAAE,EAAE,MAAM,EAAEC,cAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,QAAQ,EAAE;AACvF,IAAA,GAAG,EAAE,CAAC,EAAE,EAAE,CAAM,EAAE,GAAG,KAAKC,2BAAgB,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAA,CAAC;AAEK,MAAM,QAAQ,GAAuB;AAC1C,IAAA,OAAO,CAAC,eAAe,EAAE,sEAAsE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;AACpI,QAAA,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAI;AAC5B,YAAA,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,UAAU;YAC5B,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACxB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AACnE,YAAA,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI;AACrB,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;gBAC/B,IAAI,CAAC,GAAG,CAAC;gBACT,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE;oBAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC;gBACnF,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC;AACvD,gBAAA,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;gBAC7C,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YACnH;QACF,CAAC;KACF,CAAC;AACF,IAAA,OAAO,CAAC,YAAY,EAAE,oCAAoC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;AAC1F,QAAA,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAI;AAC5B,YAAA,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,UAAU;YAC5B,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACxB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;AACrB,YAAA,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAGC,iBAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AACjC,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI;AAClC,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;gBAChC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC;gBACtD,GAAG,CAAC,WAAW,GAAG,CAAA,KAAA,EAAQ,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,EAAI,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,KAAK,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA,CAAA,CAAG;AAC9E,gBAAA,GAAG,CAAC,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,GAAG,CAAC;gBACnC,GAAG,CAAC,SAAS,EAAE;gBACf,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;gBAC1C,GAAG,CAAC,MAAM,EAAE;YACd;QACF,CAAC;KACF,CAAC;AACF,IAAA,OAAO,CAAC,WAAW,EAAE,0CAA0C,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;AACtG,QAAA,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAI;AAC5B,YAAA,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,UAAU;YAC5B,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACxB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;AACrB,YAAA,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM;AACvB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI;AAClC,YAAA,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,KAAK;AACzB,YAAA,GAAG,CAAC,SAAS,GAAG,CAAC;YACjB,GAAG,CAAC,SAAS,EAAE;AACf,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;AAC3B,gBAAA,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,EAAE,GAAG,CAAC;AAC/B,gBAAA,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;AACxE,gBAAA,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG;AACnC,gBAAA,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG;AACnC,gBAAA,IAAI,CAAC;AAAE,oBAAA,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;;AAClB,oBAAA,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;YACvB;YACA,GAAG,CAAC,SAAS,EAAE;YACf,GAAG,CAAC,MAAM,EAAE;QACd,CAAC;KACF,CAAC;;AAYJ;;;;;;AAMG;AACG,SAAU,WAAW,CAAC,GAAG,GAAG,WAAW,EAAA;AAC3C,IAAA,OAAOC,kBAAa,CAClB,GAAG,EACH,CAAC,IAAI,KACH,MAAM,QAAS,SAAQ,IAAI,CAAA;AAA3B,QAAA,WAAA,GAAA;;YAIE,IAAA,CAAA,MAAM,GAAG,KAAK;YACN,IAAA,CAAA,KAAK,GAAyB,IAAI;YAClC,IAAA,CAAA,GAAG,GAAwB,IAAI;QAqDzC;AA1DE,QAAA,WAAW,kBAAkB,GAAA;YAC3B,OAAO,CAAC,QAAQ,CAAC;QACnB;QAIQ,MAAM,GAAA;YACZ,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAoB,qBAAqB,CAAC;YACpE,IAAI,CAAC,CAAC,EAAE;AACN,gBAAA,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;AACpC,gBAAA,CAAC,CAAC,IAAI,GAAG,QAAQ;AACjB,gBAAA,CAAC,CAAC,YAAY,CAAC,mBAAmB,EAAE,EAAE,CAAC;gBACvC,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,kCAAkC,CAAC;AACrE,gBAAA,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;gBACf,IAAI,CAAC,SAAS,CAAC,MAAM,CAAE,CAAC,MAAM,EAAE,CAAC;YACnC;AACA,YAAA,OAAO,CAAC;QACV;AACA,QAAA,MAAM,MAAM,GAAA;AACV,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE;YACvB,IAAI,IAAI,CAAC,MAAM;AAAE,gBAAA,OAAO,IAAI,CAAC,IAAI,EAAE;AACnC,YAAA,IAAI;AACF,gBAAA,IAAI,CAAC,KAAK,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AACzD,gBAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,gBAAA,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC;AACxC,gBAAA,CAAC,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC;gBACtC,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,KAAI;AACtB,oBAAA,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7E,oBAAA,IAAIL,yBAAoB,EAAE;wBAAE;oBAC5B,IAAI,CAAC,gBAAgB,CAAc,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,KAAI;wBACnE,IAAI,IAAI,GAAG,EAAE;AACb,wBAAA,IAAI;AACF,4BAAA,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,IAAI,EAAE;wBAC5D;AAAE,wBAAA,MAAM;;wBAER;wBACAC,mBAAU,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC;AAC5E,oBAAA,CAAC,CAAC;gBACJ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC;YACrF;YAAE,OAAO,GAAG,EAAE;AACZ,gBAAA,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,EAAE,CAAC;gBACzC,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,iBAAiB,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACnG;QACF;QACQ,IAAI,GAAA;AACV,YAAA,IAAI,CAAC,GAAG,IAAI;AACZ,YAAA,IAAI,CAAC,GAAG,GAAG,IAAI;YACf,IAAI,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,IAAI,CAAC,KAAK;AAAE,gBAAA,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;AAC3D,YAAA,IAAI,CAAC,KAAK,GAAG,IAAI;AACjB,YAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,YAAA,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,EAAE,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC;QAClF;QACA,KAAK,GAAA;AACH,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE;AACvB,YAAA,CAAC,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC;AACvC,YAAA,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;YACjD,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACnC;KACD,EACH,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,oGAAoG,EAAE,CAChI;AACH;;;;;;;;;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { playEffect } from './registry-
|
|
2
|
-
import {
|
|
1
|
+
import { playEffect } from './registry-BKzyg1JV.js';
|
|
2
|
+
import { f as defineElement, p as prefersReducedMotion } from './base-BTev8qxg.js';
|
|
3
3
|
import { c as canvasBackground, h as hexRgb } from './generative-2LhxG5BJ.js';
|
|
4
4
|
import { P as PALETTE } from './shared-CkKHWrtJ.js';
|
|
5
5
|
|
|
@@ -330,4 +330,4 @@ function defineAudio(tag = 'usa-audio') {
|
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
export { AUDIO_FX as A, disableAudio as a, bindBeat as b, createBeatDetector as c, defineAudio as d, enableAudio as e, getAudio as g, onBeat as o };
|
|
333
|
-
//# sourceMappingURL=audio-
|
|
333
|
+
//# sourceMappingURL=audio-CWt1xdZB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-D95jwlOh.js","sources":["../../src/components/effects/audio.ts"],"sourcesContent":["/**\n * 5.6 — sound-reactive effects (Web Audio).\n *\n * - `enableAudio(input)` — start analysing the microphone (`'mic'`), an\n * `<audio>` / `<video>` element (or a selector for one) or a `MediaStream`.\n * Browsers only allow an `AudioContext` to start inside a user gesture, so\n * call it from a click handler (or use `<usa-audio>`, which renders the\n * toggle button for you).\n * - Background effects (kind `background`, Canvas 2D through\n * `canvasBackground()`): `spectrum-bars`, `pulse-ring`, `wave-ring`. Before\n * audio is enabled they idle gently.\n * - Beat detection: `createBeatDetector()` (pure: energy → beat?), `onBeat(cb)`\n * and `bindBeat(el, effect, options)`, which plays any registered effect on\n * every beat. `<usa-audio>` does the same for `[data-usa-beat=\"effect\"]`\n * children and emits `usa-beat`.\n * - While audio runs, `--usa-audio-level` and `--usa-audio-bass` (0–1) are set\n * on `<html>` for CSS-driven reactions.\n *\n * Reduced motion: the visual effects are skipped, beats play no effects and\n * the CSS variables stay at 0 — audio itself keeps playing.\n */\nimport type { EffectDefinition } from '../fx/registry';\nimport { playEffect } from '../fx/registry';\nimport { defineElement, prefersReducedMotion, type UsaElement } from '../base';\nimport { canvasBackground, hexRgb, type GenerativeSpec } from './generative';\nimport { PALETTE } from './shared';\n\nexport type AudioInput = 'mic' | HTMLMediaElement | MediaStream | string;\n\nexport interface AudioSample {\n /** Overall loudness (RMS of the waveform), 0–1. */\n level: number;\n /** Low-frequency energy (first ~8 % of the spectrum), 0–1. */\n bass: number;\n /** Frequency bins, 0–255 each. */\n freq: Uint8Array;\n /** Time-domain waveform, 0–255 (128 = silence). */\n wave: Uint8Array;\n}\n\nexport interface AudioReactive {\n readonly context: AudioContext;\n readonly analyser: AnalyserNode;\n /** Read the analyser now. */\n sample(): AudioSample;\n /** Stop analysing (media keeps playing; the microphone is released). */\n stop(): void;\n}\n\nexport interface BeatOptions {\n /** A beat is energy above `threshold` × the recent average (default 1.35). */\n threshold?: number;\n /** Minimum ms between beats (default 250). */\n cooldown?: number;\n /** Frames of history for the average (default 43 ≈ 0.7 s). */\n history?: number;\n /** Ignore energy below this floor, 0–1 (default 0.08). */\n floor?: number;\n}\n\nlet actx: AudioContext | null = null;\nlet current: AudioReactive | null = null;\nconst mediaSources = new WeakMap<HTMLMediaElement, MediaElementAudioSourceNode>();\n\n/** The running analyser, if `enableAudio()` was called. */\nexport const getAudio = (): AudioReactive | null => current;\n\nfunction audioContext(): AudioContext {\n const AC = (globalThis as any).AudioContext || (globalThis as any).webkitAudioContext;\n if (!AC) throw new Error('[motionary] Web Audio is not available');\n if (!actx || actx.state === 'closed') actx = new AC() as AudioContext;\n return actx;\n}\n\n/**\n * Start analysing `input` and make it the source of every sound-reactive\n * effect. Call from a user gesture. Replaces a previous source.\n */\nexport async function enableAudio(input: AudioInput = 'mic', opts: { fftSize?: number; smoothing?: number } = {}): Promise<AudioReactive> {\n current?.stop();\n const ac = audioContext();\n if (ac.state === 'suspended') await ac.resume().catch(() => undefined);\n const analyser = ac.createAnalyser();\n analyser.fftSize = opts.fftSize || 512;\n analyser.smoothingTimeConstant = opts.smoothing ?? 0.8;\n let src: AudioNode;\n let release = () => {};\n const media = typeof input === 'string' && input !== 'mic' ? document.querySelector<HTMLMediaElement>(input) : input;\n if (media === 'mic') {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n src = ac.createMediaStreamSource(stream);\n src.connect(analyser); // never to the speakers: no feedback\n release = () => stream.getTracks().forEach((t) => t.stop());\n } else if (media && typeof (media as HTMLMediaElement).play === 'function') {\n const m = media as HTMLMediaElement;\n let node = mediaSources.get(m);\n if (!node) mediaSources.set(m, (node = ac.createMediaElementSource(m)));\n try {\n node.disconnect();\n } catch {\n /* not connected */\n }\n src = node;\n src.connect(analyser);\n analyser.connect(ac.destination);\n release = () => {\n try {\n node!.disconnect();\n } catch {\n /* already */\n }\n node!.connect(ac.destination); // keep the media audible\n };\n if (m.paused) await m.play()?.catch?.(() => undefined);\n } else if (media && typeof (media as MediaStream).getTracks === 'function') {\n src = ac.createMediaStreamSource(media as MediaStream);\n src.connect(analyser);\n } else throw new Error(`[motionary] enableAudio: no audio source for ${String(input)}`);\n const freq = new Uint8Array(analyser.frequencyBinCount);\n const wave = new Uint8Array(analyser.fftSize);\n const self: AudioReactive = {\n context: ac,\n analyser,\n sample: () => {\n analyser.getByteFrequencyData(freq);\n analyser.getByteTimeDomainData(wave);\n let sq = 0;\n for (let i = 0; i < wave.length; i++) sq += ((wave[i] - 128) / 128) ** 2;\n const n = Math.max(1, Math.round(freq.length * 0.08));\n let b = 0;\n for (let i = 0; i < n; i++) b += freq[i];\n return { level: Math.min(1, Math.sqrt(sq / wave.length) * 2), bass: b / n / 255, freq, wave };\n },\n stop: () => {\n if (current === self) {\n current = null;\n if (raf && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(raf);\n raf = 0;\n }\n try {\n src.disconnect();\n analyser.disconnect();\n } catch {\n /* already */\n }\n release();\n setVars(0, 0);\n },\n };\n current = self;\n kick();\n return self;\n}\n\n/** Stop the current audio source (if any). */\nexport function disableAudio(): void {\n current?.stop();\n}\n\n/** A pure beat detector: feed it energy (0–1) and a timestamp per frame; it answers \"beat?\". */\nexport function createBeatDetector(o: BeatOptions = {}): (energy: number, now: number) => boolean {\n const { threshold = 1.35, cooldown = 250, history = 43, floor = 0.08 } = o;\n const hist: number[] = [];\n let last = -Infinity;\n return (energy, now) => {\n const avg = hist.length ? hist.reduce((a, b) => a + b, 0) / hist.length : energy;\n const ready = hist.length >= 8;\n hist.push(energy);\n if (hist.length > history) hist.shift();\n if (ready && energy > floor && energy > avg * threshold && now - last >= cooldown) {\n last = now;\n return true;\n }\n return false;\n };\n}\n\ntype BeatListener = { detect: (e: number, t: number) => boolean; cb: (detail: { energy: number; time: number }) => void };\nconst listeners = new Set<BeatListener>();\nlet raf = 0;\n\nfunction setVars(level: number, bass: number): void {\n if (typeof document === 'undefined') return;\n const s = document.documentElement.style;\n s.setProperty('--usa-audio-level', level.toFixed(3));\n s.setProperty('--usa-audio-bass', bass.toFixed(3));\n}\n\nfunction loop(now: number): void {\n raf = 0;\n if (!current) return;\n const { level, bass } = current.sample();\n const reduced = prefersReducedMotion();\n setVars(reduced ? 0 : level, reduced ? 0 : bass);\n for (const l of Array.from(listeners)) if (l.detect(bass, now)) l.cb({ energy: bass, time: now });\n kick();\n}\n\nfunction kick(): void {\n if (!raf && current && typeof requestAnimationFrame === 'function') raf = requestAnimationFrame(loop);\n}\n\n/** Call `cb` on every detected beat of the current audio source. Returns an unsubscribe. */\nexport function onBeat(cb: (detail: { energy: number; time: number }) => void, o: BeatOptions = {}): () => void {\n const l: BeatListener = { detect: createBeatDetector(o), cb };\n listeners.add(l);\n kick();\n return () => void listeners.delete(l);\n}\n\n/** Play the registered effect `name` on `el` at every beat (not under reduced motion). Returns an unbind. */\nexport function bindBeat(el: HTMLElement, name: string, options: Record<string, unknown> & BeatOptions = {}): () => void {\n const { threshold, cooldown, history, floor, ...fx } = options;\n return onBeat(() => {\n if (!prefersReducedMotion()) playEffect(el, name, fx).catch(() => undefined);\n }, { threshold, cooldown, history, floor } as BeatOptions);\n}\n\n// --- visual effects ----------------------------------------------------------\n\n/** The current sample, or a gentle synthetic one while no audio is enabled. */\nfunction read(t: number, bins: number): AudioSample & { idle: boolean } {\n if (current) return { ...current.sample(), idle: false };\n const freq = new Uint8Array(bins);\n const wave = new Uint8Array(bins * 2);\n for (let i = 0; i < bins; i++) freq[i] = 70 + 50 * Math.sin(t * 2 + i * 0.35) * Math.cos(t * 0.7 + i * 0.11) * (1 - i / bins);\n for (let i = 0; i < wave.length; i++) wave[i] = 128 + 22 * Math.sin(t * 3 + i * 0.12);\n return { level: 0.25 + 0.1 * Math.sin(t * 2), bass: 0.35 + 0.2 * Math.sin(t * 2.4), freq, wave, idle: true };\n}\n\nconst audioFx = (name: string, description: string, defaults: Record<string, unknown>, spec: GenerativeSpec): EffectDefinition => ({\n name,\n kind: 'background',\n description,\n reduced: 'skip',\n defaults: { colors: PALETTE, background: '#0b0d12', speed: 1, quality: 1, ...defaults },\n run: (el, o: any, ctx) => canvasBackground(el, ctx, spec, o),\n});\n\nexport const AUDIO_FX: EffectDefinition[] = [\n audioFx('spectrum-bars', 'Frequency bars dance to the audio (mirror them with `mirror: true`).', { bars: 48, gap: 2, mirror: false }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, o.bars);\n const per = Math.max(1, Math.floor((s.freq.length * 0.7) / o.bars));\n const bw = w / o.bars;\n for (let i = 0; i < o.bars; i++) {\n let v = 0;\n for (let k = 0; k < per; k++) v += s.freq[Math.min(s.freq.length - 1, i * per + k)];\n const bh = (v / per / 255) * h * (o.mirror ? 0.5 : 0.9);\n ctx.fillStyle = o.colors[i % o.colors.length];\n ctx.fillRect(i * bw + o.gap / 2, o.mirror ? h / 2 - bh : h - bh, Math.max(1, bw - o.gap), o.mirror ? bh * 2 : bh);\n }\n },\n }),\n audioFx('pulse-ring', 'Glowing rings pulse with the bass.', { rings: 3, color: '#7c5cff' }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, 32);\n const [r, g, b] = hexRgb(o.color);\n const base = Math.min(w, h) * 0.18;\n for (let i = 0; i < o.rings; i++) {\n const rad = base * (1 + i * 0.55) * (1 + s.bass * 0.6);\n ctx.strokeStyle = `rgba(${r},${g},${b},${(0.9 - i * 0.25) * (0.4 + s.level)})`;\n ctx.lineWidth = 3 + s.bass * 10 - i;\n ctx.beginPath();\n ctx.arc(w / 2, h / 2, rad, 0, Math.PI * 2);\n ctx.stroke();\n }\n },\n }),\n audioFx('wave-ring', 'The live waveform wrapped into a circle.', { color: '#22d3ee', amplitude: 0.35 }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, 64);\n const n = s.wave.length;\n const base = Math.min(w, h) * 0.28;\n ctx.strokeStyle = o.color;\n ctx.lineWidth = 2;\n ctx.beginPath();\n for (let i = 0; i <= n; i++) {\n const a = (i / n) * Math.PI * 2;\n const rad = base * (1 + ((s.wave[i % n] - 128) / 128) * o.amplitude * 2);\n const x = w / 2 + Math.cos(a) * rad;\n const y = h / 2 + Math.sin(a) * rad;\n if (i) ctx.lineTo(x, y);\n else ctx.moveTo(x, y);\n }\n ctx.closePath();\n ctx.stroke();\n },\n }),\n];\n\n// --- <usa-audio> -----------------------------------------------------------\n\nexport interface UsaAudioElement extends UsaElement {\n /** `true` while this element's audio source is being analysed. */\n readonly active: boolean;\n /** Start (from a user gesture) or stop analysing. */\n toggle(): Promise<void>;\n}\n\n/**\n * `<usa-audio source=\"#track | mic\" label=\"…\">` — a toggle button (yours, as\n * `[data-audio-toggle]`, or one it renders) that enables the audio source on\n * click; children with `data-usa-beat=\"effect\"` play that effect on every\n * beat (`data-usa-beat-options` JSON; `threshold` / `cooldown` attributes).\n * Emits `usa-beat` and `usa-audio-error`.\n */\nexport function defineAudio(tag = 'usa-audio'): CustomElementConstructor | undefined {\n return defineElement(\n tag,\n (Base) =>\n class UsaAudio extends Base {\n static get observedAttributes(): string[] {\n return ['source'];\n }\n active = false;\n private audio: AudioReactive | null = null;\n private off: (() => void) | null = null;\n private button(): HTMLButtonElement {\n let b = this.querySelector<HTMLButtonElement>('[data-audio-toggle]');\n if (!b) {\n b = document.createElement('button');\n b.type = 'button';\n b.setAttribute('data-audio-toggle', '');\n b.textContent = this.str('label', '🔊 Enable sound-reactive effects');\n this.prepend(b);\n this.onCleanup(() => b!.remove());\n }\n return b;\n }\n async toggle(): Promise<void> {\n const b = this.button();\n if (this.active) return this.stop();\n try {\n this.audio = await enableAudio(this.str('source', 'mic'));\n this.active = true;\n this.removeAttribute('data-audio-error');\n b.setAttribute('aria-pressed', 'true');\n this.off = onBeat((d) => {\n this.dispatchEvent(new CustomEvent('usa-beat', { detail: d, bubbles: true }));\n if (prefersReducedMotion()) return;\n this.querySelectorAll<HTMLElement>('[data-usa-beat]').forEach((el) => {\n let opts = {};\n try {\n opts = JSON.parse(el.dataset.usaBeatOptions || '{}') || {};\n } catch {\n /* ignore bad JSON */\n }\n playEffect(el, el.dataset.usaBeat || 'pulse', opts).catch(() => undefined);\n });\n }, { threshold: this.num('threshold', 1.35), cooldown: this.num('cooldown', 250) });\n } catch (err) {\n this.setAttribute('data-audio-error', '');\n this.dispatchEvent(new CustomEvent('usa-audio-error', { detail: { error: err }, bubbles: true }));\n }\n }\n private stop(): void {\n this.off?.();\n this.off = null;\n if (this.audio && current === this.audio) this.audio.stop();\n this.audio = null;\n this.active = false;\n this.querySelector('[data-audio-toggle]')?.setAttribute('aria-pressed', 'false');\n }\n mount(): void {\n const b = this.button();\n b.setAttribute('aria-pressed', 'false');\n this.listen(b, 'click', () => void this.toggle());\n this.onCleanup(() => this.stop());\n }\n },\n { id: 'usa-audio', text: 'usa-audio{display:block}usa-audio[data-audio-error] [data-audio-toggle]{outline:2px solid #ff5c8a}' }\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"audio-CWt1xdZB.js","sources":["../../src/components/effects/audio.ts"],"sourcesContent":["/**\n * 5.6 — sound-reactive effects (Web Audio).\n *\n * - `enableAudio(input)` — start analysing the microphone (`'mic'`), an\n * `<audio>` / `<video>` element (or a selector for one) or a `MediaStream`.\n * Browsers only allow an `AudioContext` to start inside a user gesture, so\n * call it from a click handler (or use `<usa-audio>`, which renders the\n * toggle button for you).\n * - Background effects (kind `background`, Canvas 2D through\n * `canvasBackground()`): `spectrum-bars`, `pulse-ring`, `wave-ring`. Before\n * audio is enabled they idle gently.\n * - Beat detection: `createBeatDetector()` (pure: energy → beat?), `onBeat(cb)`\n * and `bindBeat(el, effect, options)`, which plays any registered effect on\n * every beat. `<usa-audio>` does the same for `[data-usa-beat=\"effect\"]`\n * children and emits `usa-beat`.\n * - While audio runs, `--usa-audio-level` and `--usa-audio-bass` (0–1) are set\n * on `<html>` for CSS-driven reactions.\n *\n * Reduced motion: the visual effects are skipped, beats play no effects and\n * the CSS variables stay at 0 — audio itself keeps playing.\n */\nimport type { EffectDefinition } from '../fx/registry';\nimport { playEffect } from '../fx/registry';\nimport { defineElement, prefersReducedMotion, type UsaElement } from '../base';\nimport { canvasBackground, hexRgb, type GenerativeSpec } from './generative';\nimport { PALETTE } from './shared';\n\nexport type AudioInput = 'mic' | HTMLMediaElement | MediaStream | string;\n\nexport interface AudioSample {\n /** Overall loudness (RMS of the waveform), 0–1. */\n level: number;\n /** Low-frequency energy (first ~8 % of the spectrum), 0–1. */\n bass: number;\n /** Frequency bins, 0–255 each. */\n freq: Uint8Array;\n /** Time-domain waveform, 0–255 (128 = silence). */\n wave: Uint8Array;\n}\n\nexport interface AudioReactive {\n readonly context: AudioContext;\n readonly analyser: AnalyserNode;\n /** Read the analyser now. */\n sample(): AudioSample;\n /** Stop analysing (media keeps playing; the microphone is released). */\n stop(): void;\n}\n\nexport interface BeatOptions {\n /** A beat is energy above `threshold` × the recent average (default 1.35). */\n threshold?: number;\n /** Minimum ms between beats (default 250). */\n cooldown?: number;\n /** Frames of history for the average (default 43 ≈ 0.7 s). */\n history?: number;\n /** Ignore energy below this floor, 0–1 (default 0.08). */\n floor?: number;\n}\n\nlet actx: AudioContext | null = null;\nlet current: AudioReactive | null = null;\nconst mediaSources = new WeakMap<HTMLMediaElement, MediaElementAudioSourceNode>();\n\n/** The running analyser, if `enableAudio()` was called. */\nexport const getAudio = (): AudioReactive | null => current;\n\nfunction audioContext(): AudioContext {\n const AC = (globalThis as any).AudioContext || (globalThis as any).webkitAudioContext;\n if (!AC) throw new Error('[motionary] Web Audio is not available');\n if (!actx || actx.state === 'closed') actx = new AC() as AudioContext;\n return actx;\n}\n\n/**\n * Start analysing `input` and make it the source of every sound-reactive\n * effect. Call from a user gesture. Replaces a previous source.\n */\nexport async function enableAudio(input: AudioInput = 'mic', opts: { fftSize?: number; smoothing?: number } = {}): Promise<AudioReactive> {\n current?.stop();\n const ac = audioContext();\n if (ac.state === 'suspended') await ac.resume().catch(() => undefined);\n const analyser = ac.createAnalyser();\n analyser.fftSize = opts.fftSize || 512;\n analyser.smoothingTimeConstant = opts.smoothing ?? 0.8;\n let src: AudioNode;\n let release = () => {};\n const media = typeof input === 'string' && input !== 'mic' ? document.querySelector<HTMLMediaElement>(input) : input;\n if (media === 'mic') {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n src = ac.createMediaStreamSource(stream);\n src.connect(analyser); // never to the speakers: no feedback\n release = () => stream.getTracks().forEach((t) => t.stop());\n } else if (media && typeof (media as HTMLMediaElement).play === 'function') {\n const m = media as HTMLMediaElement;\n let node = mediaSources.get(m);\n if (!node) mediaSources.set(m, (node = ac.createMediaElementSource(m)));\n try {\n node.disconnect();\n } catch {\n /* not connected */\n }\n src = node;\n src.connect(analyser);\n analyser.connect(ac.destination);\n release = () => {\n try {\n node!.disconnect();\n } catch {\n /* already */\n }\n node!.connect(ac.destination); // keep the media audible\n };\n if (m.paused) await m.play()?.catch?.(() => undefined);\n } else if (media && typeof (media as MediaStream).getTracks === 'function') {\n src = ac.createMediaStreamSource(media as MediaStream);\n src.connect(analyser);\n } else throw new Error(`[motionary] enableAudio: no audio source for ${String(input)}`);\n const freq = new Uint8Array(analyser.frequencyBinCount);\n const wave = new Uint8Array(analyser.fftSize);\n const self: AudioReactive = {\n context: ac,\n analyser,\n sample: () => {\n analyser.getByteFrequencyData(freq);\n analyser.getByteTimeDomainData(wave);\n let sq = 0;\n for (let i = 0; i < wave.length; i++) sq += ((wave[i] - 128) / 128) ** 2;\n const n = Math.max(1, Math.round(freq.length * 0.08));\n let b = 0;\n for (let i = 0; i < n; i++) b += freq[i];\n return { level: Math.min(1, Math.sqrt(sq / wave.length) * 2), bass: b / n / 255, freq, wave };\n },\n stop: () => {\n if (current === self) {\n current = null;\n if (raf && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(raf);\n raf = 0;\n }\n try {\n src.disconnect();\n analyser.disconnect();\n } catch {\n /* already */\n }\n release();\n setVars(0, 0);\n },\n };\n current = self;\n kick();\n return self;\n}\n\n/** Stop the current audio source (if any). */\nexport function disableAudio(): void {\n current?.stop();\n}\n\n/** A pure beat detector: feed it energy (0–1) and a timestamp per frame; it answers \"beat?\". */\nexport function createBeatDetector(o: BeatOptions = {}): (energy: number, now: number) => boolean {\n const { threshold = 1.35, cooldown = 250, history = 43, floor = 0.08 } = o;\n const hist: number[] = [];\n let last = -Infinity;\n return (energy, now) => {\n const avg = hist.length ? hist.reduce((a, b) => a + b, 0) / hist.length : energy;\n const ready = hist.length >= 8;\n hist.push(energy);\n if (hist.length > history) hist.shift();\n if (ready && energy > floor && energy > avg * threshold && now - last >= cooldown) {\n last = now;\n return true;\n }\n return false;\n };\n}\n\ntype BeatListener = { detect: (e: number, t: number) => boolean; cb: (detail: { energy: number; time: number }) => void };\nconst listeners = new Set<BeatListener>();\nlet raf = 0;\n\nfunction setVars(level: number, bass: number): void {\n if (typeof document === 'undefined') return;\n const s = document.documentElement.style;\n s.setProperty('--usa-audio-level', level.toFixed(3));\n s.setProperty('--usa-audio-bass', bass.toFixed(3));\n}\n\nfunction loop(now: number): void {\n raf = 0;\n if (!current) return;\n const { level, bass } = current.sample();\n const reduced = prefersReducedMotion();\n setVars(reduced ? 0 : level, reduced ? 0 : bass);\n for (const l of Array.from(listeners)) if (l.detect(bass, now)) l.cb({ energy: bass, time: now });\n kick();\n}\n\nfunction kick(): void {\n if (!raf && current && typeof requestAnimationFrame === 'function') raf = requestAnimationFrame(loop);\n}\n\n/** Call `cb` on every detected beat of the current audio source. Returns an unsubscribe. */\nexport function onBeat(cb: (detail: { energy: number; time: number }) => void, o: BeatOptions = {}): () => void {\n const l: BeatListener = { detect: createBeatDetector(o), cb };\n listeners.add(l);\n kick();\n return () => void listeners.delete(l);\n}\n\n/** Play the registered effect `name` on `el` at every beat (not under reduced motion). Returns an unbind. */\nexport function bindBeat(el: HTMLElement, name: string, options: Record<string, unknown> & BeatOptions = {}): () => void {\n const { threshold, cooldown, history, floor, ...fx } = options;\n return onBeat(() => {\n if (!prefersReducedMotion()) playEffect(el, name, fx).catch(() => undefined);\n }, { threshold, cooldown, history, floor } as BeatOptions);\n}\n\n// --- visual effects ----------------------------------------------------------\n\n/** The current sample, or a gentle synthetic one while no audio is enabled. */\nfunction read(t: number, bins: number): AudioSample & { idle: boolean } {\n if (current) return { ...current.sample(), idle: false };\n const freq = new Uint8Array(bins);\n const wave = new Uint8Array(bins * 2);\n for (let i = 0; i < bins; i++) freq[i] = 70 + 50 * Math.sin(t * 2 + i * 0.35) * Math.cos(t * 0.7 + i * 0.11) * (1 - i / bins);\n for (let i = 0; i < wave.length; i++) wave[i] = 128 + 22 * Math.sin(t * 3 + i * 0.12);\n return { level: 0.25 + 0.1 * Math.sin(t * 2), bass: 0.35 + 0.2 * Math.sin(t * 2.4), freq, wave, idle: true };\n}\n\nconst audioFx = (name: string, description: string, defaults: Record<string, unknown>, spec: GenerativeSpec): EffectDefinition => ({\n name,\n kind: 'background',\n description,\n reduced: 'skip',\n defaults: { colors: PALETTE, background: '#0b0d12', speed: 1, quality: 1, ...defaults },\n run: (el, o: any, ctx) => canvasBackground(el, ctx, spec, o),\n});\n\nexport const AUDIO_FX: EffectDefinition[] = [\n audioFx('spectrum-bars', 'Frequency bars dance to the audio (mirror them with `mirror: true`).', { bars: 48, gap: 2, mirror: false }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, o.bars);\n const per = Math.max(1, Math.floor((s.freq.length * 0.7) / o.bars));\n const bw = w / o.bars;\n for (let i = 0; i < o.bars; i++) {\n let v = 0;\n for (let k = 0; k < per; k++) v += s.freq[Math.min(s.freq.length - 1, i * per + k)];\n const bh = (v / per / 255) * h * (o.mirror ? 0.5 : 0.9);\n ctx.fillStyle = o.colors[i % o.colors.length];\n ctx.fillRect(i * bw + o.gap / 2, o.mirror ? h / 2 - bh : h - bh, Math.max(1, bw - o.gap), o.mirror ? bh * 2 : bh);\n }\n },\n }),\n audioFx('pulse-ring', 'Glowing rings pulse with the bass.', { rings: 3, color: '#7c5cff' }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, 32);\n const [r, g, b] = hexRgb(o.color);\n const base = Math.min(w, h) * 0.18;\n for (let i = 0; i < o.rings; i++) {\n const rad = base * (1 + i * 0.55) * (1 + s.bass * 0.6);\n ctx.strokeStyle = `rgba(${r},${g},${b},${(0.9 - i * 0.25) * (0.4 + s.level)})`;\n ctx.lineWidth = 3 + s.bass * 10 - i;\n ctx.beginPath();\n ctx.arc(w / 2, h / 2, rad, 0, Math.PI * 2);\n ctx.stroke();\n }\n },\n }),\n audioFx('wave-ring', 'The live waveform wrapped into a circle.', { color: '#22d3ee', amplitude: 0.35 }, {\n draw: ({ ctx, w, h, t, o }) => {\n ctx.fillStyle = o.background;\n ctx.fillRect(0, 0, w, h);\n const s = read(t, 64);\n const n = s.wave.length;\n const base = Math.min(w, h) * 0.28;\n ctx.strokeStyle = o.color;\n ctx.lineWidth = 2;\n ctx.beginPath();\n for (let i = 0; i <= n; i++) {\n const a = (i / n) * Math.PI * 2;\n const rad = base * (1 + ((s.wave[i % n] - 128) / 128) * o.amplitude * 2);\n const x = w / 2 + Math.cos(a) * rad;\n const y = h / 2 + Math.sin(a) * rad;\n if (i) ctx.lineTo(x, y);\n else ctx.moveTo(x, y);\n }\n ctx.closePath();\n ctx.stroke();\n },\n }),\n];\n\n// --- <usa-audio> -----------------------------------------------------------\n\nexport interface UsaAudioElement extends UsaElement {\n /** `true` while this element's audio source is being analysed. */\n readonly active: boolean;\n /** Start (from a user gesture) or stop analysing. */\n toggle(): Promise<void>;\n}\n\n/**\n * `<usa-audio source=\"#track | mic\" label=\"…\">` — a toggle button (yours, as\n * `[data-audio-toggle]`, or one it renders) that enables the audio source on\n * click; children with `data-usa-beat=\"effect\"` play that effect on every\n * beat (`data-usa-beat-options` JSON; `threshold` / `cooldown` attributes).\n * Emits `usa-beat` and `usa-audio-error`.\n */\nexport function defineAudio(tag = 'usa-audio'): CustomElementConstructor | undefined {\n return defineElement(\n tag,\n (Base) =>\n class UsaAudio extends Base {\n static get observedAttributes(): string[] {\n return ['source'];\n }\n active = false;\n private audio: AudioReactive | null = null;\n private off: (() => void) | null = null;\n private button(): HTMLButtonElement {\n let b = this.querySelector<HTMLButtonElement>('[data-audio-toggle]');\n if (!b) {\n b = document.createElement('button');\n b.type = 'button';\n b.setAttribute('data-audio-toggle', '');\n b.textContent = this.str('label', '🔊 Enable sound-reactive effects');\n this.prepend(b);\n this.onCleanup(() => b!.remove());\n }\n return b;\n }\n async toggle(): Promise<void> {\n const b = this.button();\n if (this.active) return this.stop();\n try {\n this.audio = await enableAudio(this.str('source', 'mic'));\n this.active = true;\n this.removeAttribute('data-audio-error');\n b.setAttribute('aria-pressed', 'true');\n this.off = onBeat((d) => {\n this.dispatchEvent(new CustomEvent('usa-beat', { detail: d, bubbles: true }));\n if (prefersReducedMotion()) return;\n this.querySelectorAll<HTMLElement>('[data-usa-beat]').forEach((el) => {\n let opts = {};\n try {\n opts = JSON.parse(el.dataset.usaBeatOptions || '{}') || {};\n } catch {\n /* ignore bad JSON */\n }\n playEffect(el, el.dataset.usaBeat || 'pulse', opts).catch(() => undefined);\n });\n }, { threshold: this.num('threshold', 1.35), cooldown: this.num('cooldown', 250) });\n } catch (err) {\n this.setAttribute('data-audio-error', '');\n this.dispatchEvent(new CustomEvent('usa-audio-error', { detail: { error: err }, bubbles: true }));\n }\n }\n private stop(): void {\n this.off?.();\n this.off = null;\n if (this.audio && current === this.audio) this.audio.stop();\n this.audio = null;\n this.active = false;\n this.querySelector('[data-audio-toggle]')?.setAttribute('aria-pressed', 'false');\n }\n mount(): void {\n const b = this.button();\n b.setAttribute('aria-pressed', 'false');\n this.listen(b, 'click', () => void this.toggle());\n this.onCleanup(() => this.stop());\n }\n },\n { id: 'usa-audio', text: 'usa-audio{display:block}usa-audio[data-audio-error] [data-audio-toggle]{outline:2px solid #ff5c8a}' }\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -457,5 +457,5 @@ function kindOf(el, valid, fallback) {
|
|
|
457
457
|
}
|
|
458
458
|
const clamp = (v, min, max) => Math.min(max, Math.max(min, v));
|
|
459
459
|
|
|
460
|
-
export { srText as A,
|
|
461
|
-
//# sourceMappingURL=base-
|
|
460
|
+
export { srText as A, deprecate as B, adoptStyles as C, EASE_OUT as D, EASE_SPRING as E, kindOf as F, shadowStyles as G, FLUENT_DECELERATE as H, MOTION_SENSITIVITY_LEVELS as M, applyFrame as a, caf as b, configureComponents as c, clamp as d, animateWithMotion as e, defineElement as f, getMotionSensitivity as g, getClock as h, canDefine as i, MOTION_SCALE as j, activeAnimations as k, adaptKeyframes as l, motionScale as m, now as n, onClockChange as o, prefersReducedMotion as p, animationBudget as q, raf as r, setClock as s, trackAnimation as t, getMotionIntensity as u, onFrame as v, schedulerStats as w, setAnimationBudget as x, withoutDeprecations as y, setStyleLoader as z };
|
|
461
|
+
//# sourceMappingURL=base-BTev8qxg.js.map
|