motionary 0.0.0-stage → 6.1.1
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 +784 -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-Yno7N2eC.js +404 -0
- package/dist/chunks/base-Yno7N2eC.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-BIOaYdgN.js +181 -0
- package/dist/chunks/core-BIOaYdgN.js.map +1 -0
- package/dist/chunks/core-CUGCsMsJ.js +260 -0
- package/dist/chunks/core-CUGCsMsJ.js.map +1 -0
- package/dist/chunks/core-D7cVumUu.js +909 -0
- package/dist/chunks/core-D7cVumUu.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-BqDeFywO.js +109 -0
- package/dist/chunks/fx-BqDeFywO.js.map +1 -0
- package/dist/chunks/fx-lBGVtQO1.cjs +114 -0
- package/dist/chunks/fx-lBGVtQO1.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/spring-DfQO5USi.js +219 -0
- package/dist/chunks/spring-DfQO5USi.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-VNscPeTD.js +35 -0
- package/dist/chunks/variants-VNscPeTD.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 +75 -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 +69 -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 +2590 -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 +2531 -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.cjs +289 -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 +275 -0
- package/dist/components/fx.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 +11099 -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 +10831 -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 +85 -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 +81 -0
- package/dist/components/solid.js.map +1 -0
- package/dist/components/svelte.cjs +67 -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 +63 -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 +66 -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 +63 -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.cjs +350 -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 +105 -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/docs/API.md +147 -0
- package/docs/ROADMAP.md +15 -0
- package/docs/accessibility.md +60 -0
- package/docs/components.md +535 -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 +532 -4
package/README_zh.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# Motionary
|
|
4
|
+
|
|
5
|
+
**面向现代 Web 的滚动动画与动画 Web Components —— 214 个滚动预设、90 种效果、零依赖。**
|
|
6
|
+
|
|
7
|
+
_原名 **use-scroll-animate** —— API 与 `<usa-*>` 标签完全不变;旧 npm 包继续作为别名发布。_
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/motionary) [](https://github.com/HarrisonCN/motionary/actions/workflows/ci.yml) [](./LICENSE)
|
|
10
|
+
|
|
11
|
+
[English](./README.md) | [简体中文](./README_zh.md) | [日本語](./README_ja.md)
|
|
12
|
+
|
|
13
|
+
**[🛍 动画商店](https://harrisoncn.github.io/motionary/showcase/)** · **[🧩 组件](https://harrisoncn.github.io/motionary/showcase/components.html)** · **[🎛 Playground](https://harrisoncn.github.io/motionary/showcase/playground.html)** · **[📜 滚动叙事](https://harrisoncn.github.io/motionary/showcase/story.html)**
|
|
14
|
+
|
|
15
|
+
<sub>动画商店可预览、调整并复制全部 <b>227</b> 个动画 —— 214 个滚动预设,以及卡片、点击、物理与整页效果 —— 支持桌面与手机尺寸。</sub>
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
Motionary 在内容滚入视口时播放入场动画(IntersectionObserver + Web Animations,或浏览器原生滚动时间线),并提供 94 个动画自定义元素 —— 卡片、按钮、物理、页面转场、背景、WebGL 等 —— 可用于任何框架、纯 HTML 以及桌面 Web 视图应用(Electron、Tauri、WebView2)。全部遵循 `prefers-reduced-motion`。
|
|
20
|
+
|
|
21
|
+
## 安装
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm i motionary
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<!-- CDN (no build) -->
|
|
29
|
+
<script src="https://unpkg.com/motionary@6/dist/index.umd.js"></script> <!-- window.ScrollAnimate -->
|
|
30
|
+
<script src="https://unpkg.com/motionary@6/dist/presets-extended.umd.js"></script> <!-- +181 presets -->
|
|
31
|
+
<script src="https://unpkg.com/motionary@6/dist/components.umd.js"></script> <!-- every <usa-*>, window.UsaComponents -->
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
jsDelivr 同样可用:`https://cdn.jsdelivr.net/npm/motionary@6/dist/…`。已有的 `use-scroll-animate` 安装与 `unpkg.com/use-scroll-animate@6` 链接继续可用。
|
|
35
|
+
|
|
36
|
+
## 30 秒上手
|
|
37
|
+
|
|
38
|
+
给元素加上 `data-sa`,用 `data-sa-animation` 选择预设(每个选项都有对应的 `data-sa-*` 属性),或使用 JS API:
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<!-- 1. HTML only: data attributes + one init() call -->
|
|
42
|
+
<h2 data-sa data-sa-animation="fade-in-up">Hello</h2>
|
|
43
|
+
<div data-sa data-sa-animation="bounce-in-up" data-sa-delay="150">Card</div>
|
|
44
|
+
<script type="module">
|
|
45
|
+
import ScrollAnimate from 'motionary';
|
|
46
|
+
import 'motionary/presets/extended'; // optional: +181 presets (bounce-in-up, clip-diamond, …)
|
|
47
|
+
ScrollAnimate.init(); // picks up every [data-sa]
|
|
48
|
+
</script>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
// 2. JS API
|
|
53
|
+
import ScrollAnimate, { staggerChildren, parallax, timeline } from 'motionary';
|
|
54
|
+
|
|
55
|
+
ScrollAnimate.observe('.card', { animation: 'zoom-in-up', duration: 800, easing: 'spring' });
|
|
56
|
+
staggerChildren(document.querySelector('.grid'), { animation: 'stagger-pop', stagger: 60 });
|
|
57
|
+
parallax('.hero-bg', { speed: 0.3 });
|
|
58
|
+
ScrollAnimate.observe('.logo', { animation: 'scrub-spin', engine: 'css', viewRange: ['cover 0%', 'cover 100%'] });
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
框架 —— 每个适配器都是独立入口,卸载时自动清理:
|
|
62
|
+
|
|
63
|
+
```jsx
|
|
64
|
+
// React
|
|
65
|
+
import React from 'react';
|
|
66
|
+
import { createReactHooks } from 'motionary/react';
|
|
67
|
+
const { useScrollAnimate } = createReactHooks(React);
|
|
68
|
+
|
|
69
|
+
export function Card() {
|
|
70
|
+
const ref = useScrollAnimate({ animation: 'fade-in-up' });
|
|
71
|
+
return <div ref={ref}>Hello</div>;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```vue
|
|
76
|
+
<!-- Vue 3 -->
|
|
77
|
+
<script setup>
|
|
78
|
+
import { ref, onMounted, onUnmounted } from 'vue';
|
|
79
|
+
import { createVueComposables } from 'motionary/vue';
|
|
80
|
+
const { useScrollAnimate } = createVueComposables({ ref, onMounted, onUnmounted });
|
|
81
|
+
const { animateRef } = useScrollAnimate({ animation: 'zoom-in' });
|
|
82
|
+
</script>
|
|
83
|
+
<template><div ref="animateRef">Hello</div></template>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```svelte
|
|
87
|
+
<!-- Svelte 3–5 -->
|
|
88
|
+
<script>
|
|
89
|
+
import { scrollAnimate } from 'motionary/svelte';
|
|
90
|
+
</script>
|
|
91
|
+
<div use:scrollAnimate={{ animation: 'flip-up' }}>Hello</div>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
```jsx
|
|
95
|
+
// Solid
|
|
96
|
+
import { scrollAnimate } from 'motionary/solid';
|
|
97
|
+
scrollAnimate; // keep the directive import (TypeScript)
|
|
98
|
+
export const Card = () => <div use:scrollAnimate={{ animation: 'blur-in-up' }}>Hello</div>;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
// Angular (standalone) — the animated Web Components
|
|
103
|
+
import { APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
|
|
104
|
+
import { usaInitializer } from 'motionary/components/angular';
|
|
105
|
+
import 'motionary/presets/extended'; // lets <usa-reveal effect> use every preset name
|
|
106
|
+
// app.config.ts: providers: [{ provide: APP_INITIALIZER, multi: true, useFactory: usaInitializer() }]
|
|
107
|
+
@Component({ standalone: true, schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
108
|
+
template: `<usa-reveal effect="bounce-in-up"><h2>Hello</h2></usa-reveal>` })
|
|
109
|
+
export class Hero {}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
动画组件无需任何框架:
|
|
113
|
+
|
|
114
|
+
```html
|
|
115
|
+
<script type="module">
|
|
116
|
+
import { defineComponents } from 'motionary/components';
|
|
117
|
+
defineComponents(); // or lazyDefine() from 'motionary/components/lazy'
|
|
118
|
+
</script>
|
|
119
|
+
<usa-card effect="holo">…</usa-card>
|
|
120
|
+
<usa-button deform="gooey">Buy</usa-button>
|
|
121
|
+
<usa-fx effect="confetti" trigger="click"><button>Celebrate</button></usa-fx>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## 功能一览
|
|
125
|
+
|
|
126
|
+
| 领域 | 内容 |
|
|
127
|
+
|---|---|
|
|
128
|
+
| **滚动预设** | **214** 个入场预设(33 个核心 + 181 个位于 `motionary/presets/extended`),14 个系列:淡入、缩放、3D 翻转与开门、回弹滑入、clip-path 形状、模糊与遮罩、弹跳与弹性、色彩与光影、景深、故障 / 打字机、错峰列表与随滚动 `scrub-*`;另有 `timeline()` 与 10 个时间线预设 |
|
|
129
|
+
| **卡片、点击与按钮形变** | `<usa-card>` 含 10 种效果(翻转、全息、玻璃、边框光晕……),卡片堆叠与 3D 轮播;7 个点击组件、4 种按钮形变(squash · wobble · gooey · dent)与图标变形;12 个注册的卡片 / 点击效果(holo、book-open、shockwave、ink-splash、emoji-rain……) |
|
|
130
|
+
| **物理与弹跳** | `<usa-spring>`、`<usa-draggable>`(回弹 · 惯性 · 吸附)、`<usa-overscroll>`;`spring()` / `solveSpring()` 与 7 个弹簧预设;7 个物理效果(bounce-in、rubber-band、gravity-text、bell-swing……) |
|
|
131
|
+
| **页面转场** | `pageTransition()`、`viewTransition()`、`sharedTransition()`、`flip()`、多页(MPA)转场;7 个页面效果(curtain、iris、pixel-dissolve、blinds、velocity-skew……);`<usa-dialog>`、`<usa-view-switch>` |
|
|
132
|
+
| **生成式背景** | 6 种画布背景(flow-field、voronoi、mesh-gradient、starfield、metaballs、contours)+ 9 个背景元素(极光、粒子、胶片颗粒、流体色块、水波、亚克力 / 云母……) |
|
|
133
|
+
| **声音响应** | `<usa-audio>` + Web Audio 节拍检测(`createBeatDetector()`、`onBeat()`);3 种音频可视化(spectrum-bars、pulse-ring、wave-ring);任意效果都可随节拍触发 |
|
|
134
|
+
| **光标与手势** | 5 种光标效果(彗星 / 丝带 / 星光拖尾、磁性圆点、聚光灯)+ `<usa-cursor>`;甩动 · 旋转 · 长按触发效果(`<usa-gesture-fx>`);`<usa-swipeable>`、`<usa-pinch-zoom>` |
|
|
135
|
+
| **主题** | 5 套主题(neon · paper · glass · retro · brutalist),通过 `<usa-theme>` / `applyTheme()` 使用,各带一个标志性效果;动效令牌(`/components/tokens`) |
|
|
136
|
+
| **微交互** | 23 个现成的界面瞬间:copy-success、like-heart、add-to-cart、send-plane、upvote、trash-shake、input-shake、success-check、notify-badge…… |
|
|
137
|
+
| **`<usa-player>` 与滚动叙事** | `<usa-player>` 播放 JSON 动画(关键帧轨道、预设、效果;load / view / scroll / click 触发),可从 Playground 导出;`<usa-story>` 含 6 个滚动叙事模板 |
|
|
138
|
+
| **WebGL** | `<usa-shader>`、`<usa-distort>`、`<usa-liquid>`、`<usa-post-fx>` —— 5 个粒子预设、9 种后期效果(bloom、CRT、色散、故障……),带 CSS 降级与省电调速 |
|
|
139
|
+
|
|
140
|
+
90 种效果共用一个注册表(`registerEffect()` / `playEffect()` / `bindEffect()` / `<usa-fx>`,位于 `motionary/components/fx`);5.x 效果包位于 `motionary/components/effects`。
|
|
141
|
+
|
|
142
|
+
### 全部 94 个动画组件
|
|
143
|
+
|
|
144
|
+
可按分类导入(`motionary/components/cards`)、全部导入(`motionary/components`)、使用按需加载 CSS 的 `/components/lite`,或用 `lazyDefine()` 只加载页面上出现的标签。框架封装:`/components/react`、`/vue`、`/svelte`、`/solid`、`/angular`。
|
|
145
|
+
|
|
146
|
+
| 入口 | 元素 |
|
|
147
|
+
|---|---|
|
|
148
|
+
| **滚动揭示** (`/components/reveal`) | `<usa-reveal>` · `<usa-stagger>` · `<usa-scroll-progress>` · `<usa-scrolly>` |
|
|
149
|
+
| **文字** (`/components/text`) | `<usa-typewriter>` · `<usa-split-text>` · `<usa-scramble>` · `<usa-counter>` · `<usa-shimmer-text>` · `<usa-text-rotate>` · `<usa-wave-text>` · `<usa-glitch>` · `<usa-gradient-text>` · `<usa-handwriting>` · `<usa-scroll-highlight>` |
|
|
150
|
+
| **交互** (`/components/interaction`) | `<usa-ripple>` · `<usa-magnetic>` · `<usa-tilt>` · `<usa-spotlight>` · `<usa-press>` · `<usa-toggle>` |
|
|
151
|
+
| **反馈** (`/components/feedback`) | `<usa-spinner>` · `<usa-skeleton>` · `<usa-progress>` · `<usa-toaster>` · `<usa-check>` |
|
|
152
|
+
| **背景与装饰** (`/components/background`) | `<usa-aurora>` · `<usa-particles>` · `<usa-grain>` · `<usa-marquee>` · `<usa-acrylic>` · `<usa-grid-glow>` · `<usa-blobs>` · `<usa-water-ripple>` · `<usa-dot-network>` |
|
|
153
|
+
| **转场** (`/components/transitions`) | `<usa-dialog>` · `<usa-accordion>` · `<usa-view-switch>` |
|
|
154
|
+
| **弹簧与物理** (`/components/physics`) | `<usa-spring>` · `<usa-draggable>` · `<usa-overscroll>` |
|
|
155
|
+
| **卡片** (`/components/cards`) | `<usa-card>` · `<usa-card-stack>` · `<usa-sticky-stack>` · `<usa-carousel-3d>` |
|
|
156
|
+
| **点击与按钮** (`/components/click`) | `<usa-click>` · `<usa-button>` · `<usa-icon-morph>` · `<usa-like>` · `<usa-hold>` · `<usa-double-tap>` · `<usa-checkbox>` |
|
|
157
|
+
| **UI 组件** (`/components/ui`) | `<usa-tabs>` · `<usa-drawer>` · `<usa-bottom-sheet>` · `<usa-pull-refresh>` · `<usa-fab>` · `<usa-navbar>` · `<usa-slider>` · `<usa-rating>` · `<usa-tooltip>` · `<usa-popover>` · `<usa-badge>` · `<usa-avatar-stack>` |
|
|
158
|
+
| **整页** (`/components/page`) | `<usa-cursor>` · `<usa-fullpage>` · `<usa-loading-bar>` · `<usa-back-to-top>` · `<usa-ambient>` · `<usa-splash>` · `<usa-auto-skeleton>` · `<usa-motion-switch>` |
|
|
159
|
+
| **时间线** (`/components/timeline`) | `<usa-timeline>` |
|
|
160
|
+
| **手势** (`/components/gesture`) | `<usa-swipeable>` · `<usa-pinch-zoom>` |
|
|
161
|
+
| **SVG** (`/components/svg`) | `<usa-draw>` · `<usa-morph>` · `<usa-mask-reveal>` · `<usa-anim-icon>` |
|
|
162
|
+
| **WebGL** (`/components/webgl`) | `<usa-shader>` · `<usa-distort>` · `<usa-liquid>` · `<usa-post-fx>` |
|
|
163
|
+
| **3D 景深** (`/components/depth`) | `<usa-cube>` · `<usa-depth>` |
|
|
164
|
+
| **布局** (`/components/layout`) | `<usa-auto-animate>` · `<usa-masonry>` |
|
|
165
|
+
| **效果包** (`/components/packs`) | `<usa-pack>` |
|
|
166
|
+
| **效果注册表** (`/components/fx`) | `<usa-fx>` |
|
|
167
|
+
| **效果包** (`/components/effects`) | `<usa-player>` · `<usa-story>` · `<usa-audio>` · `<usa-theme>` · `<usa-gesture-fx>` |
|
|
168
|
+
|
|
169
|
+
## 无障碍与减少动态效果
|
|
170
|
+
|
|
171
|
+
- 开启 `prefers-reduced-motion: reduce` 时,滚动揭示会立即显示内容(无入场、视差或随滚动动画),组件退回平静状态(`staticAlternative()` / `adaptKeyframes()`)。
|
|
172
|
+
- `motionary/components/a11y`:`setMotionSensitivity()` 分级让用户关闭闪烁、循环或视差;`announce()` 实时播报区域;`auditMotionA11y()`;`baselineReport()`。`<usa-motion-switch>` 是现成的面向用户的动效开关。
|
|
173
|
+
- 详见 [docs/accessibility.md](./docs/accessibility.md)。
|
|
174
|
+
|
|
175
|
+
## 性能与体积
|
|
176
|
+
|
|
177
|
+
默认不监听 scroll 事件(IntersectionObserver),动画运行在合成层(`transform`、`opacity`、`filter`、`clip-path`),可选主线程之外的原生滚动时间线(`engine: 'css'`)。每个入口都可摇树,并在 CI 中强制 gzip 预算(`size-budget.json`)。6.1 实测(压缩 + gzip):
|
|
178
|
+
|
|
179
|
+
| 导入内容 | gzip |
|
|
180
|
+
|---|---:|
|
|
181
|
+
| `import ScrollAnimate from 'motionary'` (default instance) | 5.72 kB |
|
|
182
|
+
| Everything from the main entry | 8.69 kB |
|
|
183
|
+
| `dist/index.umd.js` (CDN) | 8.81 kB |
|
|
184
|
+
| `parallax()` alone | 1.22 kB |
|
|
185
|
+
| `motionary/presets/extended` (181 presets) | 4.69 kB |
|
|
186
|
+
| `motionary/components/reveal` | 4.10 kB |
|
|
187
|
+
| `motionary/components/effects` (8 effect packs) | 26.40 kB |
|
|
188
|
+
| `motionary/components/lite` (every component, CSS on demand) | 68.48 kB |
|
|
189
|
+
| `motionary/components` (every component + CSS) | 85.15 kB |
|
|
190
|
+
| `dist/components.umd.js` (CDN, everything) | 106.75 kB |
|
|
191
|
+
|
|
192
|
+
更多:[docs/performance.md](./docs/performance.md)。
|
|
193
|
+
|
|
194
|
+
## 浏览器支持
|
|
195
|
+
|
|
196
|
+
2023 年以来的常青浏览器:Chrome / Edge ≥ 111、Safari ≥ 16.4、Firefox ≥ 115、WebView2、Electron ≥ 24(Custom Elements、Web Animations、IntersectionObserver、ResizeObserver、可构造样式表)。View Transitions 与滚动驱动动画为渐进增强 —— 支持时使用,否则回退到 JS。在服务端(SSR)导入不会执行任何操作。可用 `baselineReport()` 检查浏览器。
|
|
197
|
+
|
|
198
|
+
## 文档
|
|
199
|
+
|
|
200
|
+
- [API 参考](./docs/API.md)(英文)—— 所有导出、选项与 `data-sa-*` 属性
|
|
201
|
+
- [预设一览](./docs/presets.md)(全部 214 个)
|
|
202
|
+
- [组件文档](./docs/components.md)(每个 `<usa-*>` 元素、属性与事件)
|
|
203
|
+
- [框架与 SSR](./docs/frameworks-ssr.md) · [Windows 应用](./docs/windows-apps.md) · [混合应用(MAUI、Flutter、Electron、Tauri)](./docs/hybrid-apps.md)
|
|
204
|
+
- [动效令牌](./docs/motion-tokens.md) · [从 AOS 迁移](./docs/migration-from-aos.md) · [从 GSAP ScrollTrigger 迁移](./docs/migration-from-gsap-scrolltrigger.md)
|
|
205
|
+
- [演示页](./demo/index.html)(每个预设都可点击,无需构建)
|
|
206
|
+
|
|
207
|
+
## 升级
|
|
208
|
+
|
|
209
|
+
- 从 `use-scroll-animate`:`npm i motionary`,把导入路径与 CDN 链接中的 `use-scroll-animate` 换成 `motionary` 即可,其余不变(旧包名会继续同步发布)。
|
|
210
|
+
- [升级到 6.0](./docs/upgrading-6.md)(`npx usa-codemod-6`)· [升级到 5.0](./docs/upgrading-5.md)(`npx usa-codemod-5`)· [4.0](./docs/upgrading-4.md) · [3.0](./docs/upgrading-3.md) · [2.0](./docs/deprecations.md)
|
|
211
|
+
- [更新日志](./CHANGELOG.md)
|
|
212
|
+
|
|
213
|
+
## 路线图
|
|
214
|
+
|
|
215
|
+
每个版本一个 PR,直至 7.0 —— 粒子与流体、文字特效、光影与材质、3D 场景、形变、转场、天气氛围、交互物理:[docs/ROADMAP.md](./docs/ROADMAP.md)。
|
|
216
|
+
|
|
217
|
+
## 贡献与许可证
|
|
218
|
+
|
|
219
|
+
欢迎提交 Issue 与 PR —— 参见 [CONTRIBUTING.md](./CONTRIBUTING.md)。MIT © HarrisonCN —— 参见 [LICENSE](./LICENSE)。
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// use-scroll-animate 4.x → 5.0 codemod.
|
|
3
|
+
// npx usa-codemod-5 [--write] [paths…] (default: ./src; dry run without --write)
|
|
4
|
+
// Rewrites:
|
|
5
|
+
// 1. motionIntensity: 'off' → motionSensitivity: 'minimal'
|
|
6
|
+
// 2. setMotionIntensity('off'…) → setMotionSensitivity('minimal'…) (+ import from components/a11y)
|
|
7
|
+
// 3. reducedMotion: 'no-preference' → reducedMotion: 'user'
|
|
8
|
+
// 4. <usa-timeline … scrub="js" …> → scrub smooth="0.1"
|
|
9
|
+
// 5. configureComponents / prefersReducedMotion imported from a category entry
|
|
10
|
+
// (use-scroll-animate/components/<category>) → from 'use-scroll-animate/components'
|
|
11
|
+
import { readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs';
|
|
12
|
+
import { join, extname } from 'node:path';
|
|
13
|
+
import { pathToFileURL } from 'node:url';
|
|
14
|
+
|
|
15
|
+
const EXT = new Set(['.js', '.mjs', '.cjs', '.jsx', '.ts', '.tsx', '.mts', '.cts', '.vue', '.svelte', '.html', '.astro']);
|
|
16
|
+
const SHARED = ['configureComponents', 'prefersReducedMotion', 'ComponentsConfig', 'UsaElement'];
|
|
17
|
+
|
|
18
|
+
/** Apply every rewrite to one file's source. Returns { code, changes }. */
|
|
19
|
+
export function transform(source) {
|
|
20
|
+
const changes = [];
|
|
21
|
+
let code = source;
|
|
22
|
+
const rep = (re, to, label) => {
|
|
23
|
+
code = code.replace(re, (...m) => {
|
|
24
|
+
changes.push(label);
|
|
25
|
+
return typeof to === 'function' ? to(...m) : to;
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
rep(/motionIntensity(\s*:\s*)(['"])off\2/g, (_m, sep, q) => `motionSensitivity${sep}${q}minimal${q}`, "motionIntensity: 'off' → motionSensitivity: 'minimal'");
|
|
29
|
+
let usedSens = false;
|
|
30
|
+
rep(/\bsetMotionIntensity\(\s*(['"])off\1/g, (_m, q) => ((usedSens = true), `setMotionSensitivity(${q}minimal${q}`), "setMotionIntensity('off') → setMotionSensitivity('minimal')");
|
|
31
|
+
rep(/reducedMotion(\s*:\s*)(['"])no-preference\2/g, (_m, sep, q) => `reducedMotion${sep}${q}user${q}`, "reducedMotion: 'no-preference' → 'user'");
|
|
32
|
+
rep(/(<usa-timeline\b[^>]*?)\bscrub=(["'])js\2/g, (_m, pre) => `${pre}scrub smooth="0.1"`, '<usa-timeline scrub="js"> → scrub smooth="0.1"');
|
|
33
|
+
// shared names imported from a category entry
|
|
34
|
+
rep(/import\s+(type\s+)?\{([^}]*)\}\s*from\s*(['"])use-scroll-animate\/components\/([a-z-]+)\3;?/g, (m, type, names, q, cat) => {
|
|
35
|
+
if (['react', 'vue', 'svelte', 'solid', 'angular', 'jsx', 'lazy', 'tokens', 'a11y', 'perf', 'bridge', 'lite'].includes(cat)) return changes.pop(), m;
|
|
36
|
+
const list = names.split(',').map((n) => n.trim()).filter(Boolean);
|
|
37
|
+
const shared = list.filter((n) => SHARED.includes(n.replace(/^type\s+/, '').split(/\s+as\s+/)[0]));
|
|
38
|
+
changes.pop(); // the generic label; re-pushed precisely below when something changes
|
|
39
|
+
if (!shared.length) return m;
|
|
40
|
+
changes.push(`${shared.join(', ')} → import from 'use-scroll-animate/components'`);
|
|
41
|
+
const rest = list.filter((n) => !shared.includes(n));
|
|
42
|
+
const t = type || '';
|
|
43
|
+
const a = rest.length ? `import ${t}{ ${rest.join(', ')} } from ${q}use-scroll-animate/components/${cat}${q};\n` : '';
|
|
44
|
+
return `${a}import ${t}{ ${shared.join(', ')} } from ${q}use-scroll-animate/components${q};`;
|
|
45
|
+
}, 'shared import');
|
|
46
|
+
if (usedSens && !/\bsetMotionSensitivity\b[^(]*from\s*['"]use-scroll-animate/.test(code) && /\bimport\b/.test(code)) {
|
|
47
|
+
code = code.replace(/^(\s*import[^\n]*\n)/m, `import { setMotionSensitivity } from 'use-scroll-animate/components/a11y';\n$1`);
|
|
48
|
+
changes.push("added import { setMotionSensitivity } from 'use-scroll-animate/components/a11y'");
|
|
49
|
+
}
|
|
50
|
+
return { code, changes };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function* walk(p) {
|
|
54
|
+
const st = statSync(p);
|
|
55
|
+
if (st.isDirectory()) {
|
|
56
|
+
for (const f of readdirSync(p)) if (!['node_modules', 'dist', '.git'].includes(f)) yield* walk(join(p, f));
|
|
57
|
+
} else if (EXT.has(extname(p))) yield p;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function run(args) {
|
|
61
|
+
const write = args.includes('--write');
|
|
62
|
+
const paths = args.filter((a) => !a.startsWith('--'));
|
|
63
|
+
let files = 0;
|
|
64
|
+
let edits = 0;
|
|
65
|
+
for (const root of paths.length ? paths : ['src'])
|
|
66
|
+
for (const f of walk(root)) {
|
|
67
|
+
const src = readFileSync(f, 'utf8');
|
|
68
|
+
const { code, changes } = transform(src);
|
|
69
|
+
if (!changes.length) continue;
|
|
70
|
+
files++;
|
|
71
|
+
edits += changes.length;
|
|
72
|
+
console.log(`${f}\n - ${changes.join('\n - ')}`);
|
|
73
|
+
if (write) writeFileSync(f, code);
|
|
74
|
+
}
|
|
75
|
+
console.log(`\n${edits} change(s) in ${files} file(s)${write ? ' written' : ' (dry run — add --write to apply)'}.`);
|
|
76
|
+
return { files, edits };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (import.meta.url === pathToFileURL(process.argv[1] || '').href) run(process.argv.slice(2));
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// use-scroll-animate 5.x → 6.0 codemod.
|
|
3
|
+
// npx usa-codemod-6 [--write] [paths…] (default: ./src; dry run without --write)
|
|
4
|
+
// Rewrites (5.9 deprecations, removed in 6.0 — every effect goes through the registry):
|
|
5
|
+
// 1. burst(x, y[, opts]) → playEffect(document.body, 'burst', { x: x, y: y[, ...opts] })
|
|
6
|
+
// 2. confetti([opts]) → playEffect(document.body, 'confetti'[, opts])
|
|
7
|
+
// 3. shake(el[, i[, d]]) → playEffect(el, 'shake'[, { intensity: i[, duration: d] }])
|
|
8
|
+
// …and the import of burst / confetti / shake from use-scroll-animate/components[/click]
|
|
9
|
+
// becomes `import { playEffect } from 'use-scroll-animate/components/fx'`.
|
|
10
|
+
// Reported for a manual change (no safe rewrite):
|
|
11
|
+
// 4. <usa-cursor mode="trail"> → <usa-fx effect="comet-trail" trigger="load" self> around the content
|
|
12
|
+
import { readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs';
|
|
13
|
+
import { join, extname } from 'node:path';
|
|
14
|
+
import { pathToFileURL } from 'node:url';
|
|
15
|
+
|
|
16
|
+
const EXT = new Set(['.js', '.mjs', '.cjs', '.jsx', '.ts', '.tsx', '.mts', '.cts', '.vue', '.svelte', '.html', '.astro']);
|
|
17
|
+
const OLD = ['burst', 'confetti', 'shake'];
|
|
18
|
+
|
|
19
|
+
/** Split a call's argument list at top-level commas (pure). */
|
|
20
|
+
export function splitArgs(s) {
|
|
21
|
+
const out = [];
|
|
22
|
+
let depth = 0;
|
|
23
|
+
let cur = '';
|
|
24
|
+
let q = '';
|
|
25
|
+
for (let i = 0; i < s.length; i++) {
|
|
26
|
+
const c = s[i];
|
|
27
|
+
if (q) {
|
|
28
|
+
cur += c;
|
|
29
|
+
if (c === '\\') cur += s[++i] ?? '';
|
|
30
|
+
else if (c === q) q = '';
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (c === '"' || c === "'" || c === '`') q = c;
|
|
34
|
+
else if ('([{'.includes(c)) depth++;
|
|
35
|
+
else if (')]}'.includes(c)) depth--;
|
|
36
|
+
if (c === ',' && depth === 0) {
|
|
37
|
+
out.push(cur.trim());
|
|
38
|
+
cur = '';
|
|
39
|
+
} else cur += c;
|
|
40
|
+
}
|
|
41
|
+
if (cur.trim()) out.push(cur.trim());
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Find `name(` calls and their balanced argument text. */
|
|
46
|
+
function rewriteCalls(code, name, fn, changes) {
|
|
47
|
+
const re = new RegExp(`(?<![\\w.$])${name}\\(`, 'g');
|
|
48
|
+
let out = '';
|
|
49
|
+
let last = 0;
|
|
50
|
+
let m;
|
|
51
|
+
while ((m = re.exec(code))) {
|
|
52
|
+
const start = m.index;
|
|
53
|
+
let i = re.lastIndex;
|
|
54
|
+
let depth = 1;
|
|
55
|
+
let q = '';
|
|
56
|
+
for (; i < code.length && depth; i++) {
|
|
57
|
+
const c = code[i];
|
|
58
|
+
if (q) {
|
|
59
|
+
if (c === '\\') i++;
|
|
60
|
+
else if (c === q) q = '';
|
|
61
|
+
} else if (c === '"' || c === "'" || c === '`') q = c;
|
|
62
|
+
else if (c === '(') depth++;
|
|
63
|
+
else if (c === ')') depth--;
|
|
64
|
+
}
|
|
65
|
+
if (depth) break;
|
|
66
|
+
const args = splitArgs(code.slice(re.lastIndex, i - 1));
|
|
67
|
+
const rep = fn(args);
|
|
68
|
+
if (rep == null) continue;
|
|
69
|
+
out += code.slice(last, start) + rep;
|
|
70
|
+
last = i;
|
|
71
|
+
re.lastIndex = i;
|
|
72
|
+
changes.push(`${name.replace('\\', '')}() → playEffect(…)`);
|
|
73
|
+
}
|
|
74
|
+
return out + code.slice(last);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const objOf = (pairs, rest) => {
|
|
78
|
+
const lit = rest && /^\{[\s\S]*\}$/.test(rest) ? rest.slice(1, -1).trim() : '';
|
|
79
|
+
const tail = rest ? [lit || `...${rest}`] : [];
|
|
80
|
+
return `{ ${[...pairs.filter(([, v]) => v !== undefined).map(([k, v]) => (k === v ? k : `${k}: ${v}`)), ...tail].filter(Boolean).join(', ')} }`;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/** Apply every rewrite to one file's source. Returns { code, changes, manual }. */
|
|
84
|
+
export function transform(source) {
|
|
85
|
+
const changes = [];
|
|
86
|
+
const manual = [];
|
|
87
|
+
let code = source;
|
|
88
|
+
// Only touch files that import the old helpers from the library (or use the UMD global).
|
|
89
|
+
const importRe = /import\s*\{([^}]*)\}\s*from\s*(['"])use-scroll-animate\/components(?:\/click)?\2;?/g;
|
|
90
|
+
const imported = new Map(); // local name → original helper
|
|
91
|
+
code = code.replace(importRe, (m, names, q) => {
|
|
92
|
+
const list = names.split(',').map((n) => n.trim()).filter(Boolean);
|
|
93
|
+
const old = list.filter((n) => OLD.includes(n.split(/\s+as\s+/)[0]));
|
|
94
|
+
if (!old.length) return m;
|
|
95
|
+
old.forEach((n) => imported.set(n.split(/\s+as\s+/).pop(), n.split(/\s+as\s+/)[0]));
|
|
96
|
+
const rest = list.filter((n) => !old.includes(n));
|
|
97
|
+
const src = m.match(/from\s*(['"])(.*?)\1/)[2];
|
|
98
|
+
changes.push(`import { ${old.join(', ')} } → import { playEffect } from 'use-scroll-animate/components/fx'`);
|
|
99
|
+
const keep = rest.length ? `import { ${rest.join(', ')} } from ${q}${src}${q};\n` : '';
|
|
100
|
+
return `${keep}import { playEffect } from ${q}use-scroll-animate/components/fx${q};`;
|
|
101
|
+
});
|
|
102
|
+
const umd = /UsaComponents\.(burst|confetti|shake)\(/.test(code);
|
|
103
|
+
if (umd) code = code.replace(/UsaComponents\.(burst|confetti|shake)\(/g, (_m, n) => (imported.set(`UsaComponents.${n}`, n), `UsaComponents.${n}(`));
|
|
104
|
+
for (const [name, kind] of imported) {
|
|
105
|
+
const pe = name.startsWith('UsaComponents.') ? 'UsaComponents.playEffect' : 'playEffect';
|
|
106
|
+
const esc = name.replace('.', '\\.');
|
|
107
|
+
code = rewriteCalls(code, esc, (a) => {
|
|
108
|
+
if (kind === 'burst') return a.length >= 2 ? `${pe}(document.body, 'burst', ${objOf([['x', a[0]], ['y', a[1]]], a[2])})` : null;
|
|
109
|
+
if (kind === 'confetti') return `${pe}(document.body, 'confetti'${a[0] ? `, ${a[0]}` : ''})`;
|
|
110
|
+
if (kind === 'shake') return a.length ? `${pe}(${a[0]}, 'shake'${a.length > 1 ? `, ${objOf([['intensity', a[1]], ['duration', a[2]]])}` : ''})` : null;
|
|
111
|
+
return null;
|
|
112
|
+
}, changes);
|
|
113
|
+
}
|
|
114
|
+
if (/<usa-cursor\b[^>]*\bmode=(["'])trail\1/.test(code)) manual.push('<usa-cursor mode="trail"> is removed in 6.0 — wrap the content in <usa-fx effect="comet-trail" trigger="load" self> (see docs/upgrading-6.md)');
|
|
115
|
+
return { code, changes, manual };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function* walk(p) {
|
|
119
|
+
const st = statSync(p);
|
|
120
|
+
if (st.isDirectory()) {
|
|
121
|
+
for (const f of readdirSync(p)) if (!['node_modules', 'dist', '.git'].includes(f)) yield* walk(join(p, f));
|
|
122
|
+
} else if (EXT.has(extname(p))) yield p;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function run(args) {
|
|
126
|
+
const write = args.includes('--write');
|
|
127
|
+
const paths = args.filter((a) => !a.startsWith('--'));
|
|
128
|
+
let files = 0;
|
|
129
|
+
let edits = 0;
|
|
130
|
+
let todo = 0;
|
|
131
|
+
for (const root of paths.length ? paths : ['src'])
|
|
132
|
+
for (const f of walk(root)) {
|
|
133
|
+
const src = readFileSync(f, 'utf8');
|
|
134
|
+
const { code, changes, manual } = transform(src);
|
|
135
|
+
if (!changes.length && !manual.length) continue;
|
|
136
|
+
files++;
|
|
137
|
+
edits += changes.length;
|
|
138
|
+
todo += manual.length;
|
|
139
|
+
console.log(`${f}${changes.map((c) => `\n - ${c}`).join('')}${manual.map((c) => `\n ! manual: ${c}`).join('')}`);
|
|
140
|
+
if (write && changes.length) writeFileSync(f, code);
|
|
141
|
+
}
|
|
142
|
+
console.log(`\n${edits} change(s), ${todo} manual item(s) in ${files} file(s)${write ? ' written' : ' (dry run — add --write to apply)'}.`);
|
|
143
|
+
return { files, edits, manual: todo };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (import.meta.url === pathToFileURL(process.argv[1] || '').href) run(process.argv.slice(2));
|