0
# Animation Utilities
1
2
Utility hooks and context providers for accessing animation values and gesture handlers within screen components, enabling custom animations and gesture-aware components.
3
4
## Capabilities
5
6
### useCardAnimation
7
8
Hook that provides access to card animation interpolation properties within stack screen components.
9
10
```typescript { .api }
11
/**
12
* Hook to access card animation values within stack screens
13
* @returns Card animation interpolation properties
14
* @throws Error if called outside of a stack screen context
15
*/
16
function useCardAnimation(): StackCardInterpolationProps;
17
```
18
19
**Usage Examples:**
20
21
```typescript
22
import React from 'react';
23
import { Animated, View } from 'react-native';
24
import { useCardAnimation } from '@react-navigation/stack';
25
26
function AnimatedScreen() {
27
const { current, closing, swiping } = useCardAnimation();
28
29
// Create custom animations based on card animation progress
30
const customOpacity = current.progress.interpolate({
31
inputRange: [0, 1],
32
outputRange: [0.3, 1],
33
});
34
35
const customScale = current.progress.interpolate({
36
inputRange: [0, 1],
37
outputRange: [0.9, 1],
38
});
39
40
const customRotation = current.progress.interpolate({
41
inputRange: [0, 1],
42
outputRange: ['-5deg', '0deg'],
43
});
44
45
return (
46
<Animated.View
47
style={{
48
flex: 1,
49
opacity: customOpacity,
50
transform: [
51
{ scale: customScale },
52
{ rotate: customRotation },
53
],
54
}}
55
>
56
<View style={{ padding: 20 }}>
57
<Text>Custom Animated Content</Text>
58
59
{/* Animate based on swipe gesture */}
60
<Animated.View
61
style={{
62
opacity: swiping.interpolate({
63
inputRange: [0, 1],
64
outputRange: [1, 0.5],
65
}),
66
}}
67
>
68
<Text>This fades during swipe gestures</Text>
69
</Animated.View>
70
71
{/* Animate based on closing state */}
72
<Animated.View
73
style={{
74
transform: [{
75
translateY: closing.interpolate({
76
inputRange: [0, 1],
77
outputRange: [0, -20],
78
}),
79
}],
80
}}
81
>
82
<Text>This moves up when closing</Text>
83
</Animated.View>
84
</View>
85
</Animated.View>
86
);
87
}
88
```
89
90
### useGestureHandlerRef
91
92
Hook that provides access to the gesture handler reference for coordinating custom gestures with navigation gestures.
93
94
```typescript { .api }
95
/**
96
* Hook to access gesture handler ref within stack screens
97
* @returns Gesture handler reference for coordination with navigation gestures
98
* @throws Error if called outside of a stack screen context
99
*/
100
function useGestureHandlerRef(): React.Ref<PanGestureHandler>;
101
```
102
103
**Usage Examples:**
104
105
```typescript
106
import React from 'react';
107
import { PanGestureHandler, State } from 'react-native-gesture-handler';
108
import { useGestureHandlerRef } from '@react-navigation/stack';
109
110
function GestureAwareScreen() {
111
const navigationGestureRef = useGestureHandlerRef();
112
const customGestureRef = useRef();
113
114
const handleGestureEvent = (event) => {
115
// Custom gesture handling that works with navigation gestures
116
console.log('Custom gesture:', event.nativeEvent);
117
};
118
119
const handleStateChange = (event) => {
120
if (event.nativeEvent.state === State.END) {
121
console.log('Custom gesture ended');
122
}
123
};
124
125
return (
126
<PanGestureHandler
127
ref={customGestureRef}
128
onGestureEvent={handleGestureEvent}
129
onHandlerStateChange={handleStateChange}
130
simultaneousHandlers={navigationGestureRef} // Allow simultaneous gestures
131
>
132
<View style={{ flex: 1 }}>
133
<Text>Swipe me while navigation gestures still work!</Text>
134
</View>
135
</PanGestureHandler>
136
);
137
}
138
```
139
140
### CardAnimationContext
141
142
React context that provides card animation interpolation properties to child components.
143
144
```typescript { .api }
145
/**
146
* Context providing card animation interpolation props to child components
147
* Value is undefined when not within a stack screen
148
*/
149
const CardAnimationContext: React.Context<StackCardInterpolationProps | undefined>;
150
```
151
152
**Usage Examples:**
153
154
```typescript
155
import React, { useContext } from 'react';
156
import { CardAnimationContext } from '@react-navigation/stack';
157
158
function CustomAnimatedComponent() {
159
const animationProps = useContext(CardAnimationContext);
160
161
if (!animationProps) {
162
// Not within a stack screen, render without animation
163
return <StaticComponent />;
164
}
165
166
const { current, next, closing } = animationProps;
167
168
const animatedOpacity = current.progress.interpolate({
169
inputRange: [0, 1],
170
outputRange: [0, 1],
171
});
172
173
return (
174
<Animated.View style={{ opacity: animatedOpacity }}>
175
<Text>Animated based on card transition</Text>
176
</Animated.View>
177
);
178
}
179
180
// Provider usage (automatically provided by stack navigator)
181
function CustomScreen() {
182
return (
183
<View>
184
<CustomAnimatedComponent />
185
</View>
186
);
187
}
188
```
189
190
### GestureHandlerRefContext
191
192
React context that provides the gesture handler reference for coordinating custom gestures.
193
194
```typescript { .api }
195
/**
196
* Context providing gesture handler ref to child components
197
* Value is null when not within a stack screen
198
*/
199
const GestureHandlerRefContext: React.Context<React.Ref<PanGestureHandler> | null>;
200
```
201
202
**Usage Examples:**
203
204
```typescript
205
import React, { useContext } from 'react';
206
import { PanGestureHandler } from 'react-native-gesture-handler';
207
import { GestureHandlerRefContext } from '@react-navigation/stack';
208
209
function NestedGestureComponent() {
210
const navigationGestureRef = useContext(GestureHandlerRefContext);
211
212
return (
213
<PanGestureHandler
214
simultaneousHandlers={navigationGestureRef}
215
onGestureEvent={(event) => {
216
// Handle custom gesture while preserving navigation gestures
217
console.log('Nested gesture:', event.nativeEvent);
218
}}
219
>
220
<View style={{ padding: 20, backgroundColor: 'lightblue' }}>
221
<Text>This area has custom gestures that work with navigation</Text>
222
</View>
223
</PanGestureHandler>
224
);
225
}
226
```
227
228
## Advanced Animation Patterns
229
230
### Coordinated Animations
231
232
Combine multiple animation utilities for complex effects:
233
234
```typescript
235
import { useCardAnimation, useGestureHandlerRef } from '@react-navigation/stack';
236
237
function AdvancedAnimatedScreen() {
238
const { current, next, closing, swiping } = useCardAnimation();
239
const gestureRef = useGestureHandlerRef();
240
241
// Parallax effect with background
242
const backgroundTranslateX = current.progress.interpolate({
243
inputRange: [0, 1],
244
outputRange: [100, 0],
245
});
246
247
// Content animation with gesture awareness
248
const contentOpacity = Animated.multiply(
249
current.progress,
250
swiping.interpolate({
251
inputRange: [0, 1],
252
outputRange: [1, 0.7],
253
})
254
);
255
256
return (
257
<View style={{ flex: 1 }}>
258
{/* Animated background */}
259
<Animated.View
260
style={{
261
position: 'absolute',
262
top: 0,
263
left: 0,
264
right: 0,
265
bottom: 0,
266
backgroundColor: 'lightblue',
267
transform: [{ translateX: backgroundTranslateX }],
268
}}
269
/>
270
271
{/* Animated content */}
272
<Animated.View
273
style={{
274
flex: 1,
275
opacity: contentOpacity,
276
}}
277
>
278
<Text>Advanced coordinated animation</Text>
279
</Animated.View>
280
</View>
281
);
282
}
283
```
284
285
### Conditional Animations
286
287
Use animation context for conditional rendering and animations:
288
289
```typescript
290
function ConditionalAnimationScreen() {
291
const animationProps = useCardAnimation();
292
const isAnimating = animationProps ? animationProps.current.progress._value < 1 : false;
293
294
return (
295
<View style={{ flex: 1 }}>
296
{isAnimating ? (
297
<LoadingComponent />
298
) : (
299
<MainContent />
300
)}
301
302
{animationProps && (
303
<Animated.View
304
style={{
305
position: 'absolute',
306
bottom: 20,
307
right: 20,
308
opacity: animationProps.current.progress.interpolate({
309
inputRange: [0.8, 1],
310
outputRange: [0, 1],
311
extrapolate: 'clamp',
312
}),
313
}}
314
>
315
<FloatingActionButton />
316
</Animated.View>
317
)}
318
</View>
319
);
320
}
321
```
322
323
## Animation Properties Reference
324
325
### StackCardInterpolationProps
326
327
Complete properties available through animation utilities:
328
329
```typescript { .api }
330
interface StackCardInterpolationProps {
331
current: {
332
progress: Animated.AnimatedInterpolation<number>;
333
};
334
next?: {
335
progress: Animated.AnimatedInterpolation<number>;
336
};
337
index: number;
338
closing: Animated.AnimatedInterpolation<0 | 1>;
339
swiping: Animated.AnimatedInterpolation<0 | 1>;
340
inverted: Animated.AnimatedInterpolation<-1 | 1>;
341
layouts: {
342
screen: Layout;
343
};
344
insets: {
345
top: number;
346
right: number;
347
bottom: number;
348
left: number;
349
};
350
}
351
352
interface Layout {
353
width: number;
354
height: number;
355
}
356
```
357
358
These properties enable:
359
- **current.progress**: Animation progress of the current screen (0 to 1)
360
- **next.progress**: Animation progress of the next screen in stack (if exists)
361
- **closing**: Whether the screen is closing (1) or opening (0)
362
- **swiping**: Whether user is actively swiping (1) or not (0)
363
- **inverted**: Animation direction multiplier (-1 for RTL, 1 for LTR)
364
- **layouts.screen**: Screen dimensions for responsive animations
365
- **insets**: Safe area insets for proper positioning