0
# Imperative Animation
1
2
Method-based animation control for complex programmatic animations and transitions. Execute animations directly via component methods for fine-grained control over timing and sequencing.
3
4
## Capabilities
5
6
### Animate Method
7
8
Execute any animation imperatively with optional timing parameters.
9
10
```javascript { .api }
11
/**
12
* Execute an animation imperatively
13
* @param animation - Animation name or custom definition
14
* @param duration - Optional duration override in milliseconds
15
* @param iterationDelay - Optional delay between iterations in milliseconds
16
* @returns Promise that resolves when animation completes or is cancelled
17
*/
18
animate(animation: Animation | CustomAnimation, duration?: number, iterationDelay?: number): Promise<{ finished: boolean }>;
19
```
20
21
**Usage Examples:**
22
23
```javascript
24
class AnimatedComponent extends Component {
25
handleViewRef = ref => this.view = ref;
26
27
startAnimation = async () => {
28
try {
29
// Execute animation and wait for completion
30
const endState = await this.view.animate('bounceIn', 800);
31
32
if (endState.finished) {
33
console.log('Animation completed successfully');
34
this.startNextAnimation();
35
} else {
36
console.log('Animation was cancelled');
37
}
38
} catch (error) {
39
console.log('Animation error:', error);
40
}
41
};
42
43
customAnimation = () => {
44
// Use custom animation object
45
const customBounce = {
46
0: { scale: 1, translateY: 0 },
47
0.5: { scale: 1.2, translateY: -50 },
48
1: { scale: 1, translateY: 0 }
49
};
50
51
this.view.animate(customBounce, 1000);
52
};
53
54
render() {
55
return (
56
<Animatable.View ref={this.handleViewRef}>
57
<TouchableOpacity onPress={this.startAnimation}>
58
<Text>Tap to animate</Text>
59
</TouchableOpacity>
60
</Animatable.View>
61
);
62
}
63
}
64
```
65
66
### Built-in Animation Methods
67
68
All built-in animations are available as direct methods on animatable components.
69
70
```javascript { .api }
71
interface AnimationMethods {
72
// Attention seekers
73
bounce(duration?: number): Promise<{ finished: boolean }>;
74
flash(duration?: number): Promise<{ finished: boolean }>;
75
jello(duration?: number): Promise<{ finished: boolean }>;
76
pulse(duration?: number): Promise<{ finished: boolean }>;
77
rotate(duration?: number): Promise<{ finished: boolean }>;
78
rubberBand(duration?: number): Promise<{ finished: boolean }>;
79
shake(duration?: number): Promise<{ finished: boolean }>;
80
swing(duration?: number): Promise<{ finished: boolean }>;
81
tada(duration?: number): Promise<{ finished: boolean }>;
82
wobble(duration?: number): Promise<{ finished: boolean }>;
83
84
// Bouncing entrances
85
bounceIn(duration?: number): Promise<{ finished: boolean }>;
86
bounceInDown(duration?: number): Promise<{ finished: boolean }>;
87
bounceInUp(duration?: number): Promise<{ finished: boolean }>;
88
bounceInLeft(duration?: number): Promise<{ finished: boolean }>;
89
bounceInRight(duration?: number): Promise<{ finished: boolean }>;
90
91
// ... all other built-in animations
92
}
93
```
94
95
**Usage Examples:**
96
97
```javascript
98
class InteractiveComponent extends Component {
99
handleViewRef = ref => this.view = ref;
100
101
// Different methods for different interactions
102
onPress = () => this.view.pulse(200);
103
onLongPress = () => this.view.shake(400);
104
onSuccess = () => this.view.bounce(600);
105
onError = () => this.view.flash(300);
106
107
sequentialAnimations = async () => {
108
// Chain animations sequentially
109
await this.view.slideInLeft(500);
110
await this.view.pulse(300);
111
await this.view.slideOutRight(500);
112
};
113
114
render() {
115
return (
116
<TouchableOpacity
117
onPress={this.onPress}
118
onLongPress={this.onLongPress}
119
>
120
<Animatable.View ref={this.handleViewRef}>
121
<Text>Interactive Element</Text>
122
</Animatable.View>
123
</TouchableOpacity>
124
);
125
}
126
}
127
```
128
129
### Stop Animation
130
131
Stop any currently running animation immediately.
132
133
```javascript { .api }
134
/**
135
* Stop any currently running animation
136
*/
137
stopAnimation(): void;
138
```
139
140
**Usage Examples:**
141
142
```javascript
143
class ControlledAnimation extends Component {
144
handleViewRef = ref => this.view = ref;
145
146
startInfiniteAnimation = () => {
147
// Start infinite animation
148
this.view.animate('pulse', 1000);
149
150
// Set up auto-stop after 5 seconds
151
this.stopTimer = setTimeout(() => {
152
this.view.stopAnimation();
153
}, 5000);
154
};
155
156
stopAnimation = () => {
157
// Stop animation immediately
158
this.view.stopAnimation();
159
if (this.stopTimer) {
160
clearTimeout(this.stopTimer);
161
}
162
};
163
164
componentWillUnmount() {
165
// Always stop animations when component unmounts
166
this.view?.stopAnimation();
167
if (this.stopTimer) {
168
clearTimeout(this.stopTimer);
169
}
170
};
171
172
render() {
173
return (
174
<View>
175
<Animatable.View ref={this.handleViewRef}>
176
<Text>Controlled Animation</Text>
177
</Animatable.View>
178
<Button title="Start" onPress={this.startInfiniteAnimation} />
179
<Button title="Stop" onPress={this.stopAnimation} />
180
</View>
181
);
182
}
183
}
184
```
185
186
### Transition Method
187
188
Transition between specific style values with full control over from and to states.
189
190
```javascript { .api }
191
/**
192
* Transition between specific style values
193
* @param fromValues - Starting style values
194
* @param toValues - Ending style values
195
* @param duration - Optional transition duration in milliseconds
196
* @param easing - Optional easing function
197
*/
198
transition(fromValues: object, toValues: object, duration?: number, easing?: Easing): void;
199
```
200
201
**Usage Examples:**
202
203
```javascript
204
class TransitionComponent extends Component {
205
handleViewRef = ref => this.view = ref;
206
207
colorTransition = () => {
208
this.view.transition(
209
{ backgroundColor: 'red', scale: 1 }, // From
210
{ backgroundColor: 'blue', scale: 1.2 }, // To
211
800, // Duration
212
'ease-in-out' // Easing
213
);
214
};
215
216
layoutTransition = () => {
217
this.view.transition(
218
{
219
width: 100,
220
height: 100,
221
borderRadius: 0
222
},
223
{
224
width: 200,
225
height: 50,
226
borderRadius: 25
227
},
228
1000,
229
'ease-out-back'
230
);
231
};
232
233
multiPropertyTransition = () => {
234
this.view.transition(
235
{
236
opacity: 1,
237
translateX: 0,
238
translateY: 0,
239
rotate: '0deg',
240
scale: 1
241
},
242
{
243
opacity: 0.7,
244
translateX: 100,
245
translateY: 50,
246
rotate: '45deg',
247
scale: 1.5
248
},
249
1200
250
);
251
};
252
253
render() {
254
return (
255
<View>
256
<Animatable.View ref={this.handleViewRef} style={styles.box}>
257
<Text>Transition Box</Text>
258
</Animatable.View>
259
<Button title="Color Transition" onPress={this.colorTransition} />
260
<Button title="Layout Transition" onPress={this.layoutTransition} />
261
<Button title="Multi-Property" onPress={this.multiPropertyTransition} />
262
</View>
263
);
264
}
265
}
266
```
267
268
### Transition To Method
269
270
Transition to specific style values from the current state automatically.
271
272
```javascript { .api }
273
/**
274
* Transition to specific style values from current state
275
* @param toValues - Target style values
276
* @param duration - Optional transition duration in milliseconds
277
* @param easing - Optional easing function
278
*/
279
transitionTo(toValues: object, duration?: number, easing?: Easing): void;
280
```
281
282
**Usage Examples:**
283
284
```javascript
285
class SmartTransition extends Component {
286
handleViewRef = ref => this.view = ref;
287
288
state = {
289
expanded: false,
290
highlighted: false
291
};
292
293
toggleExpanded = () => {
294
const expanded = !this.state.expanded;
295
this.setState({ expanded });
296
297
// Transition to new size
298
this.view.transitionTo({
299
width: expanded ? 300 : 150,
300
height: expanded ? 200 : 100,
301
scale: expanded ? 1.1 : 1
302
}, 400, 'ease-out');
303
};
304
305
toggleHighlight = () => {
306
const highlighted = !this.state.highlighted;
307
this.setState({ highlighted });
308
309
// Transition to new appearance
310
this.view.transitionTo({
311
backgroundColor: highlighted ? 'yellow' : 'white',
312
opacity: highlighted ? 1 : 0.8,
313
borderWidth: highlighted ? 3 : 1
314
}, 200);
315
};
316
317
animateToRandomPosition = () => {
318
// Transition to random position
319
this.view.transitionTo({
320
translateX: Math.random() * 200 - 100,
321
translateY: Math.random() * 200 - 100,
322
rotate: `${Math.random() * 360}deg`
323
}, 800, 'ease-in-out');
324
};
325
326
resetPosition = () => {
327
// Return to original position
328
this.view.transitionTo({
329
translateX: 0,
330
translateY: 0,
331
rotate: '0deg',
332
scale: 1,
333
opacity: 1
334
}, 600, 'ease-out-back');
335
};
336
337
render() {
338
return (
339
<View>
340
<Animatable.View
341
ref={this.handleViewRef}
342
style={[
343
styles.box,
344
{
345
width: 150,
346
height: 100,
347
backgroundColor: 'white',
348
borderWidth: 1,
349
borderColor: 'gray'
350
}
351
]}
352
>
353
<Text>Smart Transition</Text>
354
</Animatable.View>
355
356
<Button title="Toggle Size" onPress={this.toggleExpanded} />
357
<Button title="Toggle Highlight" onPress={this.toggleHighlight} />
358
<Button title="Random Position" onPress={this.animateToRandomPosition} />
359
<Button title="Reset" onPress={this.resetPosition} />
360
</View>
361
);
362
}
363
}
364
```
365
366
## Advanced Imperative Patterns
367
368
### Animation Sequences
369
370
Create complex animation sequences with promises:
371
372
```javascript
373
class SequenceAnimation extends Component {
374
handleViewRef = ref => this.view = ref;
375
376
complexSequence = async () => {
377
try {
378
// Step 1: Slide in
379
await this.view.slideInLeft(500);
380
381
// Step 2: Pulse 3 times
382
for (let i = 0; i < 3; i++) {
383
await this.view.pulse(300);
384
if (i < 2) await this.wait(200); // Pause between pulses
385
}
386
387
// Step 3: Scale up and change color
388
this.view.transitionTo({
389
scale: 1.5,
390
backgroundColor: 'gold'
391
}, 400);
392
393
await this.wait(400);
394
395
// Step 4: Final bounce and slide out
396
await this.view.bounce(600);
397
await this.view.slideOutRight(500);
398
399
} catch (error) {
400
console.log('Sequence interrupted:', error);
401
}
402
};
403
404
wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
405
406
render() {
407
return (
408
<Animatable.View ref={this.handleViewRef}>
409
<TouchableOpacity onPress={this.complexSequence}>
410
<Text>Start Complex Sequence</Text>
411
</TouchableOpacity>
412
</Animatable.View>
413
);
414
}
415
}
416
```
417
418
### Conditional Animation Chaining
419
420
```javascript
421
class ConditionalAnimation extends Component {
422
handleViewRef = ref => this.view = ref;
423
424
smartAnimation = async () => {
425
const startTime = Date.now();
426
427
// Start with attention seeker
428
const result = await this.view.shake(400);
429
430
if (result.finished) {
431
// If user hasn't interacted, continue with more animations
432
if (Date.now() - startTime > 2000) {
433
await this.view.bounce(600);
434
await this.view.pulse(300);
435
}
436
} else {
437
// Animation was cancelled, do cleanup
438
this.resetState();
439
}
440
};
441
442
interruptibleSequence = async () => {
443
this.animationCancelled = false;
444
445
const animations = ['fadeIn', 'pulse', 'shake', 'bounce'];
446
447
for (const animation of animations) {
448
if (this.animationCancelled) break;
449
450
const result = await this.view.animate(animation, 600);
451
if (!result.finished) break;
452
453
await this.wait(300);
454
}
455
};
456
457
cancelSequence = () => {
458
this.animationCancelled = true;
459
this.view.stopAnimation();
460
};
461
}
462
```
463
464
### Performance-Optimized Animations
465
466
```javascript
467
class OptimizedAnimations extends Component {
468
handleViewRef = ref => this.view = ref;
469
470
// Use native driver for transform animations
471
nativeTransforms = () => {
472
// These work with native driver
473
this.view.transitionTo({
474
translateX: 100,
475
translateY: 50,
476
scale: 1.2,
477
rotate: '45deg',
478
opacity: 0.8
479
}, 400);
480
};
481
482
// Use JS driver for layout/color animations
483
jsAnimations = () => {
484
// These require JS driver
485
this.view.transitionTo({
486
backgroundColor: 'red',
487
width: 200,
488
height: 150,
489
borderRadius: 20
490
}, 400);
491
};
492
493
// Batch multiple transform animations
494
batchedTransforms = () => {
495
// More efficient than multiple separate calls
496
this.view.transitionTo({
497
translateX: 50,
498
translateY: -30,
499
scale: 1.1,
500
rotate: '15deg'
501
}, 300);
502
};
503
}
504
```
505
506
### Error Handling and Cleanup
507
508
```javascript
509
class RobustAnimations extends Component {
510
animationPromises = [];
511
512
handleViewRef = ref => this.view = ref;
513
514
safeAnimation = async () => {
515
try {
516
const animationPromise = this.view.bounce(800);
517
this.animationPromises.push(animationPromise);
518
519
const result = await animationPromise;
520
521
// Remove completed promise
522
this.animationPromises = this.animationPromises.filter(p => p !== animationPromise);
523
524
if (result.finished) {
525
this.onAnimationComplete();
526
} else {
527
this.onAnimationCancelled();
528
}
529
530
} catch (error) {
531
console.error('Animation error:', error);
532
this.onAnimationError(error);
533
}
534
};
535
536
componentWillUnmount() {
537
// Stop all animations and clear promises
538
this.view?.stopAnimation();
539
this.animationPromises = [];
540
};
541
542
onAnimationComplete = () => {
543
console.log('Animation completed successfully');
544
};
545
546
onAnimationCancelled = () => {
547
console.log('Animation was cancelled');
548
};
549
550
onAnimationError = (error) => {
551
console.error('Animation failed:', error);
552
};
553
}
554
```