motionary 0.0.0-stage → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +803 -0
- package/LICENSE +21 -0
- package/README.md +218 -2
- package/README_ja.md +219 -0
- package/README_zh.md +219 -0
- package/bin/usa-codemod-5.mjs +79 -0
- package/bin/usa-codemod-6.mjs +146 -0
- package/dist/chunks/base-BaQV-2ha.cjs +436 -0
- package/dist/chunks/base-BaQV-2ha.cjs.map +1 -0
- package/dist/chunks/base-C_3cAoRz.js +404 -0
- package/dist/chunks/base-C_3cAoRz.js.map +1 -0
- package/dist/chunks/bind-B_CTL6Qn.js +22 -0
- package/dist/chunks/bind-B_CTL6Qn.js.map +1 -0
- package/dist/chunks/bind-Ui43-n2d.cjs +25 -0
- package/dist/chunks/bind-Ui43-n2d.cjs.map +1 -0
- package/dist/chunks/core-B5T0dhFH.cjs +920 -0
- package/dist/chunks/core-B5T0dhFH.cjs.map +1 -0
- package/dist/chunks/core-BGAyaY6L.cjs +265 -0
- package/dist/chunks/core-BGAyaY6L.cjs.map +1 -0
- package/dist/chunks/core-D7cVumUu.js +909 -0
- package/dist/chunks/core-D7cVumUu.js.map +1 -0
- package/dist/chunks/core-VEBw36QK.js +260 -0
- package/dist/chunks/core-VEBw36QK.js.map +1 -0
- package/dist/chunks/core-ps8uvYuN.js +181 -0
- package/dist/chunks/core-ps8uvYuN.js.map +1 -0
- package/dist/chunks/core-zq17EeCI.cjs +185 -0
- package/dist/chunks/core-zq17EeCI.cjs.map +1 -0
- package/dist/chunks/fx-Bs6IrV4Q.js +109 -0
- package/dist/chunks/fx-Bs6IrV4Q.js.map +1 -0
- package/dist/chunks/fx-lBGVtQO1.cjs +114 -0
- package/dist/chunks/fx-lBGVtQO1.cjs.map +1 -0
- package/dist/chunks/generative-D2YyhaeO.js +336 -0
- package/dist/chunks/generative-D2YyhaeO.js.map +1 -0
- package/dist/chunks/generative-DzIZq-_g.cjs +348 -0
- package/dist/chunks/generative-DzIZq-_g.cjs.map +1 -0
- package/dist/chunks/gpu-Bu7qwugO.js +380 -0
- package/dist/chunks/gpu-Bu7qwugO.js.map +1 -0
- package/dist/chunks/gpu-CenK2l6b.cjs +387 -0
- package/dist/chunks/gpu-CenK2l6b.cjs.map +1 -0
- package/dist/chunks/index-tags-DucKMQr_.js +26 -0
- package/dist/chunks/index-tags-DucKMQr_.js.map +1 -0
- package/dist/chunks/index-tags-wv0R_vkO.cjs +28 -0
- package/dist/chunks/index-tags-wv0R_vkO.cjs.map +1 -0
- package/dist/chunks/presets-BYBVJVeP.js +226 -0
- package/dist/chunks/presets-BYBVJVeP.js.map +1 -0
- package/dist/chunks/presets-CUHys3sK.cjs +233 -0
- package/dist/chunks/presets-CUHys3sK.cjs.map +1 -0
- package/dist/chunks/registry-CKNLQpwd.js +121 -0
- package/dist/chunks/registry-CKNLQpwd.js.map +1 -0
- package/dist/chunks/registry-DehBVRDV.cjs +131 -0
- package/dist/chunks/registry-DehBVRDV.cjs.map +1 -0
- package/dist/chunks/spring-CbvHfVtP.js +219 -0
- package/dist/chunks/spring-CbvHfVtP.js.map +1 -0
- package/dist/chunks/spring-Dgx187Vh.cjs +232 -0
- package/dist/chunks/spring-Dgx187Vh.cjs.map +1 -0
- package/dist/chunks/stagger-CCFyhzSw.cjs +86 -0
- package/dist/chunks/stagger-CCFyhzSw.cjs.map +1 -0
- package/dist/chunks/stagger-DtMKo2SK.js +84 -0
- package/dist/chunks/stagger-DtMKo2SK.js.map +1 -0
- package/dist/chunks/variants-BhjyddG8.cjs +39 -0
- package/dist/chunks/variants-BhjyddG8.cjs.map +1 -0
- package/dist/chunks/variants-DRlKVHvu.js +35 -0
- package/dist/chunks/variants-DRlKVHvu.js.map +1 -0
- package/dist/components/a11y.cjs +276 -0
- package/dist/components/a11y.cjs.map +1 -0
- package/dist/components/a11y.d.cts +131 -0
- package/dist/components/a11y.d.ts +131 -0
- package/dist/components/a11y.js +259 -0
- package/dist/components/a11y.js.map +1 -0
- package/dist/components/angular.cjs +76 -0
- package/dist/components/angular.cjs.map +1 -0
- package/dist/components/angular.d.cts +1734 -0
- package/dist/components/angular.d.ts +1734 -0
- package/dist/components/angular.js +70 -0
- package/dist/components/angular.js.map +1 -0
- package/dist/components/background.cjs +659 -0
- package/dist/components/background.cjs.map +1 -0
- package/dist/components/background.css +9 -0
- package/dist/components/background.d.cts +166 -0
- package/dist/components/background.d.ts +166 -0
- package/dist/components/background.js +647 -0
- package/dist/components/background.js.map +1 -0
- package/dist/components/bridge.cjs +154 -0
- package/dist/components/bridge.cjs.map +1 -0
- package/dist/components/bridge.d.cts +63 -0
- package/dist/components/bridge.d.ts +63 -0
- package/dist/components/bridge.js +147 -0
- package/dist/components/bridge.js.map +1 -0
- package/dist/components/cards.cjs +561 -0
- package/dist/components/cards.cjs.map +1 -0
- package/dist/components/cards.css +6 -0
- package/dist/components/cards.d.cts +115 -0
- package/dist/components/cards.d.ts +115 -0
- package/dist/components/cards.js +554 -0
- package/dist/components/cards.js.map +1 -0
- package/dist/components/click.cjs +877 -0
- package/dist/components/click.cjs.map +1 -0
- package/dist/components/click.css +9 -0
- package/dist/components/click.d.cts +218 -0
- package/dist/components/click.d.ts +218 -0
- package/dist/components/click.js +863 -0
- package/dist/components/click.js.map +1 -0
- package/dist/components/depth.cjs +250 -0
- package/dist/components/depth.cjs.map +1 -0
- package/dist/components/depth.css +3 -0
- package/dist/components/depth.d.cts +86 -0
- package/dist/components/depth.d.ts +86 -0
- package/dist/components/depth.js +242 -0
- package/dist/components/depth.js.map +1 -0
- package/dist/components/effects.cjs +2258 -0
- package/dist/components/effects.cjs.map +1 -0
- package/dist/components/effects.d.cts +545 -0
- package/dist/components/effects.d.ts +545 -0
- package/dist/components/effects.js +2200 -0
- package/dist/components/effects.js.map +1 -0
- package/dist/components/feedback.cjs +442 -0
- package/dist/components/feedback.cjs.map +1 -0
- package/dist/components/feedback.css +7 -0
- package/dist/components/feedback.d.cts +144 -0
- package/dist/components/feedback.d.ts +144 -0
- package/dist/components/feedback.js +433 -0
- package/dist/components/feedback.js.map +1 -0
- package/dist/components/fx-gpu.cjs +12 -0
- package/dist/components/fx-gpu.cjs.map +1 -0
- package/dist/components/fx-gpu.d.cts +63 -0
- package/dist/components/fx-gpu.d.ts +63 -0
- package/dist/components/fx-gpu.js +5 -0
- package/dist/components/fx-gpu.js.map +1 -0
- package/dist/components/fx.cjs +169 -0
- package/dist/components/fx.cjs.map +1 -0
- package/dist/components/fx.css +3 -0
- package/dist/components/fx.d.cts +114 -0
- package/dist/components/fx.d.ts +114 -0
- package/dist/components/fx.js +156 -0
- package/dist/components/fx.js.map +1 -0
- package/dist/components/fx2.cjs +25 -0
- package/dist/components/fx2.cjs.map +1 -0
- package/dist/components/fx2.d.cts +136 -0
- package/dist/components/fx2.d.ts +136 -0
- package/dist/components/fx2.js +17 -0
- package/dist/components/fx2.js.map +1 -0
- package/dist/components/gesture.cjs +209 -0
- package/dist/components/gesture.cjs.map +1 -0
- package/dist/components/gesture.css +3 -0
- package/dist/components/gesture.d.cts +134 -0
- package/dist/components/gesture.d.ts +134 -0
- package/dist/components/gesture.js +203 -0
- package/dist/components/gesture.js.map +1 -0
- package/dist/components/interaction.cjs +424 -0
- package/dist/components/interaction.cjs.map +1 -0
- package/dist/components/interaction.css +8 -0
- package/dist/components/interaction.d.cts +115 -0
- package/dist/components/interaction.d.ts +115 -0
- package/dist/components/interaction.js +416 -0
- package/dist/components/interaction.js.map +1 -0
- package/dist/components/jsx.cjs +3 -0
- package/dist/components/jsx.cjs.map +1 -0
- package/dist/components/jsx.d.cts +53 -0
- package/dist/components/jsx.d.ts +53 -0
- package/dist/components/jsx.js +2 -0
- package/dist/components/jsx.js.map +1 -0
- package/dist/components/layout.cjs +257 -0
- package/dist/components/layout.cjs.map +1 -0
- package/dist/components/layout.css +3 -0
- package/dist/components/layout.d.cts +99 -0
- package/dist/components/layout.d.ts +99 -0
- package/dist/components/layout.js +249 -0
- package/dist/components/layout.js.map +1 -0
- package/dist/components/lazy.cjs +92 -0
- package/dist/components/lazy.cjs.map +1 -0
- package/dist/components/lazy.d.cts +48 -0
- package/dist/components/lazy.d.ts +48 -0
- package/dist/components/lazy.js +87 -0
- package/dist/components/lazy.js.map +1 -0
- package/dist/components/lite.cjs +11095 -0
- package/dist/components/lite.cjs.map +1 -0
- package/dist/components/lite.d.cts +4 -0
- package/dist/components/lite.d.ts +4 -0
- package/dist/components/lite.js +10827 -0
- package/dist/components/lite.js.map +1 -0
- package/dist/components/packs.cjs +192 -0
- package/dist/components/packs.cjs.map +1 -0
- package/dist/components/packs.css +3 -0
- package/dist/components/packs.d.cts +72 -0
- package/dist/components/packs.d.ts +72 -0
- package/dist/components/packs.js +184 -0
- package/dist/components/packs.js.map +1 -0
- package/dist/components/page.cjs +824 -0
- package/dist/components/page.cjs.map +1 -0
- package/dist/components/page.css +11 -0
- package/dist/components/page.d.cts +249 -0
- package/dist/components/page.d.ts +249 -0
- package/dist/components/page.js +799 -0
- package/dist/components/page.js.map +1 -0
- package/dist/components/perf.cjs +120 -0
- package/dist/components/perf.cjs.map +1 -0
- package/dist/components/perf.d.cts +98 -0
- package/dist/components/perf.d.ts +98 -0
- package/dist/components/perf.js +110 -0
- package/dist/components/perf.js.map +1 -0
- package/dist/components/physics.cjs +448 -0
- package/dist/components/physics.cjs.map +1 -0
- package/dist/components/physics.css +5 -0
- package/dist/components/physics.d.cts +189 -0
- package/dist/components/physics.d.ts +189 -0
- package/dist/components/physics.js +430 -0
- package/dist/components/physics.js.map +1 -0
- package/dist/components/react.cjs +96 -0
- package/dist/components/react.cjs.map +1 -0
- package/dist/components/react.d.cts +18 -0
- package/dist/components/react.d.ts +18 -0
- package/dist/components/react.js +91 -0
- package/dist/components/react.js.map +1 -0
- package/dist/components/reveal.cjs +362 -0
- package/dist/components/reveal.cjs.map +1 -0
- package/dist/components/reveal.css +5 -0
- package/dist/components/reveal.d.cts +105 -0
- package/dist/components/reveal.d.ts +105 -0
- package/dist/components/reveal.js +353 -0
- package/dist/components/reveal.js.map +1 -0
- package/dist/components/solid.cjs +86 -0
- package/dist/components/solid.cjs.map +1 -0
- package/dist/components/solid.d.cts +1751 -0
- package/dist/components/solid.d.ts +1751 -0
- package/dist/components/solid.js +82 -0
- package/dist/components/solid.js.map +1 -0
- package/dist/components/svelte.cjs +68 -0
- package/dist/components/svelte.cjs.map +1 -0
- package/dist/components/svelte.d.cts +1733 -0
- package/dist/components/svelte.d.ts +1733 -0
- package/dist/components/svelte.js +64 -0
- package/dist/components/svelte.js.map +1 -0
- package/dist/components/svg.cjs +359 -0
- package/dist/components/svg.cjs.map +1 -0
- package/dist/components/svg.css +3 -0
- package/dist/components/svg.d.cts +113 -0
- package/dist/components/svg.d.ts +113 -0
- package/dist/components/svg.js +347 -0
- package/dist/components/svg.js.map +1 -0
- package/dist/components/text.cjs +968 -0
- package/dist/components/text.cjs.map +1 -0
- package/dist/components/text.css +8 -0
- package/dist/components/text.d.cts +342 -0
- package/dist/components/text.d.ts +342 -0
- package/dist/components/text.js +947 -0
- package/dist/components/text.js.map +1 -0
- package/dist/components/timeline.cjs +109 -0
- package/dist/components/timeline.cjs.map +1 -0
- package/dist/components/timeline.css +3 -0
- package/dist/components/timeline.d.cts +155 -0
- package/dist/components/timeline.d.ts +155 -0
- package/dist/components/timeline.js +103 -0
- package/dist/components/timeline.js.map +1 -0
- package/dist/components/tokens.cjs +226 -0
- package/dist/components/tokens.cjs.map +1 -0
- package/dist/components/tokens.d.cts +74 -0
- package/dist/components/tokens.d.ts +74 -0
- package/dist/components/tokens.js +211 -0
- package/dist/components/tokens.js.map +1 -0
- package/dist/components/transitions.cjs +430 -0
- package/dist/components/transitions.cjs.map +1 -0
- package/dist/components/transitions.css +5 -0
- package/dist/components/transitions.d.cts +126 -0
- package/dist/components/transitions.d.ts +126 -0
- package/dist/components/transitions.js +423 -0
- package/dist/components/transitions.js.map +1 -0
- package/dist/components/ui.cjs +1050 -0
- package/dist/components/ui.cjs.map +1 -0
- package/dist/components/ui.css +14 -0
- package/dist/components/ui.d.cts +224 -0
- package/dist/components/ui.d.ts +224 -0
- package/dist/components/ui.js +1034 -0
- package/dist/components/ui.js.map +1 -0
- package/dist/components/vue.cjs +67 -0
- package/dist/components/vue.cjs.map +1 -0
- package/dist/components/vue.d.cts +1722 -0
- package/dist/components/vue.d.ts +1722 -0
- package/dist/components/vue.js +64 -0
- package/dist/components/vue.js.map +1 -0
- package/dist/components/webgl.cjs +459 -0
- package/dist/components/webgl.cjs.map +1 -0
- package/dist/components/webgl.css +3 -0
- package/dist/components/webgl.d.cts +133 -0
- package/dist/components/webgl.d.ts +133 -0
- package/dist/components/webgl.js +442 -0
- package/dist/components/webgl.js.map +1 -0
- package/dist/components/widgets.cjs +591 -0
- package/dist/components/widgets.cjs.map +1 -0
- package/dist/components/widgets.d.cts +110 -0
- package/dist/components/widgets.d.ts +110 -0
- package/dist/components/widgets.js +581 -0
- package/dist/components/widgets.js.map +1 -0
- package/dist/components.cjs +351 -0
- package/dist/components.cjs.map +1 -0
- package/dist/components.css +75 -0
- package/dist/components.d.cts +2997 -0
- package/dist/components.d.ts +2997 -0
- package/dist/components.js +106 -0
- package/dist/components.js.map +1 -0
- package/dist/components.umd.js +23 -0
- package/dist/components.umd.js.map +1 -0
- package/dist/element.cjs +97 -0
- package/dist/element.cjs.map +1 -0
- package/dist/element.d.cts +215 -0
- package/dist/element.d.ts +215 -0
- package/dist/element.js +95 -0
- package/dist/element.js.map +1 -0
- package/dist/element.umd.js +2 -0
- package/dist/element.umd.js.map +1 -0
- package/dist/index.cjs +149 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +425 -0
- package/dist/index.d.ts +425 -0
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +15 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/presets/extended.cjs +243 -0
- package/dist/presets/extended.cjs.map +1 -0
- package/dist/presets/extended.d.cts +37 -0
- package/dist/presets/extended.d.ts +37 -0
- package/dist/presets/extended.js +239 -0
- package/dist/presets/extended.js.map +1 -0
- package/dist/presets-extended.umd.js +2 -0
- package/dist/presets-extended.umd.js.map +1 -0
- package/dist/react.cjs +68 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +158 -0
- package/dist/react.d.ts +158 -0
- package/dist/react.js +65 -0
- package/dist/react.js.map +1 -0
- package/dist/solid.cjs +93 -0
- package/dist/solid.cjs.map +1 -0
- package/dist/solid.d.cts +249 -0
- package/dist/solid.d.ts +249 -0
- package/dist/solid.js +89 -0
- package/dist/solid.js.map +1 -0
- package/dist/svelte.cjs +66 -0
- package/dist/svelte.cjs.map +1 -0
- package/dist/svelte.d.cts +243 -0
- package/dist/svelte.d.ts +243 -0
- package/dist/svelte.js +63 -0
- package/dist/svelte.js.map +1 -0
- package/dist/vue.cjs +62 -0
- package/dist/vue.cjs.map +1 -0
- package/dist/vue.d.cts +158 -0
- package/dist/vue.d.ts +158 -0
- package/dist/vue.js +60 -0
- package/dist/vue.js.map +1 -0
- package/dist/widgets.umd.js +2 -0
- package/dist/widgets.umd.js.map +1 -0
- package/docs/API.md +147 -0
- package/docs/ROADMAP.md +14 -0
- package/docs/accessibility.md +60 -0
- package/docs/components.md +564 -0
- package/docs/deprecations.md +30 -0
- package/docs/frameworks-ssr.md +100 -0
- package/docs/hybrid-apps.md +145 -0
- package/docs/images/showcase-detail.png +0 -0
- package/docs/images/showcase-grid.png +0 -0
- package/docs/images/showcase-mobile.png +0 -0
- package/docs/migration-from-aos.md +67 -0
- package/docs/migration-from-gsap-scrolltrigger.md +80 -0
- package/docs/motion-tokens.css +31 -0
- package/docs/motion-tokens.md +46 -0
- package/docs/motion.tokens.json +132 -0
- package/docs/performance.md +24 -0
- package/docs/presets.md +310 -0
- package/docs/upgrading-3.md +21 -0
- package/docs/upgrading-4.md +65 -0
- package/docs/upgrading-5.md +31 -0
- package/docs/upgrading-6.md +32 -0
- package/docs/windows-apps.md +119 -0
- package/package.json +562 -4
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Deprecations
|
|
2
|
+
|
|
3
|
+
## Deprecated in 5.9, removed in 6.0
|
|
4
|
+
|
|
5
|
+
See [upgrading-6.md](./upgrading-6.md) — `burst()`, `confetti()`, `shake()` (use `playEffect(el, 'burst' | 'confetti' | 'shake', …)`), `<usa-cursor mode="trail">` (use the `comet-trail` effect). Run `npx usa-codemod-6 --write src`.
|
|
6
|
+
|
|
7
|
+
## Deprecated in 4.9, removed in 5.0
|
|
8
|
+
|
|
9
|
+
See [upgrading-5.md](./upgrading-5.md) — `motionIntensity: 'off'` / `setMotionIntensity('off')`, `reducedMotion: 'no-preference'`, `<usa-timeline scrub="js">`, shared names re-exported from category entries. Run `npx usa-codemod-5 --write src`.
|
|
10
|
+
|
|
11
|
+
# Upgrading to 2.0 (removed APIs)
|
|
12
|
+
|
|
13
|
+
Everything below was deprecated in 1.9 and is **removed in 2.0.0**. The full step-by-step list is the MIGRATION section of the [CHANGELOG](../CHANGELOG.md).
|
|
14
|
+
|
|
15
|
+
| Removed in 2.0 | Use instead |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `import { createReactHooks } from 'use-scroll-animate'` | `import { createReactHooks } from 'use-scroll-animate/react'` |
|
|
18
|
+
| `import { createVueComposables } from 'use-scroll-animate'` | `import { createVueComposables } from 'use-scroll-animate/vue'` |
|
|
19
|
+
| `module` field, `dist/index.esm.js`, `dist/index.mjs` | the `exports` map: `import` → `dist/index.js` (ESM) |
|
|
20
|
+
| `dist/index.js` as CommonJS | `require('use-scroll-animate')` → `dist/index.cjs` (`main`) |
|
|
21
|
+
| per-file declarations in `dist/types/*`, `dist/*.d.mts` | bundled `dist/*.d.ts` (ESM) / `dist/*.d.cts` (CJS), resolved through `exports` |
|
|
22
|
+
| `use-scroll-animate/dist/*` deep imports | the named entry points (`use-scroll-animate`, `/react`, `/vue`, `/svelte`, `/solid`, `/element`) |
|
|
23
|
+
|
|
24
|
+
Unchanged: the browser bundles at `dist/index.umd.js` (global `ScrollAnimate`) and `dist/element.umd.js` keep their CDN URLs (`https://unpkg.com/use-scroll-animate/dist/index.umd.js`).
|
|
25
|
+
|
|
26
|
+
Behaviour changes in 2.0 (no API removed):
|
|
27
|
+
|
|
28
|
+
- `engine` defaults to `'auto'`: the native scroll-driven timeline is used where `animation-timeline: view()` is supported, unless the element sets `duration`, `delay`, `offset` or `stagger` itself. `createScrollAnimate({ defaultEngine: 'js' })` (or `ScrollAnimate.configure({ defaultEngine: 'js' })`) restores the 1.x behaviour.
|
|
29
|
+
- Output targets ES2020 (optional chaining / nullish coalescing are no longer down-levelled). Every browser with `Animation.commitStyles()` — which the library already relied on — supports ES2020.
|
|
30
|
+
- Node ≥ 18 is declared in `engines` (only relevant for SSR imports).
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Next.js, Astro, React, Vue — using `<usa-*>` components (v2.9)
|
|
2
|
+
|
|
3
|
+
All entry points are **SSR-safe**: importing never touches `window`/`document`; `define*()` is a no-op on the server. Register on the client only.
|
|
4
|
+
|
|
5
|
+
## Next.js (App Router)
|
|
6
|
+
```tsx
|
|
7
|
+
// app/usa-provider.tsx
|
|
8
|
+
'use client';
|
|
9
|
+
import { useEffect } from 'react';
|
|
10
|
+
export function UsaProvider() {
|
|
11
|
+
useEffect(() => { import('motionary/components/lazy').then((m) => m.lazyDefine()); }, []);
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
// app/layout.tsx → <body><UsaProvider />{children}</body>
|
|
15
|
+
```
|
|
16
|
+
The raw tags render on the server as plain HTML and upgrade on hydration. Type them with `motionary/components/jsx`:
|
|
17
|
+
```ts
|
|
18
|
+
// usa-jsx.d.ts
|
|
19
|
+
import type { UsaIntrinsicElements } from 'motionary/components/jsx';
|
|
20
|
+
declare module 'react' { namespace JSX { interface IntrinsicElements extends UsaIntrinsicElements {} } }
|
|
21
|
+
```
|
|
22
|
+
Prefer typed wrappers (React 18 sets properties & `usa:*` events for you):
|
|
23
|
+
```tsx
|
|
24
|
+
'use client';
|
|
25
|
+
import * as React from 'react';
|
|
26
|
+
import { createUsaComponents } from 'motionary/components/react';
|
|
27
|
+
export const { UsaButton, UsaToggle, UsaCard } = createUsaComponents(React);
|
|
28
|
+
// <UsaToggle checked={on} onUsaChange={(e) => setOn(e.detail.checked)} />
|
|
29
|
+
```
|
|
30
|
+
Page transitions in the App Router: wrap `router.push` in `pageTransition(() => router.push(href), { effect: 'slide' })`.
|
|
31
|
+
|
|
32
|
+
## Astro
|
|
33
|
+
```astro
|
|
34
|
+
---
|
|
35
|
+
// src/layouts/Base.astro
|
|
36
|
+
---
|
|
37
|
+
<html><body>
|
|
38
|
+
<slot />
|
|
39
|
+
<script>
|
|
40
|
+
import { lazyDefine } from 'motionary/components/lazy';
|
|
41
|
+
import { enableMpaTransitions } from 'motionary/components/page';
|
|
42
|
+
lazyDefine();
|
|
43
|
+
enableMpaTransitions('fade'); // cross-page View Transitions (or use Astro's <ClientRouter />)
|
|
44
|
+
</script>
|
|
45
|
+
</body></html>
|
|
46
|
+
```
|
|
47
|
+
Use the tags directly in `.astro`, `.md` and island components. With `<ClientRouter />` call `lazyDefine()` again on `astro:page-load`.
|
|
48
|
+
|
|
49
|
+
## Vue / Nuxt
|
|
50
|
+
```js
|
|
51
|
+
// vite.config.js
|
|
52
|
+
import { isUsaElement } from 'motionary/components/vue';
|
|
53
|
+
vue({ template: { compilerOptions: { isCustomElement: isUsaElement } } });
|
|
54
|
+
// main.js (or a Nuxt client plugin: plugins/usa.client.ts)
|
|
55
|
+
import { UsaPlugin } from 'motionary/components/vue';
|
|
56
|
+
app.use(UsaPlugin); // or app.use(UsaPlugin, { categories: ['click', 'ui'] })
|
|
57
|
+
```
|
|
58
|
+
`<usa-toggle :checked.prop="on" @usa:change="on = $event.detail.checked" />`
|
|
59
|
+
|
|
60
|
+
## Svelte / Solid / Angular
|
|
61
|
+
Custom elements work as-is: Svelte (`on:usa:change`), Solid (`on:usa:change`, `prop:checked`), Angular (`schemas: [CUSTOM_ELEMENTS_SCHEMA]`). Call `defineComponents()` or `lazyDefine()` in the client entry.
|
|
62
|
+
|
|
63
|
+
## Lazy registration
|
|
64
|
+
`lazyDefine()` (from `motionary/components/lazy`) watches the DOM and dynamically imports only the categories whose tags appear — a page with just `<usa-button>` loads the click chunk only.
|
|
65
|
+
|
|
66
|
+
## Svelte / SvelteKit (v3.8)
|
|
67
|
+
|
|
68
|
+
```svelte
|
|
69
|
+
<script>
|
|
70
|
+
import { onMount } from 'svelte';
|
|
71
|
+
import { usa, defineUsa } from 'motionary/components/svelte';
|
|
72
|
+
onMount(() => defineUsa());
|
|
73
|
+
let on = false;
|
|
74
|
+
</script>
|
|
75
|
+
<usa-toggle use:usa={{ props: { checked: on }, on: { change: (e) => (on = e.detail.checked) } }}></usa-toggle>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Solid / SolidStart (v3.8)
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
import { onMount } from 'solid-js';
|
|
82
|
+
import { defineUsa } from 'motionary/components/solid';
|
|
83
|
+
onMount(() => defineUsa());
|
|
84
|
+
<usa-toggle prop:checked={on()} on:usa:change={(e) => setOn(e.detail.checked)} />;
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Angular (v3.8)
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
|
|
91
|
+
import { usaInitializer, usaDetail } from 'motionary/components/angular';
|
|
92
|
+
// app.config.ts
|
|
93
|
+
providers: [{ provide: APP_INITIALIZER, multi: true, useFactory: usaInitializer() }];
|
|
94
|
+
// component
|
|
95
|
+
@Component({ standalone: true, schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
96
|
+
template: `<usa-toggle [checked]="on" (usa:change)="on = detail($event).checked"></usa-toggle>` })
|
|
97
|
+
export class Settings { on = false; detail = usaDetail; }
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
MAUI, Flutter WebView, Electron and Tauri: see [hybrid-apps.md](./hybrid-apps.md).
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Hybrid & desktop apps: MAUI, Flutter WebView, Electron, Tauri
|
|
2
|
+
|
|
3
|
+
`<usa-*>` components are plain Web Components (Custom Elements + CSS + Web Animations): anything that hosts a modern web view can run them, with **no bundler** if you want — copy `dist/components.umd.js` (and optionally `dist/components.css`) next to your HTML. For WinUI 3 / WPF / WinForms with WebView2 see [windows-apps.md](./windows-apps.md).
|
|
4
|
+
|
|
5
|
+
General rules for every host:
|
|
6
|
+
|
|
7
|
+
- **Load locally, not from a CDN**, so the app works offline and passes store review: ship `components.umd.js` as an asset and reference it with a relative URL.
|
|
8
|
+
- **Strict CSP is fine**: styles are adopted as constructable stylesheets. If you load `components.css` yourself, call `configureComponents({ injectStyles: false })`.
|
|
9
|
+
- **Reduced motion follows the OS** (`prefers-reduced-motion`) inside every web view listed here. To mirror an in-app setting, call `setMotionIntensity('off' | 'low' | 'normal' | 'high')` (or `configureComponents({ reducedMotion: 'reduce' })`) from the native side.
|
|
10
|
+
- **Performance**: canvas / WebGL effects (`<usa-shader>`, `<usa-liquid>`, backgrounds) render only while visible and cap DPR at 2; they fall back to CSS where WebGL is unavailable (some Android web views).
|
|
11
|
+
- **Native ↔ web**: listen to `usa:*` events in JS and forward them over the host bridge (examples below).
|
|
12
|
+
|
|
13
|
+
## .NET MAUI
|
|
14
|
+
|
|
15
|
+
MAUI 9+ has `HybridWebView` (raw HTML + JS bridge); `BlazorWebView` also works (Razor renders the tags; enable the elements in `wwwroot/index.html`).
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
Resources/Raw/wwwroot/
|
|
19
|
+
index.html
|
|
20
|
+
components.umd.js ← copied from node_modules/motionary/dist/
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```xml
|
|
24
|
+
<!-- MainPage.xaml -->
|
|
25
|
+
<HybridWebView x:Name="Web" DefaultFile="index.html" RawMessageReceived="OnMessage" />
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<!-- Resources/Raw/wwwroot/index.html -->
|
|
30
|
+
<script src="components.umd.js"></script>
|
|
31
|
+
<script src="_framework/hybridwebview.js"></script>
|
|
32
|
+
<usa-toggle id="t"></usa-toggle>
|
|
33
|
+
<script>
|
|
34
|
+
document.getElementById('t').addEventListener('usa:change', (e) =>
|
|
35
|
+
window.HybridWebView.SendRawMessage(JSON.stringify({ checked: e.detail.checked })));
|
|
36
|
+
</script>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```csharp
|
|
40
|
+
void OnMessage(object s, HybridWebViewRawMessageReceivedEventArgs e) => Debug.WriteLine(e.Message);
|
|
41
|
+
// native → web
|
|
42
|
+
await Web.EvaluateJavaScriptAsync("UsaComponents.setMotionIntensity('low')");
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Notes: Android uses the system WebView (Chromium) — keep it updated; iOS / Mac Catalyst use WKWebView (Safari engine), where `linear()` spring easings fall back to cubic-bezier automatically.
|
|
46
|
+
|
|
47
|
+
## Flutter (webview_flutter / flutter_inappwebview)
|
|
48
|
+
|
|
49
|
+
```yaml
|
|
50
|
+
# pubspec.yaml
|
|
51
|
+
dependencies:
|
|
52
|
+
webview_flutter: ^4.10.0
|
|
53
|
+
flutter:
|
|
54
|
+
assets:
|
|
55
|
+
- assets/web/index.html
|
|
56
|
+
- assets/web/components.umd.js
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```dart
|
|
60
|
+
final controller = WebViewController()
|
|
61
|
+
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
|
62
|
+
..addJavaScriptChannel('Usa', onMessageReceived: (m) => debugPrint(m.message))
|
|
63
|
+
..loadFlutterAsset('assets/web/index.html');
|
|
64
|
+
|
|
65
|
+
// native → web (e.g. follow the platform's "reduce motion" setting)
|
|
66
|
+
final reduce = MediaQuery.of(context).disableAnimations;
|
|
67
|
+
controller.runJavaScript("UsaComponents.setMotionIntensity('${reduce ? 'off' : 'normal'}')");
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<!-- assets/web/index.html -->
|
|
72
|
+
<script src="components.umd.js"></script>
|
|
73
|
+
<usa-like id="like"></usa-like>
|
|
74
|
+
<script>
|
|
75
|
+
document.getElementById('like').addEventListener('usa:change', (e) => Usa.postMessage(JSON.stringify(e.detail)));
|
|
76
|
+
</script>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`loadFlutterAsset` serves from a `file://`-like origin; ES-module builds (`components.js`) need an HTTP origin, so prefer the UMD file here. On Flutter Web you can use the components directly in `web/index.html` via `HtmlElementView`.
|
|
80
|
+
|
|
81
|
+
## Electron
|
|
82
|
+
|
|
83
|
+
The renderer is Chromium — use the npm package with your bundler, or the UMD file without one.
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
// renderer.js (bundled)
|
|
87
|
+
import { defineComponents, configureComponents } from 'motionary/components';
|
|
88
|
+
configureComponents({ injectStyles: true });
|
|
89
|
+
defineComponents();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
```js
|
|
93
|
+
// main.js — keep contextIsolation on; expose only what you need
|
|
94
|
+
new BrowserWindow({ webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, sandbox: true } });
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
// preload.js — forward component events to the main process
|
|
99
|
+
const { contextBridge, ipcRenderer } = require('electron');
|
|
100
|
+
contextBridge.exposeInMainWorld('usaBridge', { send: (type, detail) => ipcRenderer.send('usa', type, detail) });
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Imports are SSR-safe (no `window` access at import time), so the same modules can be imported in preload scripts.
|
|
104
|
+
|
|
105
|
+
## Tauri (v2)
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
// src/main.js (Vite)
|
|
109
|
+
import { defineComponents } from 'motionary/components';
|
|
110
|
+
import { invoke } from '@tauri-apps/api/core';
|
|
111
|
+
defineComponents();
|
|
112
|
+
document.querySelector('usa-toggle').addEventListener('usa:change', (e) => invoke('set_setting', { on: e.detail.checked }));
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
// tauri.conf.json — a strict CSP works (constructable stylesheets)
|
|
117
|
+
{ "app": { "security": { "csp": "default-src 'self'; style-src 'self'; script-src 'self'" } } }
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Tauri uses WebView2 on Windows, WKWebView on macOS / iOS and WebKitGTK on Linux. WebKitGTK may disable WebGL on some drivers: WebGL components then set `data-fallback="webgl"` and show their CSS fallback.
|
|
121
|
+
|
|
122
|
+
## Native shell bridge (4.7)
|
|
123
|
+
|
|
124
|
+
`motionary/components/bridge` keeps the page in sync with the host app's **system settings** — reduce motion, light / dark / high-contrast theme, accent color — on WinUI 3 / WPF (WebView2), .NET MAUI and Flutter:
|
|
125
|
+
|
|
126
|
+
```js
|
|
127
|
+
import { connectNativeShell } from 'motionary/components/bridge';
|
|
128
|
+
const { host } = connectNativeShell(); // 'webview2' | 'maui' | 'flutter' | 'electron' | 'tauri' | 'browser'
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Protocol (JSON): the page sends `{"type":"usa:ready","version":1}` and `{"type":"usa:request-settings"}`; the host answers (and re-sends on every system change) with `{"type":"usa:settings","reducedMotion":true,"theme":"dark","accent":"#0078d4","sensitivity":"gentle"}` — via `PostWebMessageAsJson` (WebView2), `window.postMessage`, or by running `window.usaNative.apply({...})`. Incoming values are validated (unknown fields and non-color accents are dropped); settings only affect presentation.
|
|
132
|
+
|
|
133
|
+
Complete samples: [examples/native](../examples/native/) — `winui3/MainWindow.xaml.cs` (`UISettings.AnimationsEnabled`, accent, high contrast), `maui/MainPage.xaml.cs` (Android animator scale, iOS Reduce Motion, Windows `UISettings`, `RequestedThemeChanged`), `flutter/lib/main.dart` (`MediaQuery.disableAnimations`, brightness, high contrast via a `UsaBridge` JavaScriptChannel).
|
|
134
|
+
|
|
135
|
+
Helpers: `detectNativeHost()`, `postToNative(msg)`, `parseNativeSettings(data)`, `applyNativeSettings(settings)`; event `usa:native-settings` on `document`.
|
|
136
|
+
|
|
137
|
+
## Framework wrappers
|
|
138
|
+
|
|
139
|
+
| Framework | Entry | What it gives you |
|
|
140
|
+
|---|---|---|
|
|
141
|
+
| React | `motionary/components/react` | `createUsaComponents(React)` typed wrappers |
|
|
142
|
+
| Vue | `motionary/components/vue` | `UsaPlugin`, `isUsaElement` |
|
|
143
|
+
| Svelte | `motionary/components/svelte` | `use:usa={{ props, on }}` action, `defineUsa()` |
|
|
144
|
+
| Solid | `motionary/components/solid` | `use:usa` directive, `defineUsa()`, JSX types |
|
|
145
|
+
| Angular | `motionary/components/angular` | `usaInitializer()` for `APP_INITIALIZER`, `usaDetail()`; use `CUSTOM_ELEMENTS_SCHEMA` |
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Migrating from AOS (Animate On Scroll)
|
|
2
|
+
|
|
3
|
+
AOS and `motionary` work the same way at the markup level — mark elements with attributes and call `init()` — so most pages migrate with a search-and-replace.
|
|
4
|
+
|
|
5
|
+
## 1. Install and initialise
|
|
6
|
+
|
|
7
|
+
```diff
|
|
8
|
+
- import AOS from 'aos';
|
|
9
|
+
- import 'aos/dist/aos.css';
|
|
10
|
+
- AOS.init({ duration: 800, once: true, offset: 120 });
|
|
11
|
+
+ import ScrollAnimate from 'motionary';
|
|
12
|
+
+ ScrollAnimate.configure({ defaultDuration: 800, defaultOnce: true, defaultOffset: 120 });
|
|
13
|
+
+ ScrollAnimate.watch(); // like init(), and also picks up elements added later (AOS.refreshHard())
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
No stylesheet is needed: animations run through the Web Animations API (or opt into CSS classes with `useClassNames: true`).
|
|
17
|
+
|
|
18
|
+
## 2. Attributes
|
|
19
|
+
|
|
20
|
+
| AOS | motionary |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `data-aos="fade-up"` | `data-sa data-sa-animation="fade-in-up"` |
|
|
23
|
+
| `data-aos-duration="800"` | `data-sa-duration="800"` |
|
|
24
|
+
| `data-aos-delay="200"` | `data-sa-delay="200"` |
|
|
25
|
+
| `data-aos-easing="ease-in-out"` | `data-sa-easing="ease-in-out"` (also `spring`, `soft-spring`, `heavy-bounce`, `[x1,y1,x2,y2]`) |
|
|
26
|
+
| `data-aos-offset="120"` | `data-sa-offset="120"` |
|
|
27
|
+
| `data-aos-once="true"` | `data-sa-once` (default) |
|
|
28
|
+
| `data-aos-mirror="true"` (animate out when scrolling past) | `data-sa-exit` |
|
|
29
|
+
| `data-aos-anchor-placement="top-center"` | `data-sa-threshold="0.5"` or `data-sa-root-margin="0px 0px -50% 0px"` |
|
|
30
|
+
| `data-aos-anchor=".other"` | `timeline()` played when `.other` enters (or `<usa-timeline>` around it) |
|
|
31
|
+
|
|
32
|
+
## 3. Animation names
|
|
33
|
+
|
|
34
|
+
| AOS | motionary |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `fade` | `fade-in` |
|
|
37
|
+
| `fade-up` / `fade-down` | `fade-in-up` / `fade-in-down` |
|
|
38
|
+
| `fade-left` / `fade-right` | `fade-in-right` / `fade-in-left` (see the note below) |
|
|
39
|
+
| `fade-up-right` etc. | `['fade-in-up', 'fade-in-left']` (combine presets) |
|
|
40
|
+
| `flip-up` / `flip-down` | `flip-up` / `flip-down` |
|
|
41
|
+
| `flip-left` / `flip-right` | `flip-y` |
|
|
42
|
+
| `slide-up` / `slide-down` / `slide-left` / `slide-right` | `slide-up` / `slide-down` / `slide-right` / `slide-left` |
|
|
43
|
+
| `zoom-in` / `zoom-out` | `zoom-in` / `zoom-out` |
|
|
44
|
+
| `zoom-in-up` etc. | `['zoom-in', 'fade-in-up']` |
|
|
45
|
+
|
|
46
|
+
**Left/right naming:** AOS names the direction of travel — `fade-left` moves *towards* the left, i.e. comes in from the right. Here presets name where the element comes *from*: `fade-in-right` comes in from the right. Same for `slide-*`.
|
|
47
|
+
|
|
48
|
+
## 4. Global options
|
|
49
|
+
|
|
50
|
+
| `AOS.init({...})` | `createScrollAnimate({...})` / `configure()` |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `duration`, `delay`, `easing`, `offset`, `once` | `defaultDuration`, `defaultDelay`, `defaultEasing`, `defaultOffset`, `defaultOnce` |
|
|
53
|
+
| `mirror: true` | per element `exit: true` (or `data-sa-exit`) |
|
|
54
|
+
| `disable: 'mobile'` / function | `disabled: window.matchMedia('(max-width: 600px)').matches` |
|
|
55
|
+
| `startEvent`, `initClassName`, `animatedClassName` | `useClassNames`, `hiddenClass`, `visibleClass` |
|
|
56
|
+
| `throttleDelay`, `debounceDelay` | not needed (IntersectionObserver, no scroll listener) |
|
|
57
|
+
|
|
58
|
+
## 5. Events and refresh
|
|
59
|
+
|
|
60
|
+
| AOS | motionary |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `document.addEventListener('aos:in', ...)` | `onEnter` / `onStart` options, or `<scroll-animate>`'s `sa:enter` / `sa:start` events |
|
|
63
|
+
| `aos:out` | `onLeave` |
|
|
64
|
+
| `AOS.refresh()` | `ScrollAnimate.refresh()` |
|
|
65
|
+
| `AOS.refreshHard()` | `ScrollAnimate.watch()` handles DOM changes automatically |
|
|
66
|
+
|
|
67
|
+
`prefers-reduced-motion` is respected out of the box (AOS needs `disable`).
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Migrating from GSAP ScrollTrigger
|
|
2
|
+
|
|
3
|
+
GSAP + ScrollTrigger is a full animation platform; `motionary` covers the common scroll cases — reveal on enter, staggered lists, timelines, scrubbed progress and parallax — in a few kB with no dependencies. If you rely on pinning, `snap`, morphing or arbitrary property tweens, keep GSAP for those parts.
|
|
4
|
+
|
|
5
|
+
## Reveal on enter
|
|
6
|
+
|
|
7
|
+
```diff
|
|
8
|
+
- gsap.from('.card', { opacity: 0, y: 40, duration: 0.6, scrollTrigger: { trigger: '.card', start: 'top 90%', once: true } });
|
|
9
|
+
+ ScrollAnimate.observe('.card', { animation: 'fade-in-up', duration: 600 });
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
| ScrollTrigger | motionary |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `start: 'top 90%'` | `threshold` / `rootMargin` (`'0px 0px -10% 0px'`) or `offset` (px) |
|
|
15
|
+
| `once: true` | `once: true` (default) |
|
|
16
|
+
| `toggleActions: 'play none none reverse'` | `exit: true` (reverse on leave, replay on enter) |
|
|
17
|
+
| `toggleActions: 'restart none none reset'` | `repeat: true` |
|
|
18
|
+
| `onEnter`, `onLeave`, `onEnterBack`, `onLeaveBack` | `onEnter`, `onLeave` (both directions) |
|
|
19
|
+
| custom `from` vars (`{ opacity: 0, rotate: -10 }`) | `animation: { from: { opacity: 0, transform: 'rotate(-10deg)' }, to: { opacity: 1, transform: 'rotate(0deg)' } }` |
|
|
20
|
+
| `ease: 'back.out(1.7)'` | `easing: 'soft-spring'`, `[0.34, 1.56, 0.64, 1]` or `(t) => …` |
|
|
21
|
+
|
|
22
|
+
## Staggered lists
|
|
23
|
+
|
|
24
|
+
```diff
|
|
25
|
+
- gsap.from('.list li', { opacity: 0, y: 20, stagger: 0.08, scrollTrigger: '.list' });
|
|
26
|
+
+ staggerChildren(document.querySelector('.list'), { animation: 'fade-in-up', stagger: 80 });
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`observeChildren: true` also animates items appended later (infinite lists).
|
|
30
|
+
|
|
31
|
+
## Timelines
|
|
32
|
+
|
|
33
|
+
```diff
|
|
34
|
+
- const tl = gsap.timeline({ scrollTrigger: '.hero' });
|
|
35
|
+
- tl.from('.title', { opacity: 0, y: 40 })
|
|
36
|
+
- .from('.subtitle', { opacity: 0 }, '-=0.2')
|
|
37
|
+
- .from('.cta', { scale: 0.8, opacity: 0 }, 1.2);
|
|
38
|
+
+ const tl = timeline()
|
|
39
|
+
+ .to('.title', 'fade-up')
|
|
40
|
+
+ .to('.subtitle', 'fade', { at: '-=200' })
|
|
41
|
+
+ .to('.cta', 'scale', { at: 1200 });
|
|
42
|
+
+ tl.scrub(document.querySelector('.hero')); // or tl.play() when it enters
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`play()` / `reverse()` return Promises; `seek()`, `progress()`, labels and `scrub()` work like GSAP's timeline controls.
|
|
46
|
+
|
|
47
|
+
## Scrub (progress-linked) animations
|
|
48
|
+
|
|
49
|
+
```diff
|
|
50
|
+
- gsap.to('.bar', { scaleX: 1, ease: 'none', scrollTrigger: { trigger: '.bar', start: 'top bottom', end: 'bottom top', scrub: true } });
|
|
51
|
+
+ ScrollAnimate.observe('.bar', { progressVar: '--p', progressMode: 'scroll' });
|
|
52
|
+
+ /* CSS */ .bar { transform: scaleX(var(--p, 0)); }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Or let the browser drive a preset natively where scroll-driven animations are supported:
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
ScrollAnimate.observe('.card', { animation: 'zoom-in', engine: 'auto', viewRange: ['entry 0%', 'cover 50%'] });
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`progressMode: 'scroll'` matches ScrollTrigger's `start: 'top bottom', end: 'bottom top'`; `onProgress(el, p)` is the equivalent of `onUpdate: self => self.progress`.
|
|
62
|
+
|
|
63
|
+
## Parallax
|
|
64
|
+
|
|
65
|
+
```diff
|
|
66
|
+
- gsap.to('.bg', { yPercent: 20, ease: 'none', scrollTrigger: { trigger: '.hero', scrub: true } });
|
|
67
|
+
+ parallax('.bg', { speed: 0.2 });
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Cleanup
|
|
71
|
+
|
|
72
|
+
| GSAP | motionary |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `ScrollTrigger.refresh()` | `refresh()` |
|
|
75
|
+
| `trigger.kill()` / `ScrollTrigger.getAll().forEach(t => t.kill())` | `unobserve(target)` / `destroy()` |
|
|
76
|
+
| `gsap.matchMedia()` for reduced motion | built in: `prefers-reduced-motion` shows content without motion |
|
|
77
|
+
|
|
78
|
+
## Not covered
|
|
79
|
+
|
|
80
|
+
Pinning (`pin: true`), `snap`, horizontal scroll sections driven by a pinned container, and non-CSS tweening (canvas, SVG morphing, number counters) have no equivalent — combine `onProgress` with your own code, or keep GSAP for those.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* motionary motion tokens (4.2) — generated from MOTION_TOKENS */
|
|
2
|
+
:root {
|
|
3
|
+
--usa-duration-instant: 0ms;
|
|
4
|
+
--usa-duration-fast: 150ms;
|
|
5
|
+
--usa-duration-normal: 300ms;
|
|
6
|
+
--usa-duration-slow: 600ms;
|
|
7
|
+
--usa-duration-slower: 900ms;
|
|
8
|
+
--usa-duration-slowest: 1400ms;
|
|
9
|
+
--usa-easing-linear: linear;
|
|
10
|
+
--usa-easing-standard: cubic-bezier(0.2, 0, 0, 1);
|
|
11
|
+
--usa-easing-emphasized: cubic-bezier(0.22, 1, 0.36, 1);
|
|
12
|
+
--usa-easing-decelerate: cubic-bezier(0, 0, 0, 1);
|
|
13
|
+
--usa-easing-accelerate: cubic-bezier(0.3, 0, 1, 1);
|
|
14
|
+
--usa-easing-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
15
|
+
--usa-easing-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
|
16
|
+
--usa-spring-gentle-stiffness: 120;
|
|
17
|
+
--usa-spring-gentle-damping: 14;
|
|
18
|
+
--usa-spring-gentle-mass: 1;
|
|
19
|
+
--usa-spring-snappy-stiffness: 300;
|
|
20
|
+
--usa-spring-snappy-damping: 30;
|
|
21
|
+
--usa-spring-snappy-mass: 1;
|
|
22
|
+
--usa-spring-bouncy-stiffness: 260;
|
|
23
|
+
--usa-spring-bouncy-damping: 12;
|
|
24
|
+
--usa-spring-bouncy-mass: 1;
|
|
25
|
+
--usa-spring-wobbly-stiffness: 180;
|
|
26
|
+
--usa-spring-wobbly-damping: 8;
|
|
27
|
+
--usa-spring-wobbly-mass: 1;
|
|
28
|
+
--usa-spring-stiff-stiffness: 500;
|
|
29
|
+
--usa-spring-stiff-damping: 40;
|
|
30
|
+
--usa-spring-stiff-mass: 1;
|
|
31
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Motion design tokens (4.2)
|
|
2
|
+
|
|
3
|
+
`motionary/components/tokens` gives your product one motion scale — durations, easings and springs — as **CSS custom properties**, **W3C Design Tokens JSON**, and **JS values**, and imports the scale your designers keep in **Figma Tokens (Tokens Studio)** or **Style Dictionary**.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { applyMotionTokens, importMotionTokens, motionToken, motionVar } from 'motionary/components/tokens';
|
|
7
|
+
|
|
8
|
+
// 1. Use the defaults (writes --usa-* variables on <html>)…
|
|
9
|
+
applyMotionTokens();
|
|
10
|
+
// 2. …or your own scale, from a Figma Tokens / Style Dictionary / DTCG export
|
|
11
|
+
applyMotionTokens(importMotionTokens(await (await fetch('/design/tokens.json')).json()));
|
|
12
|
+
|
|
13
|
+
motionToken('duration', 'fast'); // 150
|
|
14
|
+
motionToken('easing', 'emphasized'); // 'cubic-bezier(0.22, 1, 0.36, 1)'
|
|
15
|
+
motionVar('duration', 'slow'); // 'var(--usa-duration-slow, 600ms)'
|
|
16
|
+
timeline().to('.card', 'fade-up', { duration: 'slow', easing: 'spring' }); // token names work
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```css
|
|
20
|
+
.button { transition: transform var(--usa-duration-fast) var(--usa-easing-emphasized); }
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Default scale
|
|
24
|
+
|
|
25
|
+
| Group | Tokens |
|
|
26
|
+
|---|---|
|
|
27
|
+
| `duration` (ms) | `instant` 0 · `fast` 150 · `normal` 300 · `slow` 600 · `slower` 900 · `slowest` 1400 |
|
|
28
|
+
| `easing` | `linear` · `standard` · `emphasized` · `decelerate` · `accelerate` · `spring` · `bounce` |
|
|
29
|
+
| `spring` (stiffness / damping / mass) | `gentle` 120/14/1 · `snappy` 300/30/1 · `bouncy` 260/12/1 · `wobbly` 180/8/1 · `stiff` 500/40/1 |
|
|
30
|
+
|
|
31
|
+
Prebuilt files: [`docs/motion-tokens.css`](./motion-tokens.css) and [`docs/motion.tokens.json`](./motion.tokens.json) (DTCG; `$type: duration | cubicBezier | spring`).
|
|
32
|
+
|
|
33
|
+
## API
|
|
34
|
+
|
|
35
|
+
| Function | |
|
|
36
|
+
|---|---|
|
|
37
|
+
| `MOTION_TOKENS` | The default scale. |
|
|
38
|
+
| `applyMotionTokens(partial?, root?, prefix?)` | Merge over the defaults, write `--usa-*` vars on `root` (default `<html>`), make it the active scale. Returns undo. |
|
|
39
|
+
| `importMotionTokens(json, base?)` | DTCG (`$value`/`$type`), Tokens Studio (`value`/`type`), Style Dictionary (`value`, nested). Reads leaves under any `duration` / `easing` / `spring` group (any depth) and typed leaves (`duration`, `cubicBezier`, `transition`, `spring`). |
|
|
40
|
+
| `motionTokensToCss(tokens?, selector?, prefix?)` · `motionTokensToVars()` · `motionTokensToJSON()` | Export. |
|
|
41
|
+
| `motionToken(group, name)` · `motionVar(group, name, prop?)` · `getMotionTokens()` | Read. |
|
|
42
|
+
| `parseDuration()` · `parseEasing()` · `mergeMotionTokens()` · `resolveDurationToken()` · `resolveEasingToken()` | Helpers. |
|
|
43
|
+
|
|
44
|
+
## Style Dictionary
|
|
45
|
+
|
|
46
|
+
Point Style Dictionary at `docs/motion.tokens.json` as a source, or export your own motion group and import it at runtime with `importMotionTokens()`. Tokens are plain data, so SSR is fine; `applyMotionTokens()` is a no-op without a DOM (it still sets the active scale).
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
{
|
|
2
|
+
"motion": {
|
|
3
|
+
"duration": {
|
|
4
|
+
"instant": {
|
|
5
|
+
"$type": "duration",
|
|
6
|
+
"$value": "0ms"
|
|
7
|
+
},
|
|
8
|
+
"fast": {
|
|
9
|
+
"$type": "duration",
|
|
10
|
+
"$value": "150ms"
|
|
11
|
+
},
|
|
12
|
+
"normal": {
|
|
13
|
+
"$type": "duration",
|
|
14
|
+
"$value": "300ms"
|
|
15
|
+
},
|
|
16
|
+
"slow": {
|
|
17
|
+
"$type": "duration",
|
|
18
|
+
"$value": "600ms"
|
|
19
|
+
},
|
|
20
|
+
"slower": {
|
|
21
|
+
"$type": "duration",
|
|
22
|
+
"$value": "900ms"
|
|
23
|
+
},
|
|
24
|
+
"slowest": {
|
|
25
|
+
"$type": "duration",
|
|
26
|
+
"$value": "1400ms"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"easing": {
|
|
30
|
+
"linear": {
|
|
31
|
+
"$type": "string",
|
|
32
|
+
"$value": "linear"
|
|
33
|
+
},
|
|
34
|
+
"standard": {
|
|
35
|
+
"$type": "cubicBezier",
|
|
36
|
+
"$value": [
|
|
37
|
+
0.2,
|
|
38
|
+
0,
|
|
39
|
+
0,
|
|
40
|
+
1
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"emphasized": {
|
|
44
|
+
"$type": "cubicBezier",
|
|
45
|
+
"$value": [
|
|
46
|
+
0.22,
|
|
47
|
+
1,
|
|
48
|
+
0.36,
|
|
49
|
+
1
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"decelerate": {
|
|
53
|
+
"$type": "cubicBezier",
|
|
54
|
+
"$value": [
|
|
55
|
+
0,
|
|
56
|
+
0,
|
|
57
|
+
0,
|
|
58
|
+
1
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"accelerate": {
|
|
62
|
+
"$type": "cubicBezier",
|
|
63
|
+
"$value": [
|
|
64
|
+
0.3,
|
|
65
|
+
0,
|
|
66
|
+
1,
|
|
67
|
+
1
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"spring": {
|
|
71
|
+
"$type": "cubicBezier",
|
|
72
|
+
"$value": [
|
|
73
|
+
0.34,
|
|
74
|
+
1.56,
|
|
75
|
+
0.64,
|
|
76
|
+
1
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
"bounce": {
|
|
80
|
+
"$type": "cubicBezier",
|
|
81
|
+
"$value": [
|
|
82
|
+
0.68,
|
|
83
|
+
-0.55,
|
|
84
|
+
0.265,
|
|
85
|
+
1.55
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"spring": {
|
|
90
|
+
"gentle": {
|
|
91
|
+
"$type": "spring",
|
|
92
|
+
"$value": {
|
|
93
|
+
"stiffness": 120,
|
|
94
|
+
"damping": 14,
|
|
95
|
+
"mass": 1
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"snappy": {
|
|
99
|
+
"$type": "spring",
|
|
100
|
+
"$value": {
|
|
101
|
+
"stiffness": 300,
|
|
102
|
+
"damping": 30,
|
|
103
|
+
"mass": 1
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"bouncy": {
|
|
107
|
+
"$type": "spring",
|
|
108
|
+
"$value": {
|
|
109
|
+
"stiffness": 260,
|
|
110
|
+
"damping": 12,
|
|
111
|
+
"mass": 1
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"wobbly": {
|
|
115
|
+
"$type": "spring",
|
|
116
|
+
"$value": {
|
|
117
|
+
"stiffness": 180,
|
|
118
|
+
"damping": 8,
|
|
119
|
+
"mass": 1
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"stiff": {
|
|
123
|
+
"$type": "spring",
|
|
124
|
+
"$value": {
|
|
125
|
+
"stiffness": 500,
|
|
126
|
+
"damping": 40,
|
|
127
|
+
"mass": 1
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Performance (4.5)
|
|
2
|
+
|
|
3
|
+
## One frame loop
|
|
4
|
+
Every `<usa-*>` loop (cursors, particles, springs, marquees, WebGL, scroll effects…) schedules work through **one shared `requestAnimationFrame`**: callbacks registered during a frame run together, in order, and a throwing callback no longer starves the rest. Use it for your own loops:
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
import { onFrame, schedulerStats } from 'motionary/components/perf';
|
|
8
|
+
const stop = onFrame((time, dt) => { /* … */ });
|
|
9
|
+
schedulerStats(); // { frames, callbacks, peak, pending, loops }
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Animation budget & auto-degrade
|
|
13
|
+
- `setAnimationBudget(n)` caps concurrent component animations; extra ones land on their final frame instantly. `activeAnimations()` reports the current count.
|
|
14
|
+
- `autoDegrade({ minFps = 45, maxActive = 40, sample = 1000, patience = 2, recovery = 3 })` samples the frame rate and animation count. After `patience` bad samples it sets motion intensity to `low` and the budget to `maxActive / 2`; after `recovery` good samples it restores both. Dispatches `usa:degrade` (`{ degraded, fps, active, reason }`).
|
|
15
|
+
|
|
16
|
+
## On-demand CSS — `motionary/components/lite`
|
|
17
|
+
Same API as `motionary/components`, but the light-DOM CSS is **not** inlined: the first time an element of a category connects, `dist/components/<category>.css` is added as a `<link>` (custom tag names fall back to `components.css`). Shadow-DOM styles stay inlined.
|
|
18
|
+
|
|
19
|
+
| Import | gzip |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `motionary/components` (everything, CSS inlined) | ≈ 79 KB |
|
|
22
|
+
| `motionary/components/lite` (everything, CSS on demand) | **≈ 62 KB** (budget 70 KB, checked in CI) |
|
|
23
|
+
|
|
24
|
+
Serve the CSS from somewhere else with `onDemandStyles('https://cdn.example/motionary@6/dist/')`, or preload with `loadCategoryStyles('cards', base)`.
|