0
# Animation and Transitions
1
2
Built-in animation presets and custom transition configurations for smooth tab switching experiences with full control over timing, easing, and visual effects.
3
4
## Capabilities
5
6
### Scene Style Interpolators
7
8
Pre-built interpolation functions for common tab transition animations.
9
10
```typescript { .api }
11
/**
12
* Scene style interpolators for tab transitions
13
*/
14
const SceneStyleInterpolators: {
15
/**
16
* Simple cross-fade animation between tabs
17
*/
18
forFade: BottomTabSceneStyleInterpolator;
19
20
/**
21
* Animation where screens slightly shift to left/right during transitions
22
*/
23
forShift: BottomTabSceneStyleInterpolator;
24
};
25
26
/**
27
* Function type for scene style interpolation
28
*/
29
type BottomTabSceneStyleInterpolator = (
30
props: BottomTabSceneInterpolationProps
31
) => BottomTabSceneInterpolatedStyle;
32
33
interface BottomTabSceneInterpolationProps {
34
current: {
35
/**
36
* Animated value for the current screen:
37
* - -1 if the index is lower than active tab
38
* - 0 if they're active
39
* - 1 if the index is higher than active tab
40
*/
41
progress: Animated.Value;
42
};
43
}
44
45
interface BottomTabSceneInterpolatedStyle {
46
/**
47
* Interpolated style for the view containing screen content
48
*/
49
sceneStyle: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
50
}
51
```
52
53
**Usage Examples:**
54
55
```typescript
56
import { SceneStyleInterpolators } from "@react-navigation/bottom-tabs";
57
58
<Tab.Screen
59
name="FadeScreen"
60
component={FadeScreen}
61
options={{
62
animation: 'fade',
63
sceneStyleInterpolator: SceneStyleInterpolators.forFade,
64
}}
65
/>
66
67
<Tab.Screen
68
name="ShiftScreen"
69
component={ShiftScreen}
70
options={{
71
animation: 'shift',
72
sceneStyleInterpolator: SceneStyleInterpolators.forShift,
73
}}
74
/>
75
```
76
77
### Transition Presets
78
79
Complete animation presets combining timing specifications with style interpolators.
80
81
```typescript { .api }
82
/**
83
* Pre-configured transition presets for tab animations
84
*/
85
const TransitionPresets: {
86
/**
87
* Fade transition with timing configuration
88
*/
89
FadeTransition: BottomTabTransitionPreset;
90
91
/**
92
* Shift transition with timing configuration
93
*/
94
ShiftTransition: BottomTabTransitionPreset;
95
};
96
97
interface BottomTabTransitionPreset {
98
/**
99
* Whether transition animations should be enabled when switching tabs
100
*/
101
animationEnabled?: boolean;
102
103
/**
104
* Function which specifies interpolated styles for bottom-tab scenes
105
*/
106
sceneStyleInterpolator?: BottomTabSceneStyleInterpolator;
107
108
/**
109
* Object which specifies the animation type (timing or spring) and options
110
*/
111
transitionSpec?: TransitionSpec;
112
}
113
```
114
115
**Usage Examples:**
116
117
```typescript
118
import { TransitionPresets } from "@react-navigation/bottom-tabs";
119
120
<Tab.Navigator
121
screenOptions={{
122
...TransitionPresets.FadeTransition,
123
}}
124
>
125
{/* All screens will use fade transition */}
126
</Tab.Navigator>
127
128
<Tab.Screen
129
name="SpecialScreen"
130
component={SpecialScreen}
131
options={{
132
...TransitionPresets.ShiftTransition,
133
// Override specific properties
134
animationEnabled: true,
135
}}
136
/>
137
```
138
139
### Transition Specifications
140
141
Timing and spring animation configurations for precise control over transition behavior.
142
143
```typescript { .api }
144
/**
145
* Animation timing specifications
146
*/
147
const TransitionSpecs: {
148
/**
149
* Timing spec for fade animations (150ms linear easing)
150
*/
151
FadeSpec: TransitionSpec;
152
153
/**
154
* Timing spec for shift animations (150ms ease-in-out)
155
*/
156
ShiftSpec: TransitionSpec;
157
};
158
159
type TransitionSpec =
160
| {
161
animation: 'timing';
162
config: Omit<
163
Animated.TimingAnimationConfig,
164
'toValue' | keyof Animated.AnimationConfig
165
>;
166
}
167
| {
168
animation: 'spring';
169
config: Omit<
170
Animated.SpringAnimationConfig,
171
'toValue' | keyof Animated.AnimationConfig
172
>;
173
};
174
```
175
176
**Usage Examples:**
177
178
```typescript
179
import { TransitionSpecs } from "@react-navigation/bottom-tabs";
180
181
<Tab.Screen
182
name="TimedScreen"
183
component={TimedScreen}
184
options={{
185
transitionSpec: TransitionSpecs.FadeSpec,
186
animation: 'fade',
187
}}
188
/>
189
190
// Custom timing specification
191
<Tab.Screen
192
name="CustomTiming"
193
component={CustomScreen}
194
options={{
195
transitionSpec: {
196
animation: 'timing',
197
config: {
198
duration: 300,
199
easing: Easing.bezier(0.4, 0, 0.2, 1),
200
},
201
},
202
}}
203
/>
204
205
// Spring animation specification
206
<Tab.Screen
207
name="SpringScreen"
208
component={SpringScreen}
209
options={{
210
transitionSpec: {
211
animation: 'spring',
212
config: {
213
stiffness: 1000,
214
damping: 500,
215
mass: 3,
216
overshootClamping: true,
217
restDisplacementThreshold: 0.01,
218
restSpeedThreshold: 0.01,
219
},
220
},
221
}}
222
/>
223
```
224
225
### Custom Scene Interpolators
226
227
Create custom animation effects by implementing your own scene style interpolators.
228
229
```typescript { .api }
230
/**
231
* Custom scene style interpolator implementation
232
*/
233
type CustomSceneStyleInterpolator = (
234
props: BottomTabSceneInterpolationProps
235
) => BottomTabSceneInterpolatedStyle;
236
```
237
238
**Usage Examples:**
239
240
```typescript
241
// Custom scale and rotate interpolator
242
const scaleRotateInterpolator = ({ current }) => ({
243
sceneStyle: {
244
opacity: current.progress.interpolate({
245
inputRange: [-1, 0, 1],
246
outputRange: [0, 1, 0],
247
}),
248
transform: [
249
{
250
scale: current.progress.interpolate({
251
inputRange: [-1, 0, 1],
252
outputRange: [0.85, 1, 0.85],
253
}),
254
},
255
{
256
rotateY: current.progress.interpolate({
257
inputRange: [-1, 0, 1],
258
outputRange: ['-45deg', '0deg', '45deg'],
259
}),
260
},
261
],
262
},
263
});
264
265
// Custom slide and blur effect
266
const slideBlurInterpolator = ({ current }) => ({
267
sceneStyle: {
268
opacity: current.progress.interpolate({
269
inputRange: [-1, -0.5, 0, 0.5, 1],
270
outputRange: [0, 0.5, 1, 0.5, 0],
271
}),
272
transform: [
273
{
274
translateX: current.progress.interpolate({
275
inputRange: [-1, 0, 1],
276
outputRange: [-200, 0, 200],
277
}),
278
},
279
{
280
scale: current.progress.interpolate({
281
inputRange: [-1, -0.2, 0, 0.2, 1],
282
outputRange: [0.8, 0.95, 1, 0.95, 0.8],
283
}),
284
},
285
],
286
},
287
});
288
289
<Tab.Screen
290
name="CustomAnimated"
291
component={CustomScreen}
292
options={{
293
sceneStyleInterpolator: scaleRotateInterpolator,
294
transitionSpec: {
295
animation: 'spring',
296
config: {
297
stiffness: 100,
298
damping: 15,
299
},
300
},
301
}}
302
/>
303
```
304
305
### Animation Names
306
307
Built-in animation names for common transition effects.
308
309
```typescript { .api }
310
/**
311
* Built-in animation names for tab transitions
312
*/
313
type TabAnimationName = 'none' | 'fade' | 'shift';
314
```
315
316
**Usage Examples:**
317
318
```typescript
319
<Tab.Navigator
320
screenOptions={{
321
animation: 'fade', // Apply fade animation to all screens
322
}}
323
>
324
<Tab.Screen name="Home" component={HomeScreen} />
325
<Tab.Screen
326
name="Special"
327
component={SpecialScreen}
328
options={{
329
animation: 'shift', // Override with shift animation
330
}}
331
/>
332
<Tab.Screen
333
name="Static"
334
component={StaticScreen}
335
options={{
336
animation: 'none', // No animation for this screen
337
}}
338
/>
339
</Tab.Navigator>
340
```
341
342
### Keyboard Animation Configuration
343
344
Configure tab bar visibility animations when the keyboard appears or disappears.
345
346
```typescript { .api }
347
/**
348
* Animation configuration for tab bar visibility changes
349
*/
350
interface TabBarVisibilityAnimationConfig {
351
show?: TabBarVisibilityAnimation;
352
hide?: TabBarVisibilityAnimation;
353
}
354
355
type TabBarVisibilityAnimation =
356
| TimingKeyboardAnimationConfig
357
| SpringKeyboardAnimationConfig;
358
359
interface TimingKeyboardAnimationConfig {
360
animation: 'timing';
361
config?: Omit<
362
Partial<Animated.TimingAnimationConfig>,
363
'toValue' | 'useNativeDriver'
364
>;
365
}
366
367
interface SpringKeyboardAnimationConfig {
368
animation: 'spring';
369
config?: Omit<
370
Partial<Animated.SpringAnimationConfig>,
371
'toValue' | 'useNativeDriver'
372
>;
373
}
374
```
375
376
**Usage Examples:**
377
378
```typescript
379
<Tab.Navigator
380
screenOptions={{
381
tabBarHideOnKeyboard: true,
382
tabBarVisibilityAnimationConfig: {
383
show: {
384
animation: 'spring',
385
config: {
386
damping: 15,
387
stiffness: 150,
388
mass: 1,
389
},
390
},
391
hide: {
392
animation: 'timing',
393
config: {
394
duration: 200,
395
easing: Easing.out(Easing.cubic),
396
},
397
},
398
},
399
}}
400
>
401
{/* screens */}
402
</Tab.Navigator>
403
```
404
405
### Performance Optimization
406
407
Optimize animations for better performance and smoother transitions.
408
409
```typescript { .api }
410
/**
411
* Animation configuration options for performance optimization
412
*/
413
interface AnimationPerformanceOptions {
414
/**
415
* Whether to use native driver for animations (automatically determined by platform)
416
*/
417
useNativeDriver?: boolean;
418
419
/**
420
* Whether to enable GPU acceleration for transforms
421
*/
422
enableGPUAcceleration?: boolean;
423
}
424
```
425
426
**Usage Examples:**
427
428
```typescript
429
// Optimized custom interpolator
430
const optimizedInterpolator = ({ current }) => ({
431
sceneStyle: {
432
// Use transforms instead of changing layout properties
433
transform: [
434
{
435
translateX: current.progress.interpolate({
436
inputRange: [-1, 0, 1],
437
outputRange: [-50, 0, 50],
438
}),
439
},
440
],
441
// Avoid changing opacity if not necessary for better performance
442
opacity: current.progress.interpolate({
443
inputRange: [-1, -0.01, 0, 0.01, 1],
444
outputRange: [0, 0, 1, 0, 0],
445
}),
446
},
447
});
448
449
// Performance-optimized timing config
450
const performantTransitionSpec = {
451
animation: 'timing',
452
config: {
453
duration: 150,
454
easing: Easing.out(Easing.cubic),
455
// These properties are automatically handled by React Navigation
456
useNativeDriver: true,
457
},
458
};
459
```
460
461
### Animation State Management
462
463
Monitor and control animation states programmatically.
464
465
```typescript { .api }
466
/**
467
* Animation event handlers
468
*/
469
interface AnimationEventHandlers {
470
/**
471
* Called when transition animation starts
472
*/
473
onTransitionStart?: () => void;
474
475
/**
476
* Called when transition animation ends
477
*/
478
onTransitionEnd?: () => void;
479
}
480
```
481
482
**Usage Examples:**
483
484
```typescript
485
function AnimatedScreen({ navigation }) {
486
React.useEffect(() => {
487
const startListener = navigation.addListener('transitionStart', () => {
488
console.log('Animation started');
489
// Pause expensive operations during animation
490
pauseBackgroundTasks();
491
});
492
493
const endListener = navigation.addListener('transitionEnd', () => {
494
console.log('Animation ended');
495
// Resume operations after animation
496
resumeBackgroundTasks();
497
});
498
499
return () => {
500
startListener();
501
endListener();
502
};
503
}, [navigation]);
504
505
return <View>{/* screen content */}</View>;
506
}
507
```
508
509
## Combining Animation Features
510
511
Complete example combining multiple animation features for a rich user experience.
512
513
```typescript
514
const advancedAnimationConfig = {
515
animation: 'fade',
516
sceneStyleInterpolator: ({ current }) => ({
517
sceneStyle: {
518
opacity: current.progress.interpolate({
519
inputRange: [-1, 0, 1],
520
outputRange: [0, 1, 0],
521
}),
522
transform: [
523
{
524
scale: current.progress.interpolate({
525
inputRange: [-1, -0.5, 0, 0.5, 1],
526
outputRange: [0.9, 0.95, 1, 0.95, 0.9],
527
}),
528
},
529
{
530
translateY: current.progress.interpolate({
531
inputRange: [-1, 0, 1],
532
outputRange: [50, 0, -50],
533
}),
534
},
535
],
536
},
537
}),
538
transitionSpec: {
539
animation: 'spring',
540
config: {
541
stiffness: 300,
542
damping: 25,
543
mass: 1,
544
},
545
},
546
};
547
548
<Tab.Screen
549
name="AdvancedAnimated"
550
component={AdvancedScreen}
551
options={advancedAnimationConfig}
552
/>
553
```