app-studio 0.6.46 → 0.6.47
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.
|
@@ -23,3 +23,8 @@ export declare const Comparison: ComponentStory<typeof View>;
|
|
|
23
23
|
* Multiple animations with mixed triggers
|
|
24
24
|
*/
|
|
25
25
|
export declare const MixedTriggers: ComponentStory<typeof View>;
|
|
26
|
+
/**
|
|
27
|
+
* Special Case: Timeline Override
|
|
28
|
+
* If you provide an explicit timeline (e.g. scroll()), it is respected even if animateOn="View" is set.
|
|
29
|
+
*/
|
|
30
|
+
export declare const TimelineOverride: ComponentStory<typeof View>;
|
|
@@ -18,3 +18,13 @@ export declare const ClickAnimation: ComponentStory<typeof View>;
|
|
|
18
18
|
export declare const AnimateInExample: ComponentStory<typeof View>;
|
|
19
19
|
export declare const AnimateOutExample: ComponentStory<typeof View>;
|
|
20
20
|
export declare const VisibleAnimation: ComponentStory<typeof View>;
|
|
21
|
+
/**
|
|
22
|
+
* Special Use Cases: Scroll-Driven Animations using Scroll Timeline
|
|
23
|
+
* These animations progress as the user scrolls, rather than just triggering on view.
|
|
24
|
+
*/
|
|
25
|
+
export declare const ScrollDrivenAnimations: ComponentStory<typeof View>;
|
|
26
|
+
/**
|
|
27
|
+
* Special Use Cases: View Timeline Presets
|
|
28
|
+
* Performant, pure-CSS animations that trigger when elements enter the viewport.
|
|
29
|
+
*/
|
|
30
|
+
export declare const ViewDrivenPresets: ComponentStory<typeof View>;
|
package/docs/Animation.md
CHANGED
|
@@ -2,16 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## 1. Introduction
|
|
4
4
|
|
|
5
|
-
App-Studio provides a powerful animation system through the `Animation` object. This system allows you to easily add dynamic and engaging animations
|
|
5
|
+
App-Studio provides a powerful animation system through the `Animation` object and the `Element` component. This system allows you to easily add dynamic and engaging animations, including:
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- **Standard CSS Animations**: Immediate animations on mount or loop.
|
|
8
|
+
- **Scroll-Triggered Animations** (`view()`): Animations that play when elements enter the viewport.
|
|
9
|
+
- **Scroll-Linked Animations** (`scroll()`): Animations driven by the scroll progress (e.g., parallax, reading progress).
|
|
10
|
+
- **Interactive Animations**: Triggered by events like hover, click, or focus.
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
## 2. Basic Usage
|
|
13
|
+
|
|
14
|
+
### Standard Animations
|
|
15
|
+
|
|
16
|
+
Use the `Animation` object to access standard animation presets.
|
|
10
17
|
|
|
11
18
|
```jsx
|
|
12
19
|
import { View, Animation } from 'app-studio';
|
|
13
20
|
|
|
14
|
-
// Simple animation
|
|
21
|
+
// Simple animation running immediately on mount
|
|
15
22
|
<View
|
|
16
23
|
animate={Animation.fadeIn({
|
|
17
24
|
duration: '1s',
|
|
@@ -27,349 +34,208 @@ Each animation function accepts an options object with these properties:
|
|
|
27
34
|
|
|
28
35
|
```typescript
|
|
29
36
|
type AnimationOptions = {
|
|
30
|
-
duration?: string;
|
|
31
|
-
timingFunction?: string;
|
|
37
|
+
duration?: string; // e.g., '1s', '500ms'
|
|
38
|
+
timingFunction?: string; // e.g., 'ease', 'linear', 'cubic-bezier(...)'
|
|
32
39
|
iterationCount?: string | number; // e.g., '1', 'infinite'
|
|
40
|
+
delay?: string; // e.g., '0.5s'
|
|
41
|
+
direction?: string; // e.g., 'normal', 'reverse', 'alternate'
|
|
42
|
+
fillMode?: string; // e.g., 'forwards', 'both'
|
|
43
|
+
playState?: string; // e.g., 'running', 'paused'
|
|
33
44
|
}
|
|
34
45
|
```
|
|
35
46
|
|
|
36
|
-
## 3. Animation
|
|
37
|
-
|
|
38
|
-
|
|
47
|
+
## 3. Element Props for Animation
|
|
48
|
+
|
|
49
|
+
The `Element` component (and components extending it like `View`, `Text`, `Image`) supports several props to control animations:
|
|
39
50
|
|
|
40
|
-
|
|
51
|
+
### `animate`
|
|
52
|
+
The main property to apply animations. Accepts a single animation object or an array of animations.
|
|
41
53
|
|
|
42
54
|
```jsx
|
|
43
|
-
|
|
44
|
-
Animation.fadeIn()
|
|
45
|
-
Animation.fadeOut()
|
|
46
|
-
|
|
47
|
-
// Slide animations (move elements)
|
|
48
|
-
Animation.slideInLeft()
|
|
49
|
-
Animation.slideInRight()
|
|
50
|
-
Animation.slideOutLeft()
|
|
51
|
-
Animation.slideOutRight()
|
|
52
|
-
Animation.slideInUp()
|
|
53
|
-
Animation.slideOutDown()
|
|
55
|
+
<View animate={Animation.bounce()} />
|
|
56
|
+
<View animate={[Animation.fadeIn(), Animation.slideInUp()]} />
|
|
54
57
|
```
|
|
55
58
|
|
|
56
|
-
###
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```jsx
|
|
61
|
-
// Rotate
|
|
62
|
-
Animation.rotate()
|
|
63
|
-
|
|
64
|
-
// Scale
|
|
65
|
-
Animation.scale()
|
|
66
|
-
|
|
67
|
-
// Translate
|
|
68
|
-
Animation.translate()
|
|
69
|
-
```
|
|
59
|
+
### `animateIn` & `animateOut`
|
|
60
|
+
Useful for mounting and unmounting transitions, or conditional rendering effects.
|
|
61
|
+
- `animateIn`: Applied when the component mounts or becomes visible (if `IntersectionObserver` is used internally).
|
|
62
|
+
- `animateOut`: Applied during unmount cleanup (requires immediate re-render or external handling to be visible).
|
|
70
63
|
|
|
71
|
-
###
|
|
64
|
+
### `animateOn`
|
|
65
|
+
Controls *when* the animation defined in `animate` starts.
|
|
72
66
|
|
|
73
|
-
|
|
67
|
+
- `'Mount'` (default): Animation starts immediately when the component is added to the DOM.
|
|
68
|
+
- `'View'`: Animation is converted to a CSS `view()` timeline animation. It plays as the element enters the viewport. **No JavaScript required.**
|
|
69
|
+
- `'Both'`: Technically same as Mount for most cases, ensuring visibility.
|
|
74
70
|
|
|
75
71
|
```jsx
|
|
76
|
-
//
|
|
77
|
-
Animation.
|
|
78
|
-
Animation.pulse()
|
|
79
|
-
Animation.shake()
|
|
80
|
-
Animation.flash()
|
|
81
|
-
|
|
82
|
-
// Special effects
|
|
83
|
-
Animation.flip()
|
|
84
|
-
Animation.rubberBand()
|
|
85
|
-
Animation.heartBeat()
|
|
72
|
+
// Trigger animation only when user scrolls it into view
|
|
73
|
+
<View animate={Animation.slideInUp()} animateOn="View" />
|
|
86
74
|
```
|
|
87
75
|
|
|
88
|
-
## 4.
|
|
76
|
+
## 4. Animation Presets
|
|
89
77
|
|
|
90
|
-
|
|
78
|
+
App-Studio comes with a comprehensive library of ready-to-use animations available under the `Animation` namespace.
|
|
91
79
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
animate: Animation.pulse({
|
|
99
|
-
duration: "1s",
|
|
100
|
-
iterationCount: "infinite",
|
|
101
|
-
}),
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
// Animation on click
|
|
105
|
-
click: {
|
|
106
|
-
animate: Animation.flash({ duration: '0.5s' })
|
|
107
|
-
}
|
|
108
|
-
}}
|
|
109
|
-
/>
|
|
110
|
-
```
|
|
80
|
+
### Fades
|
|
81
|
+
- `Animation.fadeIn()`
|
|
82
|
+
- `Animation.fadeOut()`
|
|
83
|
+
- `Animation.fadeInDown()`
|
|
84
|
+
- `Animation.fadeInUp()`
|
|
85
|
+
- `Animation.fadeInScroll()` - Scroll-progress driven fade
|
|
111
86
|
|
|
112
|
-
|
|
87
|
+
### Slides
|
|
88
|
+
- `Animation.slideInLeft()`
|
|
89
|
+
- `Animation.slideInRight()`
|
|
90
|
+
- `Animation.slideInDown()`
|
|
91
|
+
- `Animation.slideInUp()`
|
|
92
|
+
- `Animation.slideOutLeft()`
|
|
93
|
+
- `Animation.slideOutRight()`
|
|
94
|
+
- `Animation.slideInLeftScroll()` - Scroll-progress driven slide
|
|
113
95
|
|
|
114
|
-
|
|
96
|
+
### Zooms & Scales
|
|
97
|
+
- `Animation.zoomIn()`
|
|
98
|
+
- `Animation.zoomOut()`
|
|
99
|
+
- `Animation.zoomInDown()`
|
|
100
|
+
- `Animation.zoomOutUp()`
|
|
101
|
+
- `Animation.scale()` - Pulse scale effect
|
|
102
|
+
- `Animation.scaleDownScroll()`
|
|
103
|
+
- `Animation.listItemScaleScroll()`
|
|
115
104
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
animate: Animation.fadeIn({ duration: '1s' })
|
|
121
|
-
},
|
|
122
|
-
tablet: {
|
|
123
|
-
animate: Animation.slideInLeft({ duration: '0.5s' })
|
|
124
|
-
},
|
|
125
|
-
desktop: {
|
|
126
|
-
animate: Animation.bounce({ duration: '2s' })
|
|
127
|
-
}
|
|
128
|
-
}}
|
|
129
|
-
/>
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## 6. Custom Animation Sequences
|
|
133
|
-
|
|
134
|
-
You can create complex animation sequences by defining an array of animation states. Each state in the sequence is an object with `from` and `to` properties that define the CSS styles at the start and end of that animation segment.
|
|
105
|
+
### Bounces
|
|
106
|
+
- `Animation.bounce()`
|
|
107
|
+
- `Animation.bounceIn()`
|
|
108
|
+
- `Animation.bounceOut()`
|
|
135
109
|
|
|
136
|
-
|
|
110
|
+
### Flips & Rotations
|
|
111
|
+
- `Animation.rotate()`
|
|
112
|
+
- `Animation.flip()`
|
|
113
|
+
- `Animation.flipInX()`
|
|
114
|
+
- `Animation.flipInY()`
|
|
115
|
+
- `Animation.rollIn()`
|
|
116
|
+
- `Animation.rollOut()`
|
|
117
|
+
- `Animation.swing()`
|
|
137
118
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
<View animate={simpleSequence} />
|
|
149
|
-
```
|
|
119
|
+
### Attention Seekers & Effects
|
|
120
|
+
- `Animation.pulse()`
|
|
121
|
+
- `Animation.flash()`
|
|
122
|
+
- `Animation.shake()`
|
|
123
|
+
- `Animation.headShake()`
|
|
124
|
+
- `Animation.rubberBand()`
|
|
125
|
+
- `Animation.wobble()`
|
|
126
|
+
- `Animation.heartBeat()`
|
|
127
|
+
- `Animation.tada()`
|
|
128
|
+
- `Animation.jello()`
|
|
150
129
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
duration: "2s",
|
|
159
|
-
timingFunction: "ease-in",
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
from: { opacity: 1, transform: "translateY(100px)" },
|
|
163
|
-
to: { opacity: 0, transform: "translateY(0)" },
|
|
164
|
-
duration: "2s",
|
|
165
|
-
timingFunction: "ease-out",
|
|
166
|
-
},
|
|
167
|
-
];
|
|
168
|
-
|
|
169
|
-
<View animate={complexSequence} />
|
|
170
|
-
```
|
|
130
|
+
### Extrances & Exits
|
|
131
|
+
- `Animation.lightSpeedIn()`
|
|
132
|
+
- `Animation.lightSpeedOut()`
|
|
133
|
+
- `Animation.jackInTheBox()`
|
|
134
|
+
- `Animation.hinge()`
|
|
135
|
+
- `Animation.backInDown()`
|
|
136
|
+
- `Animation.backOutUp()`
|
|
171
137
|
|
|
172
|
-
|
|
138
|
+
### Special / Scroll-Driven
|
|
139
|
+
- `Animation.shimmer()` - Loading shimmer effect
|
|
140
|
+
- `Animation.typewriter()` - Typing effect
|
|
141
|
+
- `Animation.blinkCursor()`
|
|
142
|
+
- `Animation.handWaveScroll()`
|
|
143
|
+
- `Animation.ctaCollapseScroll()`
|
|
144
|
+
- `Animation.fillTextScroll()`
|
|
173
145
|
|
|
174
|
-
|
|
146
|
+
## 5. View Timeline Animations (Scroll-Driven)
|
|
175
147
|
|
|
176
|
-
|
|
148
|
+
There are two ways to create animations that trigger on scroll into view:
|
|
149
|
+
|
|
150
|
+
### 1. Using `animateOn="View"`
|
|
151
|
+
This works with any standard animation.
|
|
177
152
|
|
|
178
153
|
```jsx
|
|
179
|
-
// Default: Animations trigger on mount (immediate)
|
|
180
|
-
<View animate={Animation.fadeIn()} />
|
|
181
|
-
|
|
182
|
-
// Explicitly set to trigger on mount (same as default)
|
|
183
|
-
<View animate={Animation.fadeIn()} animateOn="Both" />
|
|
184
|
-
<View animate={Animation.fadeIn()} animateOn="Mount" />
|
|
185
|
-
|
|
186
|
-
// Trigger only when scrolling into viewport
|
|
187
154
|
<View animate={Animation.fadeIn()} animateOn="View" />
|
|
188
155
|
```
|
|
189
156
|
|
|
190
|
-
###
|
|
191
|
-
|
|
192
|
-
**Both / Mount (Default)**
|
|
193
|
-
- ✅ **Immediate feedback** - Animates as soon as element appears
|
|
194
|
-
- ✅ **Familiar behavior** - Works like traditional CSS animations
|
|
195
|
-
- ✅ **No dependencies** - Works in all browsers
|
|
196
|
-
- 📌 **Best for**: Hero sections, immediately visible content
|
|
197
|
-
|
|
198
|
-
**View**
|
|
199
|
-
- ✅ **Better performance** - Pure CSS, no JavaScript state
|
|
200
|
-
- ✅ **No re-renders** - Browser handles visibility detection
|
|
201
|
-
- ✅ **Scroll-triggered** - Animates when user scrolls to it
|
|
202
|
-
- 📌 **Best for**: Content below the fold that should animate on scroll
|
|
203
|
-
|
|
204
|
-
### When to Use Each Mode
|
|
205
|
-
|
|
206
|
-
```jsx
|
|
207
|
-
// Hero section - animate immediately
|
|
208
|
-
<View animate={Animation.fadeIn()} animateOn="Mount">
|
|
209
|
-
<Text>Welcome!</Text>
|
|
210
|
-
</View>
|
|
211
|
-
|
|
212
|
-
// Content card - animate on scroll into view
|
|
213
|
-
<View animate={Animation.slideUp()} animateOn="View">
|
|
214
|
-
<Text>This card animates when scrolled into view</Text>
|
|
215
|
-
</View>
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
## 8. View Timeline Animations (CSS Scroll-Driven)
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
App-Studio provides performant scroll-driven animations using CSS `animation-timeline: view()`. These animations trigger when elements enter/exit the viewport **without any JavaScript state or IntersectionObserver**.
|
|
222
|
-
|
|
223
|
-
### Benefits
|
|
224
|
-
|
|
225
|
-
- ✅ **No JavaScript state** - Pure CSS, no `useState` or re-renders
|
|
226
|
-
- ✅ **No IntersectionObserver** - Browser handles visibility detection
|
|
227
|
-
- ✅ **Compositor thread** - Smooth 60fps animations
|
|
228
|
-
- ✅ **JSON configurable** - Define animations as data
|
|
229
|
-
|
|
230
|
-
### Basic Usage
|
|
157
|
+
### 2. Using `*OnView` Helper Functions
|
|
158
|
+
These are performant, pure CSS animations explicitly designed for entry/exit effects. Imported directly from `app-studio`.
|
|
231
159
|
|
|
232
160
|
```jsx
|
|
233
|
-
import {
|
|
161
|
+
import {
|
|
162
|
+
fadeInOnView,
|
|
163
|
+
slideUpOnView,
|
|
164
|
+
scaleUpOnView,
|
|
165
|
+
blurInOnView,
|
|
166
|
+
rotateInOnView,
|
|
167
|
+
revealOnView,
|
|
168
|
+
flipXOnView,
|
|
169
|
+
flipYOnView
|
|
170
|
+
} from 'app-studio';
|
|
234
171
|
|
|
235
|
-
// Elements animate when scrolling into view
|
|
236
172
|
<View animate={fadeInOnView()} />
|
|
237
173
|
<View animate={slideUpOnView({ distance: '50px' })} />
|
|
238
|
-
<View animate={
|
|
174
|
+
<View animate={revealOnView()} /> // Clip-path reveal
|
|
239
175
|
```
|
|
240
176
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
| Function | Effect | Default Range |
|
|
244
|
-
|----------|--------|---------------|
|
|
245
|
-
| `fadeInOnView()` | Fade in | entry |
|
|
246
|
-
| `fadeOutOnView()` | Fade out | exit |
|
|
247
|
-
| `slideUpOnView()` | Slide up + fade | entry |
|
|
248
|
-
| `slideDownOnView()` | Slide down + fade | entry |
|
|
249
|
-
| `slideLeftOnView()` | Slide from left | entry |
|
|
250
|
-
| `slideRightOnView()` | Slide from right | entry |
|
|
251
|
-
| `scaleUpOnView()` | Scale up (0.9→1) | entry |
|
|
252
|
-
| `scaleDownOnView()` | Scale down | entry |
|
|
253
|
-
| `blurInOnView()` | Blur in | entry |
|
|
254
|
-
| `blurOutOnView()` | Blur out | exit |
|
|
255
|
-
| `rotateInOnView()` | Rotate + scale | entry |
|
|
256
|
-
| `revealOnView()` | Clip-path reveal | entry |
|
|
257
|
-
| `flipXOnView()` | 3D flip X | entry |
|
|
258
|
-
| `flipYOnView()` | 3D flip Y | entry |
|
|
259
|
-
|
|
260
|
-
### Custom Options
|
|
261
|
-
|
|
262
|
-
```jsx
|
|
263
|
-
// All presets accept customization options
|
|
264
|
-
<View animate={fadeInOnView({
|
|
265
|
-
duration: '1s',
|
|
266
|
-
timingFunction: 'ease-out',
|
|
267
|
-
delay: '0.2s',
|
|
268
|
-
range: 'entry 0% entry 80%'
|
|
269
|
-
})} />
|
|
270
|
-
|
|
271
|
-
<View animate={slideUpOnView({ distance: '60px' })} />
|
|
272
|
-
<View animate={blurInOnView({ blur: '20px' })} />
|
|
273
|
-
<View animate={scaleUpOnView({ scale: 0.7 })} />
|
|
274
|
-
```
|
|
177
|
+
## 6. Scroll Progress Animations
|
|
275
178
|
|
|
276
|
-
|
|
179
|
+
These animations are linked to the scroll position associated with a timeline (usually the nearest scroller). As you scroll active range, the animation progresses.
|
|
277
180
|
|
|
278
181
|
```jsx
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
<View animate={animateOnView({
|
|
282
|
-
keyframes: {
|
|
283
|
-
from: { opacity: 0, transform: 'rotate(-10deg) scale(0.9)' },
|
|
284
|
-
to: { opacity: 1, transform: 'rotate(0) scale(1)' }
|
|
285
|
-
},
|
|
286
|
-
timing: {
|
|
287
|
-
duration: '0.8s',
|
|
288
|
-
timingFunction: 'ease-out'
|
|
289
|
-
},
|
|
290
|
-
range: 'entry'
|
|
291
|
-
})} />
|
|
292
|
-
```
|
|
182
|
+
// Text that fills efficiently as you scroll (requires CSS variable support)
|
|
183
|
+
<View animate={Animation.fillTextScroll()} />
|
|
293
184
|
|
|
294
|
-
|
|
185
|
+
// Image that unclips/expands as you scroll
|
|
186
|
+
<View animate={Animation.unclipScroll()} />
|
|
295
187
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
<View animate={[
|
|
299
|
-
fadeInOnView({ range: 'entry' }),
|
|
300
|
-
fadeOutOnView({ range: 'exit' })
|
|
301
|
-
]} />
|
|
302
|
-
|
|
303
|
-
<View animate={[
|
|
304
|
-
slideUpOnView({ range: 'entry' }),
|
|
305
|
-
blurOutOnView({ range: 'exit' })
|
|
306
|
-
]} />
|
|
188
|
+
// Item that fades in based on scroll progress
|
|
189
|
+
<View animate={Animation.fadeInScroll()} />
|
|
307
190
|
```
|
|
308
191
|
|
|
309
|
-
|
|
192
|
+
## 7. Event-Based Animations
|
|
193
|
+
|
|
194
|
+
You can trigger animations on interactions like hover, click, or focus using the `on` prop or underscore props (`_hover`, `_active`).
|
|
310
195
|
|
|
311
196
|
```jsx
|
|
312
|
-
|
|
313
|
-
{
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
197
|
+
<View
|
|
198
|
+
_hover={{
|
|
199
|
+
// Pulse animation while hovering
|
|
200
|
+
animate: Animation.pulse({ duration: '0.5s' }),
|
|
201
|
+
scale: 1.05
|
|
202
|
+
}}
|
|
203
|
+
|
|
204
|
+
on={{
|
|
205
|
+
click: {
|
|
206
|
+
animate: Animation.flash()
|
|
207
|
+
}
|
|
208
|
+
}}
|
|
209
|
+
>
|
|
210
|
+
<Text>Hover or Click Me</Text>
|
|
211
|
+
</View>
|
|
321
212
|
```
|
|
322
213
|
|
|
323
|
-
|
|
214
|
+
## 8. Custom Animation Sequences
|
|
215
|
+
|
|
216
|
+
You can create complex animation sequences by configuring keyframes directly.
|
|
324
217
|
|
|
325
218
|
```jsx
|
|
326
|
-
|
|
219
|
+
const customTwist = {
|
|
220
|
+
from: { transform: 'rotate(0deg) scale(1)' },
|
|
221
|
+
'50%': { transform: 'rotate(180deg) scale(1.5)' },
|
|
222
|
+
to: { transform: 'rotate(360deg) scale(1)' },
|
|
223
|
+
duration: '2s',
|
|
224
|
+
iterationCount: 'infinite'
|
|
225
|
+
};
|
|
327
226
|
|
|
328
|
-
|
|
329
|
-
<View animate={createViewAnimation(viewAnimationPresets.fadeIn)} />
|
|
330
|
-
<View animate={createViewAnimation(viewAnimationPresets.slideUp)} />
|
|
331
|
-
<View animate={createViewAnimation(viewAnimationPresets.reveal)} />
|
|
227
|
+
<View animate={customTwist} />
|
|
332
228
|
```
|
|
333
229
|
|
|
334
|
-
### Browser Support
|
|
335
|
-
|
|
336
|
-
| Browser | Support |
|
|
337
|
-
|---------|---------|
|
|
338
|
-
| Chrome 115+ | ✅ Full |
|
|
339
|
-
| Edge 115+ | ✅ Full |
|
|
340
|
-
| Safari 17.4+ | ✅ Full |
|
|
341
|
-
| Firefox 110+ | ⚠️ Partial |
|
|
342
|
-
|
|
343
|
-
> **Note:** In unsupported browsers, elements appear without animation (graceful degradation).
|
|
344
|
-
|
|
345
230
|
## 9. Best Practices
|
|
346
231
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
3. **Code Organization**
|
|
359
|
-
- Define reusable animation configurations as JSON
|
|
360
|
-
- Use meaningful names for custom sequences
|
|
361
|
-
- Keep animation logic separate from component logic:
|
|
362
|
-
```jsx
|
|
363
|
-
const myAnimation = fadeInOnView({ duration: '1s' });
|
|
364
|
-
<View animate={myAnimation} />
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
4. **Responsive Design**
|
|
368
|
-
- Adjust animation duration for different screen sizes
|
|
369
|
-
- Consider disabling complex animations on mobile
|
|
370
|
-
- Test animations on real devices
|
|
371
|
-
|
|
372
|
-
5. **View Timeline Animations**
|
|
373
|
-
- Use for on-scroll reveal effects instead of `animateIn`
|
|
374
|
-
- Combine entry and exit animations for complete interactions
|
|
375
|
-
- Use staggered delays for list animations
|
|
232
|
+
1. **Performance**: Prefer standard transforms (`translate`, `scale`, `rotate`) and `opacity`. Avoid animating layout properties like `width` or `margin`.
|
|
233
|
+
2. **Scroll Animations**: Use `animateOn="View"` or `*OnView` helpers for "reveal" effects, as they run on the compositor thread and don't require JavaScript listeners.
|
|
234
|
+
3. **Accessibility**: Respect user motion preferences.
|
|
235
|
+
4. **Composability**: You can mix standard styles with animations.
|
|
236
|
+
```jsx
|
|
237
|
+
<View
|
|
238
|
+
style={{ opacity: 0 }} // Initial state
|
|
239
|
+
animate={Animation.fadeIn({ delay: '0.5s', fillMode: 'forwards' })}
|
|
240
|
+
/>
|
|
241
|
+
```
|
package/package.json
CHANGED