react-gsap-aos 1.5.1 โ 1.5.2
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.en.md +136 -237
- package/README.zh-TW.md +137 -238
- package/dist/client.js +31 -14
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +31 -14
- package/dist/client.mjs.map +1 -1
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/README.en.md
CHANGED
|
@@ -9,190 +9,111 @@ A lightweight GSAP + ScrollTrigger integration with an AOS-like API, specificall
|
|
|
9
9
|
|
|
10
10
|
[Live Demo](https://react-gsap-aos-nextjs.vercel.app)
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## Project Advantages
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
This is a monorepo managed with pnpm workspaces.
|
|
15
15
|
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **TypeScript
|
|
20
|
-
- **Automatic Cleanup**: Properly manages animation lifecycle with React's component lifecycle
|
|
21
|
-
|
|
22
|
-
### Problem It Solves
|
|
23
|
-
|
|
24
|
-
While AOS is great for vanilla JavaScript, integrating it with React can be problematic:
|
|
25
|
-
|
|
26
|
-
- Manual initialization and cleanup required
|
|
27
|
-
- Not SSR-friendly
|
|
28
|
-
- Limited TypeScript support
|
|
29
|
-
- Difficult to use with dynamic content
|
|
30
|
-
|
|
31
|
-
`react-gsap-aos` by React solution that automatically handles DOM mutations, component lifecycle, and SSR scenarios.
|
|
32
|
-
|
|
33
|
-
## Features
|
|
34
|
-
|
|
35
|
-
- ๐ฌ Scroll-triggered animations powered by GSAP + ScrollTrigger
|
|
36
|
-
- ๐ฏ AOS-like API with `data-aos` attributes
|
|
37
|
-
- โ๏ธ Built for React / Next.js with SSR support
|
|
38
|
-
- ๐ Automatic animation management with DOM mutations
|
|
39
|
-
- ๐ฆ Multiple parallel scopes without interference
|
|
40
|
-
- ๐จ 34 animation presets (fade, slide, flip, zoom variants)
|
|
41
|
-
- ๐ญ 17 easing options from GSAP
|
|
42
|
-
- ๐ 9 anchor placement options for precise triggering
|
|
43
|
-
- ๐งน Automatic cleanup on component unmount
|
|
44
|
-
- ๐ช Full TypeScript support
|
|
45
|
-
|
|
46
|
-
## Installation
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
npm install react-gsap-aos gsap @gsap/react
|
|
50
|
-
# or
|
|
51
|
-
yarn add react-gsap-aos gsap @gsap/react
|
|
52
|
-
# or
|
|
53
|
-
pnpm add react-gsap-aos gsap @gsap/react
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### Peer Dependencies
|
|
57
|
-
|
|
58
|
-
- `react` >= 17
|
|
59
|
-
- `gsap` ^3.12.5
|
|
60
|
-
- `@gsap/react` ^2.1.2
|
|
16
|
+
- **Stable Performance** - Built on GSAP and ScrollTrigger, delivers smooth animation experience
|
|
17
|
+
- **Automatic Element Tracking** - Dynamically tracks DOM element additions and removals, automatically registers animations (layout changes require manual `refreshScrollTrigger` call)
|
|
18
|
+
- **Focused High-Performance Implementation** - Concentrates on core AOS functionality without unnecessary features
|
|
19
|
+
- **Full TypeScript Support** - Provides complete type definitions and type safety.
|
|
61
20
|
|
|
62
21
|
## Quick Start
|
|
63
22
|
|
|
23
|
+
### Basic Usage
|
|
24
|
+
|
|
64
25
|
```tsx
|
|
26
|
+
"use client";
|
|
27
|
+
|
|
65
28
|
import { AOSProvider } from "react-gsap-aos/client";
|
|
29
|
+
import { toAOSProps } from "react-gsap-aos";
|
|
66
30
|
|
|
67
|
-
export default function
|
|
31
|
+
export default function App() {
|
|
68
32
|
return (
|
|
69
33
|
<AOSProvider className="overflow-hidden">
|
|
70
34
|
<div data-aos-container>
|
|
71
|
-
<
|
|
72
|
-
Hello AOS
|
|
73
|
-
</div>
|
|
35
|
+
<h1 {...toAOSProps({ animation: "fade-up" })}>Hello World</h1>
|
|
74
36
|
</div>
|
|
75
37
|
</AOSProvider>
|
|
76
38
|
);
|
|
77
39
|
}
|
|
78
40
|
```
|
|
79
41
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
### Setting up AOSProvider
|
|
83
|
-
|
|
84
|
-
Wrap your animated content with `AOSProvider`. All child elements with `data-aos` attributes will be automatically animated.
|
|
42
|
+
### Multiple Animated Elements
|
|
85
43
|
|
|
86
44
|
```tsx
|
|
45
|
+
"use client";
|
|
46
|
+
|
|
87
47
|
import { AOSProvider } from "react-gsap-aos/client";
|
|
48
|
+
import { toAOSProps } from "react-gsap-aos";
|
|
88
49
|
|
|
89
50
|
export default function Demo() {
|
|
90
51
|
return (
|
|
91
52
|
<AOSProvider className="overflow-hidden">
|
|
92
|
-
|
|
53
|
+
<div data-aos-container>
|
|
54
|
+
<div {...toAOSProps({ animation: "fade-up", duration: 600 })}>
|
|
55
|
+
First Block
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
<div data-aos-container>
|
|
59
|
+
<div {...toAOSProps({ animation: "zoom-in", delay: 200 })}>
|
|
60
|
+
Second Block
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
<div data-aos-container>
|
|
64
|
+
<div {...toAOSProps({ animation: "slide-left", easing: "power2.out" })}>
|
|
65
|
+
Third Block
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
93
68
|
</AOSProvider>
|
|
94
69
|
);
|
|
95
70
|
}
|
|
96
71
|
```
|
|
97
72
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
โ ๏ธ **Important**: Do not nest `AOSProvider` components, as this will cause duplicate listeners and animations.
|
|
73
|
+
**It is not recommended** to use nested animations. While the animations will still register, users must manually refresh at the appropriate time.
|
|
101
74
|
|
|
102
|
-
###
|
|
103
|
-
|
|
104
|
-
Use `data-aos-*` attributes to configure animation behavior:
|
|
75
|
+
### Dynamic Content
|
|
105
76
|
|
|
106
77
|
```tsx
|
|
107
|
-
|
|
108
|
-
data-aos="fade-up"
|
|
109
|
-
data-aos-offset={120}
|
|
110
|
-
data-aos-delay={0}
|
|
111
|
-
data-aos-duration={400}
|
|
112
|
-
data-aos-easing="ease-out-cubic"
|
|
113
|
-
data-aos-mirror={false}
|
|
114
|
-
data-aos-once={false}
|
|
115
|
-
data-aos-anchor-placement="top-bottom"
|
|
116
|
-
>
|
|
117
|
-
Animated content
|
|
118
|
-
</div>
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### Using toAOSProps Helper
|
|
122
|
-
|
|
123
|
-
For better TypeScript support and validation, use the `toAOSProps` helper:
|
|
78
|
+
"use client";
|
|
124
79
|
|
|
125
|
-
|
|
80
|
+
import { useState, useEffect } from "react";
|
|
81
|
+
import { AOSProvider, refreshScrollTrigger } from "react-gsap-aos/client";
|
|
126
82
|
import { toAOSProps } from "react-gsap-aos";
|
|
127
83
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
animation: "fade-up",
|
|
131
|
-
offset: 120,
|
|
132
|
-
delay: 0,
|
|
133
|
-
duration: 400,
|
|
134
|
-
easing: "power2.out",
|
|
135
|
-
once: false,
|
|
136
|
-
mirror: false,
|
|
137
|
-
anchorPlacement: "top-bottom",
|
|
138
|
-
})}
|
|
139
|
-
>
|
|
140
|
-
Animated content
|
|
141
|
-
</div>;
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### Container Positioning with data-aos-container
|
|
145
|
-
|
|
146
|
-
To ensure accurate ScrollTrigger calculations, mark parent containers with `data-aos-container`:
|
|
147
|
-
|
|
148
|
-
```tsx
|
|
149
|
-
<AOSProvider className="overflow-hidden">
|
|
150
|
-
{/* โ
Correct: Container specified */}
|
|
151
|
-
<div data-aos-container>
|
|
152
|
-
<div data-aos="fade-up" data-aos-offset="200">
|
|
153
|
-
Hello AOS
|
|
154
|
-
</div>
|
|
155
|
-
</div>
|
|
156
|
-
|
|
157
|
-
{/* โ Incorrect: May cause offset issues */}
|
|
158
|
-
<div data-aos="fade-up" data-aos-offset="200">
|
|
159
|
-
Hello AOS
|
|
160
|
-
</div>
|
|
161
|
-
</AOSProvider>
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Nested data-aos-container usage is **not recommended**:
|
|
84
|
+
export default function DynamicList() {
|
|
85
|
+
const [items, setItems] = useState([1, 2, 3]);
|
|
165
86
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
refreshScrollTrigger();
|
|
89
|
+
}, [items]);
|
|
169
90
|
|
|
170
|
-
|
|
171
|
-
<
|
|
172
|
-
|
|
173
|
-
|
|
91
|
+
return (
|
|
92
|
+
<AOSProvider className="overflow-hidden">
|
|
93
|
+
<button onClick={() => setItems([...items, items.length + 1])}>
|
|
94
|
+
Add Item
|
|
95
|
+
</button>
|
|
96
|
+
<ul>
|
|
97
|
+
{items.map((item) => (
|
|
98
|
+
<li key={item} data-aos-container>
|
|
99
|
+
<div {...toAOSProps({ animation: "fade-up" })}>Item {item}</div>
|
|
100
|
+
</li>
|
|
101
|
+
))}
|
|
102
|
+
</ul>
|
|
103
|
+
</AOSProvider>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
174
106
|
```
|
|
175
107
|
|
|
176
|
-
Nested containers increase the complexity of animation initialization and ScrollTrigger refresh timing. While animations will still register, users need to manually call `ScrollTrigger.refresh()` at the appropriate time.
|
|
177
|
-
|
|
178
108
|
## API Reference
|
|
179
109
|
|
|
180
110
|
### AOSProvider
|
|
181
111
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
**Props:**
|
|
185
|
-
|
|
186
|
-
| Prop | Type | Default | Description |
|
|
187
|
-
| ----------- | --------------------------- | ----------- | ------------------------------------------ |
|
|
188
|
-
| `component` | `React.ElementType` | `'div'` | The container element to render |
|
|
189
|
-
| `className` | `string` | `undefined` | CSS classes for the container |
|
|
190
|
-
| `options` | `Partial<AnimationOptions>` | `undefined` | Default animation options for all children |
|
|
191
|
-
| `children` | `React.ReactNode` | - | Child elements |
|
|
192
|
-
|
|
193
|
-
**Example:**
|
|
112
|
+
Wrapper component that provides animation scope for child elements
|
|
194
113
|
|
|
195
114
|
```tsx
|
|
115
|
+
import { AOSProvider } from "react-gsap-aos/client";
|
|
116
|
+
|
|
196
117
|
<AOSProvider
|
|
197
118
|
component="section"
|
|
198
119
|
className="overflow-hidden"
|
|
@@ -202,30 +123,27 @@ A wrapper component that provides animation scope for its children.
|
|
|
202
123
|
once: true,
|
|
203
124
|
}}
|
|
204
125
|
>
|
|
205
|
-
{/* Children
|
|
206
|
-
</AOSProvider
|
|
126
|
+
{/* Children */}
|
|
127
|
+
</AOSProvider>;
|
|
207
128
|
```
|
|
208
129
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
### useAOSScope
|
|
130
|
+
**Props**
|
|
212
131
|
|
|
213
|
-
|
|
132
|
+
| Name | Type | Default | Description |
|
|
133
|
+
| ----------- | --------------------------- | ----------- | ------------------------------------------ |
|
|
134
|
+
| `component` | `React.ElementType` | `'div'` | Block element to render |
|
|
135
|
+
| `className` | `string` | `undefined` | CSS class for container |
|
|
136
|
+
| `options` | `Partial<AnimationOptions>` | `undefined` | Default animation options for all children |
|
|
137
|
+
| `children` | `React.ReactNode` | - | Child elements |
|
|
214
138
|
|
|
215
|
-
|
|
216
|
-
function useAOSScope<E extends HTMLElement = HTMLElement>(
|
|
217
|
-
options?: Partial<AnimationOptions>,
|
|
218
|
-
): { containerRef: React.RefObject<E> };
|
|
219
|
-
```
|
|
139
|
+
### useAOSScope
|
|
220
140
|
|
|
221
|
-
|
|
141
|
+
Core hook that powers `AOSProvider`, use when you need direct control over container ref
|
|
222
142
|
|
|
223
143
|
```tsx
|
|
224
|
-
"use client";
|
|
225
|
-
|
|
226
144
|
import { useAOSScope } from "react-gsap-aos/client";
|
|
227
145
|
|
|
228
|
-
|
|
146
|
+
function Demo() {
|
|
229
147
|
const { containerRef } = useAOSScope<HTMLDivElement>({
|
|
230
148
|
easing: "bounce.out",
|
|
231
149
|
duration: 800,
|
|
@@ -239,38 +157,21 @@ export default function Demo() {
|
|
|
239
157
|
}
|
|
240
158
|
```
|
|
241
159
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
- Do not nest `useAOSScope` calls
|
|
245
|
-
- Use in client components only (add `"use client"` directive)
|
|
246
|
-
- Avoid placing in `app/layout.tsx` for proper cleanup
|
|
160
|
+
**Parameters**
|
|
247
161
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
function Demo() {
|
|
252
|
-
return (
|
|
253
|
-
<div>
|
|
254
|
-
<Section1 />
|
|
255
|
-
<Section2 />
|
|
256
|
-
</div>
|
|
257
|
-
);
|
|
258
|
-
}
|
|
162
|
+
| Name | Type | Description |
|
|
163
|
+
| --------- | --------------------------- | ------------------------- |
|
|
164
|
+
| `options` | `Partial<AnimationOptions>` | Default animation options |
|
|
259
165
|
|
|
260
|
-
|
|
261
|
-
const { containerRef } = useAOSScope<HTMLDivElement>();
|
|
262
|
-
return <div ref={containerRef}>...</div>;
|
|
263
|
-
}
|
|
166
|
+
**Returns**
|
|
264
167
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
```
|
|
168
|
+
| Name | Type | Description |
|
|
169
|
+
| -------------- | -------------------- | ------------------------- |
|
|
170
|
+
| `containerRef` | `React.RefObject<E>` | Ref for container element |
|
|
270
171
|
|
|
271
172
|
### toAOSProps
|
|
272
173
|
|
|
273
|
-
Converts animation options to data attributes with type safety
|
|
174
|
+
Converts animation options to data attributes with type safety
|
|
274
175
|
|
|
275
176
|
```tsx
|
|
276
177
|
import { toAOSProps } from "react-gsap-aos";
|
|
@@ -280,12 +181,22 @@ const props = toAOSProps({
|
|
|
280
181
|
duration: 600,
|
|
281
182
|
easing: "power2.out",
|
|
282
183
|
});
|
|
283
|
-
// Returns
|
|
184
|
+
// Returns { "data-aos": "fade-up", "data-aos-duration": 600, ... }
|
|
284
185
|
```
|
|
285
186
|
|
|
187
|
+
**Parameters**
|
|
188
|
+
|
|
189
|
+
| Name | Type | Description |
|
|
190
|
+
| --------- | --------------------------- | ----------------- |
|
|
191
|
+
| `options` | `Partial<AnimationOptions>` | Animation options |
|
|
192
|
+
|
|
193
|
+
**Returns**
|
|
194
|
+
|
|
195
|
+
Returns an object containing `data-aos-*` attributes
|
|
196
|
+
|
|
286
197
|
### refreshScrollTrigger
|
|
287
198
|
|
|
288
|
-
Manually refresh AOS animation positions,
|
|
199
|
+
Manually refresh AOS animation positions, wraps `ScrollTrigger.refresh`
|
|
289
200
|
|
|
290
201
|
```tsx
|
|
291
202
|
import { refreshScrollTrigger } from "react-gsap-aos";
|
|
@@ -294,75 +205,51 @@ import { refreshScrollTrigger } from "react-gsap-aos";
|
|
|
294
205
|
refreshScrollTrigger();
|
|
295
206
|
```
|
|
296
207
|
|
|
297
|
-
**
|
|
298
|
-
|
|
299
|
-
```tsx
|
|
300
|
-
"use client";
|
|
208
|
+
**When to Use**
|
|
301
209
|
|
|
302
|
-
|
|
303
|
-
import { AOSProvider, refreshScrollTrigger } from "react-gsap-aos/client";
|
|
210
|
+
Call manually when layout changes occur, GSAP and its library have already addressed the following scenarios for you.
|
|
304
211
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
const [items, setItems] = useState([1, 2, 3]);
|
|
212
|
+
- Window resize
|
|
213
|
+
- Content height changes
|
|
308
214
|
|
|
309
|
-
|
|
310
|
-
// Refresh after visible change
|
|
311
|
-
refreshScrollTrigger();
|
|
312
|
-
}, [visible]);
|
|
215
|
+
However, due to certain limitations, the following situations require users to manually refresh.
|
|
313
216
|
|
|
314
|
-
|
|
315
|
-
<AOSProvider className="overflow-hidden">
|
|
316
|
-
<button onClick={() => setVisible((e) => !e)}>switch visible</button>
|
|
317
|
-
// When visible changes, the layout changes.
|
|
318
|
-
{visible ? <div className="h-80" /> : null}
|
|
319
|
-
<div data-aos-container>
|
|
320
|
-
<div key={item} data-aos="fade-up">
|
|
321
|
-
Hello AOS
|
|
322
|
-
</div>
|
|
323
|
-
</div>
|
|
324
|
-
</AOSProvider>
|
|
325
|
-
);
|
|
326
|
-
}
|
|
327
|
-
```
|
|
217
|
+
- Dynamically adding or removing large elements
|
|
328
218
|
|
|
329
|
-
|
|
219
|
+
https://gsap.com/docs/v3/Plugins/ScrollTrigger/refresh()
|
|
330
220
|
|
|
331
|
-
|
|
332
|
-
| ----------------- | ----------------- | --------------------------- | -------------- | ------------------------------ |
|
|
333
|
-
| `animation` | `Animation` | `data-aos` | `undefined` | Animation type |
|
|
334
|
-
| `offset` | `number` | `data-aos-offset` | `120` | Offset (px) from trigger point |
|
|
335
|
-
| `delay` | `number` | `data-aos-delay` | `0` | Animation delay (ms) |
|
|
336
|
-
| `duration` | `number` | `data-aos-duration` | `400` | Animation duration (ms) |
|
|
337
|
-
| `easing` | `Easing` | `data-aos-easing` | `"none"` | Easing function |
|
|
338
|
-
| `once` | `boolean` | `data-aos-once` | `false` | Animate only once |
|
|
339
|
-
| `mirror` | `boolean` | `data-aos-mirror` | `false` | Reverse animation on scroll up |
|
|
340
|
-
| `anchorPlacement` | `AnchorPlacement` | `data-aos-anchor-placement` | `"top-bottom"` | Trigger position |
|
|
341
|
-
| `markers` | `boolean` | `data-aos-markers` | `false` | ScrollTrigger markers |
|
|
221
|
+
## Type Definitions
|
|
342
222
|
|
|
343
|
-
|
|
223
|
+
### AnimationOptions
|
|
344
224
|
|
|
345
|
-
|
|
225
|
+
Complete type definition for animation options
|
|
346
226
|
|
|
347
|
-
|
|
227
|
+
```tsx
|
|
228
|
+
interface AnimationOptions {
|
|
229
|
+
animation?: Animation;
|
|
230
|
+
offset?: number;
|
|
231
|
+
delay?: number;
|
|
232
|
+
duration?: number;
|
|
233
|
+
easing?: Easing;
|
|
234
|
+
once?: boolean;
|
|
235
|
+
mirror?: boolean;
|
|
236
|
+
anchorPlacement?: AnchorPlacement;
|
|
237
|
+
markers?: boolean;
|
|
238
|
+
}
|
|
239
|
+
```
|
|
348
240
|
|
|
349
|
-
|
|
350
|
-
- `fade-up-right`, `fade-up-left`, `fade-down-right`, `fade-down-left`
|
|
241
|
+
### Animation
|
|
351
242
|
|
|
352
|
-
|
|
243
|
+
Supported animation types
|
|
353
244
|
|
|
245
|
+
- `fade`, `fade-up`, `fade-down`, `fade-left`, `fade-right`, `fade-up-right`, `fade-up-left`, `fade-down-right`, `fade-down-left`
|
|
354
246
|
- `flip-up`, `flip-down`, `flip-left`, `flip-right`
|
|
355
|
-
|
|
356
|
-
**Slide Animations:**
|
|
357
|
-
|
|
358
247
|
- `slide-up`, `slide-down`, `slide-left`, `slide-right`
|
|
248
|
+
- `zoom-in`, `zoom-in-up`, `zoom-in-down`, `zoom-in-left`, `zoom-in-right`, `zoom-out`, `zoom-out-up`, `zoom-out-down`, `zoom-out-left`, `zoom-out-right`
|
|
359
249
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
- `zoom-in`, `zoom-in-up`, `zoom-in-down`, `zoom-in-left`, `zoom-in-right`
|
|
363
|
-
- `zoom-out`, `zoom-out-up`, `zoom-out-down`, `zoom-out-left`, `zoom-out-right`
|
|
250
|
+
### Easing
|
|
364
251
|
|
|
365
|
-
|
|
252
|
+
Supported easing functions
|
|
366
253
|
|
|
367
254
|
- `none`
|
|
368
255
|
- `power1`, `power1.in`, `power1.out`, `power1.inOut`
|
|
@@ -376,10 +263,22 @@ export default function DynamicList() {
|
|
|
376
263
|
- `expo`, `expo.in`, `expo.out`, `expo.inOut`
|
|
377
264
|
- `sine`, `sine.in`, `sine.out`, `sine.inOut`
|
|
378
265
|
|
|
379
|
-
###
|
|
266
|
+
### AnchorPlacement
|
|
380
267
|
|
|
381
|
-
|
|
268
|
+
Anchor placement types (9 total), format is `[element-position]-[viewport-position]`
|
|
382
269
|
|
|
383
270
|
- `top-bottom`, `top-center`, `top-top`
|
|
384
271
|
- `center-bottom`, `center-center`, `center-top`
|
|
385
272
|
- `bottom-bottom`, `bottom-center`, `bottom-top`
|
|
273
|
+
|
|
274
|
+
## License
|
|
275
|
+
|
|
276
|
+
MIT ยฉ [Gaia Yang](https://github.com/GaiaYang)
|
|
277
|
+
|
|
278
|
+
Documentation and LLM [danielchim](https://github.com/danielchim)
|
|
279
|
+
|
|
280
|
+
## Credits
|
|
281
|
+
|
|
282
|
+
Animation styles inspired by [AOS](https://github.com/michalsnik/aos)
|
|
283
|
+
|
|
284
|
+
Powered by [GSAP](https://greensock.com/gsap) and [ScrollTrigger](https://greensock.com/scrolltrigger)
|