or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation-registry.mdbuiltin-animations.mdcomponent-creation.mdcustom-animations.mddeclarative-animation.mdimperative-animation.mdindex.mdprebuilt-components.md

imperative-animation.mddocs/

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

```