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 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
- ## What is react-gsap-aos?
12
+ ## Project Advantages
13
13
 
14
- `react-gsap-aos` bridges the gap between GSAP's powerful animation capabilities and the simplicity of AOS (Animate On Scroll). It provides:
14
+ This is a monorepo managed with pnpm workspaces.
15
15
 
16
- - **Familiar API**: If you've used AOS, you already know how to use this
17
- - **GSAP Power**: Built on GSAP + ScrollTrigger for smooth, performant animations
18
- - **React-First**: Designed specifically for React and Next.js with proper SSR support
19
- - **TypeScript**: Full type safety for animations, easings, and anchor placements
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 Demo() {
31
+ export default function App() {
68
32
  return (
69
33
  <AOSProvider className="overflow-hidden">
70
34
  <div data-aos-container>
71
- <div data-aos="fade-up" data-aos-offset="200">
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
- ## Usage
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
- {/* Your animated content */}
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
- > The `overflow-hidden` class prevents elements from overflowing during their initial animation state.
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
- ### Configuring Animations with Data Attributes
103
-
104
- Use `data-aos-*` attributes to configure animation behavior:
75
+ ### Dynamic Content
105
76
 
106
77
  ```tsx
107
- <div
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
- ```tsx
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
- <div
129
- {...toAOSProps({
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
- ```tsx
167
- <div data-aos-container>
168
- <div data-aos="fade-up">Parent animation</div>
87
+ useEffect(() => {
88
+ refreshScrollTrigger();
89
+ }, [items]);
169
90
 
170
- <div data-aos-container>
171
- <div data-aos="zoom-in">Nested animation</div>
172
- </div>
173
- </div>
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
- A wrapper component that provides animation scope for its children.
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 will inherit these default options */}
206
- </AOSProvider>
126
+ {/* Children */}
127
+ </AOSProvider>;
207
128
  ```
208
129
 
209
- > The default options only affect animations generated subsequently. This is intentional behavior.
210
-
211
- ### useAOSScope
130
+ **Props**
212
131
 
213
- The core hook that powers `AOSProvider`. Use this when you need direct control over the container ref.
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
- ```tsx
216
- function useAOSScope<E extends HTMLElement = HTMLElement>(
217
- options?: Partial<AnimationOptions>,
218
- ): { containerRef: React.RefObject<E> };
219
- ```
139
+ ### useAOSScope
220
140
 
221
- **Example:**
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
- export default function Demo() {
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
- โš ๏ธ **Important**:
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
- **Parallel Usage:**
249
-
250
- ```tsx
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
- function Section1() {
261
- const { containerRef } = useAOSScope<HTMLDivElement>();
262
- return <div ref={containerRef}>...</div>;
263
- }
166
+ **Returns**
264
167
 
265
- function Section2() {
266
- const { containerRef } = useAOSScope<HTMLDivElement>();
267
- return <div ref={containerRef}>...</div>;
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: { "data-aos": "fade-up", "data-aos-duration": 600, ... }
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, wrapper around [`ScrollTrigger.refresh`](<https://gsap.com/docs/v3/Plugins/ScrollTrigger/refresh()>).
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
- **Example with Dynamic Content:**
298
-
299
- ```tsx
300
- "use client";
208
+ **When to Use**
301
209
 
302
- import { useState, useEffect } from "react";
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
- export default function DynamicList() {
306
- const [visible, setVisible] = useState(true);
307
- const [items, setItems] = useState([1, 2, 3]);
212
+ - Window resize
213
+ - Content height changes
308
214
 
309
- useEffect(() => {
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
- return (
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
- ## Animation Options
219
+ https://gsap.com/docs/v3/Plugins/ScrollTrigger/refresh()
330
220
 
331
- | Option | Type | Data Attribute | Default | Description |
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
- ## Available Types
223
+ ### AnimationOptions
344
224
 
345
- ### Animation Types (34 total)
225
+ Complete type definition for animation options
346
226
 
347
- **Fade Animations:**
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
- - `fade`, `fade-up`, `fade-down`, `fade-left`, `fade-right`
350
- - `fade-up-right`, `fade-up-left`, `fade-down-right`, `fade-down-left`
241
+ ### Animation
351
242
 
352
- **Flip Animations:**
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
- **Zoom Animations:**
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
- ### Easing Types (17 total)
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
- ### Anchor Placement Types (9 total)
266
+ ### AnchorPlacement
380
267
 
381
- Format: `[element-position]-[viewport-position]`
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)