react-gsap-aos 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +165 -102
- package/dist/client.d.mts +38 -0
- package/dist/client.d.ts +38 -0
- package/dist/client.js +753 -0
- package/dist/client.js.map +1 -0
- package/dist/client.mjs +720 -0
- package/dist/client.mjs.map +1 -0
- package/dist/constants.d.mts +11 -1
- package/dist/constants.d.ts +11 -1
- package/dist/index.d.mts +3 -38
- package/dist/index.d.ts +3 -38
- package/dist/index.js +11 -624
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +9 -621
- package/dist/index.mjs.map +1 -1
- package/dist/toAOSProps-DBQmkOnG.d.mts +12 -0
- package/dist/toAOSProps-Dx7ebLJd.d.ts +12 -0
- package/dist/{constants-D5sz-uHX.d.mts → types-BXrsuTv7.d.mts} +1 -9
- package/dist/{constants-D5sz-uHX.d.ts → types-BXrsuTv7.d.ts} +1 -9
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -2,9 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
輕量的 GSAP + ScrollTrigger 整合,用法類似 AOS,專為 React / Next.js 設計。
|
|
4
4
|
|
|
5
|
-
動畫樣式參考: https://github.com/michalsnik/aos
|
|
5
|
+
動畫樣式參考: [AOS](https://github.com/michalsnik/aos)
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 功能
|
|
8
|
+
|
|
9
|
+
- 基於 GSAP + ScrollTrigger 的捲動觸發動畫
|
|
10
|
+
- API 模仿 AOS,易於 React / Next.js 使用
|
|
11
|
+
- 支援 data-aos 屬性與函式轉換
|
|
12
|
+
- 可在多個區塊平行使用,避免互相干擾
|
|
13
|
+
- TypeScript 完整支援,包含動畫/緩動/錨點型別
|
|
14
|
+
- 輕量且 SSR 友善,具備卸載清理機制
|
|
15
|
+
|
|
16
|
+
## 安裝
|
|
8
17
|
|
|
9
18
|
```bash
|
|
10
19
|
pnpm install react-gsap-aos gsap @gsap/react
|
|
@@ -23,108 +32,128 @@ pnpm install react-gsap-aos gsap @gsap/react
|
|
|
23
32
|
|
|
24
33
|
## 快速開始
|
|
25
34
|
|
|
26
|
-
1. Next.js / SSR 請在頂層加入 `"use client"`
|
|
27
|
-
2. 在需要動畫的頁面或元件中呼叫 `useAOSInitial`,並將回傳的 `containerRef` 綁定到最外層容器。
|
|
28
|
-
|
|
29
|
-
> ⚠️ 不建議在 `app/layout.tsx` 綁定動畫,因為 GSAP 應在頁面卸載時正確清理;建議在每個頁面的區塊綁定。
|
|
30
|
-
|
|
31
|
-
> `"overflow-hidden"` 樣式是解決動畫元素起始階段溢出問題。
|
|
32
|
-
|
|
33
35
|
```tsx
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
import { useAOSInitial } from "react-gsap-aos";
|
|
36
|
+
import { AOSProvider } from "react-gsap-aos/client";
|
|
37
37
|
|
|
38
38
|
export default function Demo() {
|
|
39
|
-
const { containerRef } = useAOSInitial<HTMLDivElement>();
|
|
40
|
-
|
|
41
39
|
return (
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
<AOSProvider className="overflow-hidden">
|
|
41
|
+
<div data-aos-container>
|
|
42
|
+
<div data-aos="fade-up" data-aos-offset="200">
|
|
43
|
+
Hello AOS
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</AOSProvider>
|
|
45
47
|
);
|
|
46
48
|
}
|
|
47
49
|
```
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
## 用法
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
function Demo() {
|
|
53
|
-
const { containerRef } = useAOSInitial<HTMLDivElement>();
|
|
53
|
+
### 設置 `AOSProvider`
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
{/* ❌ 不要嵌套使用 useAOSInitial */}
|
|
58
|
-
<Box />
|
|
59
|
-
</div>
|
|
60
|
-
);
|
|
61
|
-
}
|
|
55
|
+
只要把 `AOSProvider` 包覆在需要動畫的區塊外層,
|
|
56
|
+
元件內的所有子元素就會自動被監聽與啟動動畫。
|
|
62
57
|
|
|
63
|
-
|
|
64
|
-
|
|
58
|
+
> `"overflow-hidden"` 樣式是解決動畫元素起始階段溢出問題。
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { AOSProvider } from "react-gsap-aos/client";
|
|
65
62
|
|
|
63
|
+
export default function Demo() {
|
|
66
64
|
return (
|
|
67
|
-
<
|
|
68
|
-
{/* 動畫區塊 */}
|
|
69
|
-
</div>
|
|
65
|
+
<AOSProvider className="overflow-hidden">{/* 動畫區塊 */}</AOSProvider>
|
|
70
66
|
);
|
|
71
67
|
}
|
|
72
68
|
```
|
|
73
69
|
|
|
74
|
-
|
|
70
|
+
> ⚠️ 不要巢狀使用 `AOSProvider`,會造成重複監聽與多餘動畫。
|
|
75
71
|
|
|
76
72
|
```tsx
|
|
77
|
-
|
|
73
|
+
import { AOSProvider } from "react-gsap-aos/client";
|
|
74
|
+
|
|
75
|
+
export default function Demo() {
|
|
78
76
|
return (
|
|
79
|
-
<
|
|
80
|
-
{/*
|
|
81
|
-
<
|
|
82
|
-
|
|
83
|
-
</div>
|
|
77
|
+
<AOSProvider>
|
|
78
|
+
{/* ❌ 會導致重複監聽元素以及創建動畫 */}
|
|
79
|
+
<AOSProvider />
|
|
80
|
+
</AOSProvider>
|
|
84
81
|
);
|
|
85
82
|
}
|
|
83
|
+
```
|
|
86
84
|
|
|
87
|
-
|
|
88
|
-
const { containerRef } = useAOSInitial<HTMLDivElement>();
|
|
85
|
+
`AOSProvider` 是呼叫 `useAOSScope` hook 的包裝元件,大部分情況下使用此組件即可;
|
|
89
86
|
|
|
90
|
-
|
|
91
|
-
<div ref={containerRef} className="overflow-hidden">
|
|
92
|
-
{/* 動畫區塊 */}
|
|
93
|
-
</div>
|
|
94
|
-
);
|
|
95
|
-
}
|
|
87
|
+
如果你需要更細緻的控制,可以改用 [`useAOSScope`](#useaosscope)。
|
|
96
88
|
|
|
97
|
-
|
|
98
|
-
const { containerRef } = useAOSInitial<HTMLDivElement>();
|
|
89
|
+
此外該組件提供了兩個屬性供調整:
|
|
99
90
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
91
|
+
- `component`:渲染的容器元素,預設為 `'div'`。
|
|
92
|
+
- `options`:與 `toAOSProps` 同樣結構的默認動畫參數,會應用於該範圍內的所有新動畫元素。
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
<AOSProvider
|
|
96
|
+
component="section"
|
|
97
|
+
options={{
|
|
98
|
+
animation: "fade",
|
|
99
|
+
offset: 120,
|
|
100
|
+
delay: 0,
|
|
101
|
+
duration: 400,
|
|
102
|
+
easing: "none",
|
|
103
|
+
once: false,
|
|
104
|
+
mirror: false,
|
|
105
|
+
anchorPlacement: "top-bottom",
|
|
106
|
+
}}
|
|
107
|
+
></AOSProvider>
|
|
106
108
|
```
|
|
107
109
|
|
|
108
|
-
|
|
110
|
+
### 使用 data attributes 設定動畫
|
|
109
111
|
|
|
110
|
-
|
|
112
|
+
透過帶有 `data-aos-*` 開頭的屬性來調整行為
|
|
111
113
|
|
|
112
114
|
```tsx
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
115
|
+
<div
|
|
116
|
+
data-aos="fade"
|
|
117
|
+
data-aos-offset={120}
|
|
118
|
+
data-aos-delay={0}
|
|
119
|
+
data-aos-duration={400}
|
|
120
|
+
data-aos-easing="none"
|
|
121
|
+
data-aos-mirror={false}
|
|
122
|
+
data-aos-once={false}
|
|
123
|
+
data-aos-anchor-placement="top-bottom"
|
|
124
|
+
>
|
|
125
|
+
Hello AOS
|
|
126
|
+
</div>
|
|
117
127
|
```
|
|
118
128
|
|
|
119
|
-
|
|
129
|
+
### 使用 `toAOSProps` 設定動畫
|
|
130
|
+
|
|
131
|
+
該函式提供完整型別且會過濾無效的屬性值後轉換成 data attributes
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
<div
|
|
135
|
+
{...toAOSProps({
|
|
136
|
+
animation: "fade",
|
|
137
|
+
offset: 120,
|
|
138
|
+
delay: 0,
|
|
139
|
+
duration: 400,
|
|
140
|
+
easing: "none",
|
|
141
|
+
once: false,
|
|
142
|
+
mirror: false,
|
|
143
|
+
anchorPlacement: "top-bottom",
|
|
144
|
+
})}
|
|
145
|
+
>
|
|
146
|
+
Hello AOS
|
|
147
|
+
</div>
|
|
148
|
+
```
|
|
120
149
|
|
|
121
|
-
|
|
150
|
+
### 容器定位 data-aos-container
|
|
122
151
|
|
|
123
|
-
為了避免 ScrollTrigger
|
|
152
|
+
為了避免 ScrollTrigger 計算偏移時造成觸發點不正確,請在需要的父容器加上 `data-aos-container`:
|
|
124
153
|
|
|
125
154
|
```tsx
|
|
126
155
|
return (
|
|
127
|
-
<
|
|
156
|
+
<AOSProvider className="overflow-hidden">
|
|
128
157
|
{/* ✅ 指定定位容器 */}
|
|
129
158
|
<div data-aos-container>
|
|
130
159
|
<div data-aos="fade-up" data-aos-offset="200">
|
|
@@ -136,7 +165,7 @@ return (
|
|
|
136
165
|
<div data-aos="fade-up" data-aos-offset="200">
|
|
137
166
|
Hello AOS
|
|
138
167
|
</div>
|
|
139
|
-
</
|
|
168
|
+
</AOSProvider>
|
|
140
169
|
);
|
|
141
170
|
```
|
|
142
171
|
|
|
@@ -157,51 +186,85 @@ return (
|
|
|
157
186
|
</div>
|
|
158
187
|
```
|
|
159
188
|
|
|
160
|
-
##
|
|
189
|
+
## API
|
|
190
|
+
|
|
191
|
+
### `useAOSScope`
|
|
192
|
+
|
|
193
|
+
這個 hook 是整個套件的核心,負責監聽子元素 `data-aos-*` 屬性來創建、修改動畫並且會在離開頁面時卸載動畫,`AOSProvider` 是它的輕量包裝元件,通常你只需使用 `AOSProvider`。
|
|
161
194
|
|
|
162
|
-
|
|
195
|
+
若你想在函式元件中直接掌握 container ref,就可以直接使用此 hook。
|
|
196
|
+
|
|
197
|
+
1. Next.js / SSR 專案在使用此 hook 的檔案最上方加上 `"use client"`。
|
|
198
|
+
2. 呼叫後把回傳的 `containerRef` 綁定到最外層容器。
|
|
199
|
+
|
|
200
|
+
> ⚠️ 建議綁定在頁面或元件的區塊層級,不要放在 `app/layout.tsx`,以便 GSAP 在組件卸載時能正確清理。
|
|
163
201
|
|
|
164
202
|
```tsx
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
203
|
+
"use client";
|
|
204
|
+
|
|
205
|
+
import { useAOSScope } from "react-gsap-aos/client";
|
|
206
|
+
|
|
207
|
+
export default function Demo() {
|
|
208
|
+
const { containerRef } = useAOSScope<HTMLDivElement>();
|
|
209
|
+
|
|
210
|
+
return (
|
|
211
|
+
<div ref={containerRef} className="overflow-hidden">
|
|
212
|
+
{/* 動畫區塊 */}
|
|
213
|
+
</div>
|
|
214
|
+
);
|
|
215
|
+
}
|
|
177
216
|
```
|
|
178
217
|
|
|
179
|
-
|
|
218
|
+
不要巢狀呼叫 `useAOSScope`,但是你可以像下面這樣平行使用。
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
function Demo() {
|
|
222
|
+
return (
|
|
223
|
+
<div>
|
|
224
|
+
{/* ✅ 平行使用互不干涉 */}
|
|
225
|
+
<Box />
|
|
226
|
+
<Box2 />
|
|
227
|
+
</div>
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function Box() {
|
|
232
|
+
const { containerRef } = useAOSScope<HTMLDivElement>();
|
|
233
|
+
return (
|
|
234
|
+
<div ref={containerRef} className="overflow-hidden">
|
|
235
|
+
…
|
|
236
|
+
</div>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function Box2() {
|
|
241
|
+
const { containerRef } = useAOSScope<HTMLDivElement>();
|
|
242
|
+
return (
|
|
243
|
+
<div ref={containerRef} className="overflow-hidden">
|
|
244
|
+
…
|
|
245
|
+
</div>
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
```
|
|
180
249
|
|
|
181
|
-
|
|
250
|
+
若要在區塊層級覆蓋預設設定,可傳入選項:
|
|
182
251
|
|
|
183
252
|
```tsx
|
|
184
|
-
<
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
delay: 0,
|
|
189
|
-
duration: 400,
|
|
190
|
-
easing: "none",
|
|
191
|
-
once: false,
|
|
192
|
-
mirror: false,
|
|
193
|
-
anchorPlacement: "top-bottom",
|
|
194
|
-
})}
|
|
195
|
-
>
|
|
196
|
-
Hello AOS
|
|
197
|
-
</div>
|
|
253
|
+
const { containerRef } = useAOSScope<HTMLDivElement>({
|
|
254
|
+
easing: "bounce",
|
|
255
|
+
duration: 300,
|
|
256
|
+
});
|
|
198
257
|
```
|
|
199
258
|
|
|
259
|
+
> 此設定只會應用於該容器中新產生的動畫元素,不建議頻繁動態變更此項設定。
|
|
260
|
+
|
|
200
261
|
## 刷新動畫位置
|
|
201
262
|
|
|
202
263
|
若動態修改 DOM(插入/移除元素或修改佈局),請手動呼叫:
|
|
203
264
|
|
|
204
265
|
```ts
|
|
266
|
+
"use client";
|
|
267
|
+
|
|
205
268
|
import { refreshAOS } from "react-gsap-aos";
|
|
206
269
|
|
|
207
270
|
refreshAOS();
|
|
@@ -213,17 +276,17 @@ refreshAOS();
|
|
|
213
276
|
|
|
214
277
|
### 動態 DOM 範例
|
|
215
278
|
|
|
216
|
-
|
|
279
|
+
以下範例示範在動態增減元素導致佈局變動時,如何呼叫 `refreshAOS()` :
|
|
217
280
|
|
|
218
281
|
```tsx
|
|
219
282
|
"use client";
|
|
220
283
|
|
|
221
284
|
import { useState, useEffect } from "react";
|
|
222
|
-
import {
|
|
285
|
+
import { useAOSScope, refreshAOS } from "react-gsap-aos";
|
|
223
286
|
|
|
224
287
|
export default function DynamicList() {
|
|
225
|
-
const { containerRef } =
|
|
226
|
-
const [show, setShow] = useState(
|
|
288
|
+
const { containerRef } = useAOSScope<HTMLDivElement>();
|
|
289
|
+
const [show, setShow] = useState(false);
|
|
227
290
|
|
|
228
291
|
useEffect(() => {
|
|
229
292
|
// 當 show 變動時,刷新 ScrollTrigger
|
|
@@ -331,7 +394,7 @@ export default function DynamicList() {
|
|
|
331
394
|
- sine
|
|
332
395
|
- sine.in
|
|
333
396
|
- sine.out
|
|
334
|
-
- sine.
|
|
397
|
+
- sine.inOut
|
|
335
398
|
|
|
336
399
|
## AnchorPlacement
|
|
337
400
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import React__default, { ElementType, ComponentPropsWithoutRef } from 'react';
|
|
3
|
+
import { A as AOSAttributeOptions } from './toAOSProps-DBQmkOnG.mjs';
|
|
4
|
+
import { b as AnimationOptions } from './types-BXrsuTv7.mjs';
|
|
5
|
+
|
|
6
|
+
type AOSProviderProps<T extends ElementType> = {
|
|
7
|
+
component?: T;
|
|
8
|
+
options?: AOSAttributeOptions;
|
|
9
|
+
children?: React__default.ReactNode;
|
|
10
|
+
} & Omit<ComponentPropsWithoutRef<T>, "ref">;
|
|
11
|
+
declare function AOSProvider<T extends ElementType = "div">({ component, options, children, ...props }: AOSProviderProps<T>): React__default.ReactElement<any, string | React__default.JSXElementConstructor<any>>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 綁定 AOS 動畫範圍
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
"use client";
|
|
19
|
+
|
|
20
|
+
import {useAOSScope} from '@/aos';
|
|
21
|
+
|
|
22
|
+
export default function Demo() {
|
|
23
|
+
const {containerRef} = useAOSScope<HTMLDivElement>()
|
|
24
|
+
return (
|
|
25
|
+
<div ref={containerRef} className="overflow-hidden">
|
|
26
|
+
<div data-aos-container>
|
|
27
|
+
<div data-aos="fade-up">Hello AOS</div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
declare function useAOSScope<E extends HTMLElement = HTMLElement>(options?: Partial<AnimationOptions>): {
|
|
35
|
+
containerRef: React.RefObject<E | null>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export { AOSProvider, useAOSScope };
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import React__default, { ElementType, ComponentPropsWithoutRef } from 'react';
|
|
3
|
+
import { A as AOSAttributeOptions } from './toAOSProps-Dx7ebLJd.js';
|
|
4
|
+
import { b as AnimationOptions } from './types-BXrsuTv7.js';
|
|
5
|
+
|
|
6
|
+
type AOSProviderProps<T extends ElementType> = {
|
|
7
|
+
component?: T;
|
|
8
|
+
options?: AOSAttributeOptions;
|
|
9
|
+
children?: React__default.ReactNode;
|
|
10
|
+
} & Omit<ComponentPropsWithoutRef<T>, "ref">;
|
|
11
|
+
declare function AOSProvider<T extends ElementType = "div">({ component, options, children, ...props }: AOSProviderProps<T>): React__default.ReactElement<any, string | React__default.JSXElementConstructor<any>>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 綁定 AOS 動畫範圍
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
"use client";
|
|
19
|
+
|
|
20
|
+
import {useAOSScope} from '@/aos';
|
|
21
|
+
|
|
22
|
+
export default function Demo() {
|
|
23
|
+
const {containerRef} = useAOSScope<HTMLDivElement>()
|
|
24
|
+
return (
|
|
25
|
+
<div ref={containerRef} className="overflow-hidden">
|
|
26
|
+
<div data-aos-container>
|
|
27
|
+
<div data-aos="fade-up">Hello AOS</div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
declare function useAOSScope<E extends HTMLElement = HTMLElement>(options?: Partial<AnimationOptions>): {
|
|
35
|
+
containerRef: React.RefObject<E | null>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export { AOSProvider, useAOSScope };
|