or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

accessibility.mdanimation.mdcore-utilities.mdform-controls.mdhooks.mdindex.mdinteractive-components.mdlayout-components.mdlist-components.mdmedia-components.mdplatform-apis.mdstylesheet.mdsystem-integration.mdtext-input.md

animation.mddocs/

0

# Animation

1

2

React Native's Animated API adapted for web with full support for declarative animations, timing functions, spring physics, and composition utilities for building complex animated UIs.

3

4

## Animated

5

6

The main Animated API providing declarative animation capabilities with configurable transforms, value management, and timing control for building fluid, maintainable animations.

7

8

```javascript { .api }

9

const Animated: {

10

// Value Classes

11

Value: typeof AnimatedValue;

12

ValueXY: typeof AnimatedValueXY;

13

Color: typeof AnimatedColor;

14

15

// Animation Functions

16

timing: (value: AnimatedValue | AnimatedValueXY | AnimatedColor, config: TimingAnimationConfig) => CompositeAnimation;

17

spring: (value: AnimatedValue | AnimatedValueXY | AnimatedColor, config: SpringAnimationConfig) => CompositeAnimation;

18

decay: (value: AnimatedValue | AnimatedValueXY | AnimatedColor, config: DecayAnimationConfig) => CompositeAnimation;

19

20

// Composition Functions

21

parallel: (animations: CompositeAnimation[], config?: ParallelConfig) => CompositeAnimation;

22

sequence: (animations: CompositeAnimation[]) => CompositeAnimation;

23

stagger: (time: number, animations: CompositeAnimation[]) => CompositeAnimation;

24

delay: (time: number) => CompositeAnimation;

25

loop: (animation: CompositeAnimation, config?: LoopAnimationConfig) => CompositeAnimation;

26

27

// Math Operations

28

add: (a: AnimatedNode | number, b: AnimatedNode | number) => AnimatedAddition;

29

subtract: (a: AnimatedNode | number, b: AnimatedNode | number) => AnimatedSubtraction;

30

multiply: (a: AnimatedNode | number, b: AnimatedNode | number) => AnimatedMultiplication;

31

divide: (a: AnimatedNode | number, b: AnimatedNode | number) => AnimatedDivision;

32

modulo: (a: AnimatedNode, modulus: number) => AnimatedModulo;

33

diffClamp: (a: AnimatedNode, min: number, max: number) => AnimatedDiffClamp;

34

35

// Event Handling

36

event: (argMapping: Mapping[], config: EventConfig) => Function;

37

forkEvent: (event: AnimatedEvent | Function, listener: Function) => AnimatedEvent | Function;

38

unforkEvent: (event: AnimatedEvent | Function, listener: Function) => void;

39

40

// Components

41

View: typeof AnimatedView;

42

Text: typeof AnimatedText;

43

Image: typeof AnimatedImage;

44

ScrollView: typeof AnimatedScrollView;

45

FlatList: typeof AnimatedFlatList;

46

SectionList: typeof AnimatedSectionList;

47

48

// Utilities

49

createAnimatedComponent: <T>(Component: T) => T;

50

attachNativeEvent: (viewRef: any, eventName: string, argMapping: Mapping[]) => void;

51

52

// Type Exports

53

Node: typeof AnimatedNode;

54

Interpolation: typeof AnimatedInterpolation;

55

Event: typeof AnimatedEvent;

56

};

57

```

58

59

## Easing

60

61

Comprehensive easing functions library providing mathematically accurate timing curves for animations. Includes predefined animations, standard mathematical functions, and helper functions for creating custom easing behaviors.

62

63

```javascript { .api }

64

const Easing: {

65

// Predefined animations

66

ease: (t: number) => number;

67

bounce: (t: number) => number;

68

back: (s?: number) => (t: number) => number;

69

elastic: (bounciness?: number) => (t: number) => number;

70

71

// Standard functions

72

linear: (t: number) => number;

73

quad: (t: number) => number;

74

cubic: (t: number) => number;

75

poly: (n: number) => (t: number) => number;

76

77

// Mathematical functions

78

sin: (t: number) => number;

79

circle: (t: number) => number;

80

exp: (t: number) => number;

81

bezier: (x1: number, y1: number, x2: number, y2: number) => (t: number) => number;

82

83

// Stepping functions

84

step0: (n: number) => number;

85

step1: (n: number) => number;

86

87

// Direction helpers

88

in: (easing: (t: number) => number) => (t: number) => number;

89

out: (easing: (t: number) => number) => (t: number) => number;

90

inOut: (easing: (t: number) => number) => (t: number) => number;

91

};

92

```

93

94

**Web Implementation:**

95

All easing functions are implemented using pure JavaScript mathematical functions, providing consistent behavior across all platforms and browsers.

96

97

### Predefined Animations

98

99

```javascript { .api }

100

// Simple inertial animation, similar to CSS ease

101

Easing.ease(t: number): number

102

103

// Bouncing animation with multiple bounces

104

Easing.bounce(t: number): number

105

106

// Animation that goes slightly back before moving forward

107

Easing.back(s?: number): (t: number) => number

108

109

// Spring-like elastic animation with configurable bounciness

110

Easing.elastic(bounciness?: number): (t: number) => number

111

```

112

113

### Standard Mathematical Functions

114

115

```javascript { .api }

116

// Linear timing (no easing)

117

Easing.linear(t: number): number

118

119

// Quadratic timing (t²)

120

Easing.quad(t: number): number

121

122

// Cubic timing (t³)

123

Easing.cubic(t: number): number

124

125

// Power timing (t^n)

126

Easing.poly(n: number): (t: number) => number

127

```

128

129

### Advanced Mathematical Functions

130

131

```javascript { .api }

132

// Sinusoidal timing

133

Easing.sin(t: number): number

134

135

// Circular timing

136

Easing.circle(t: number): number

137

138

// Exponential timing

139

Easing.exp(t: number): number

140

141

// Cubic Bézier curve (like CSS transition-timing-function)

142

Easing.bezier(x1: number, y1: number, x2: number, y2: number): (t: number) => number

143

```

144

145

### Direction Helpers

146

147

```javascript { .api }

148

// Run easing function forwards (identity function)

149

Easing.in(easing: (t: number) => number): (t: number) => number

150

151

// Run easing function backwards

152

Easing.out(easing: (t: number) => number): (t: number) => number

153

154

// Make easing function symmetrical (ease in for first half, ease out for second half)

155

Easing.inOut(easing: (t: number) => number): (t: number) => number

156

```

157

158

**Usage:**

159

```javascript

160

import { Animated, Easing } from "react-native-web";

161

162

function EasingExample() {

163

const fadeAnim = new Animated.Value(0);

164

const slideAnim = new Animated.Value(-100);

165

166

const startAnimation = () => {

167

Animated.parallel([

168

// Fade in with custom cubic bezier

169

Animated.timing(fadeAnim, {

170

toValue: 1,

171

duration: 500,

172

easing: Easing.bezier(0.25, 0.1, 0.25, 1), // CSS ease

173

useNativeDriver: false,

174

}),

175

176

// Slide in with elastic bounce

177

Animated.timing(slideAnim, {

178

toValue: 0,

179

duration: 800,

180

easing: Easing.elastic(1.5),

181

useNativeDriver: false,

182

}),

183

184

// Complex custom easing using helpers

185

Animated.timing(rotateAnim, {

186

toValue: 360,

187

duration: 1000,

188

easing: Easing.inOut(Easing.back(2)),

189

useNativeDriver: false,

190

}),

191

]).start();

192

};

193

194

return (

195

<Animated.View

196

style={{

197

opacity: fadeAnim,

198

transform: [

199

{ translateX: slideAnim },

200

{ rotate: rotateAnim.interpolate({

201

inputRange: [0, 360],

202

outputRange: ['0deg', '360deg']

203

})}

204

],

205

}}

206

>

207

<Text>Animated with custom easing!</Text>

208

</Animated.View>

209

);

210

}

211

212

// Compare different easing functions

213

const easingComparison = {

214

linear: Easing.linear,

215

ease: Easing.ease,

216

easeOut: Easing.out(Easing.quad),

217

easeInOut: Easing.inOut(Easing.cubic),

218

bounce: Easing.bounce,

219

elastic: Easing.elastic(1),

220

back: Easing.back(),

221

};

222

```

223

224

## Value Classes

225

226

### Animated.Value

227

Standard animated value class for driving single-property animations.

228

229

```javascript { .api }

230

class AnimatedValue extends AnimatedNode {

231

constructor(value: number, config?: AnimatedValueConfig): AnimatedValue;

232

setValue(value: number): void;

233

setOffset(offset: number): void;

234

flattenOffset(): void;

235

extractOffset(): void;

236

addListener(callback: ValueListenerCallback): string;

237

removeListener(id: string): void;

238

removeAllListeners(): void;

239

stopAnimation(callback?: (value: number) => void): void;

240

resetAnimation(callback?: (value: number) => void): void;

241

interpolate(config: InterpolationConfigType): AnimatedInterpolation;

242

animate(animation: Animation, callback?: EndCallback): void;

243

stopTracking(): void;

244

track(tracking: AnimatedTracking): void;

245

}

246

```

247

248

**Usage:**

249

```javascript

250

import { Animated, View } from "react-native-web";

251

252

function FadeInView({ children }) {

253

const fadeAnim = new Animated.Value(0);

254

255

React.useEffect(() => {

256

Animated.timing(fadeAnim, {

257

toValue: 1,

258

duration: 1000,

259

useNativeDriver: false

260

}).start();

261

}, [fadeAnim]);

262

263

return (

264

<Animated.View style={{ opacity: fadeAnim }}>

265

{children}

266

</Animated.View>

267

);

268

}

269

270

// Advanced value manipulation

271

function ComplexAnimation() {

272

const translateX = new Animated.Value(0);

273

const scale = new Animated.Value(1);

274

275

// Set initial value

276

translateX.setValue(50);

277

278

// Add offset (current value becomes offset + value)

279

translateX.setOffset(100);

280

translateX.setValue(0); // Now animates from 100

281

282

// Listen to value changes

283

const listenerId = translateX.addListener(({ value }) => {

284

console.log(`TranslateX: ${value}`);

285

});

286

287

// Interpolate for different properties

288

const backgroundColor = translateX.interpolate({

289

inputRange: [0, 100],

290

outputRange: ['rgba(255,0,0,0.5)', 'rgba(0,0,255,0.5)'],

291

extrapolate: 'clamp'

292

});

293

294

return (

295

<Animated.View

296

style={{

297

transform: [

298

{ translateX },

299

{ scale }

300

],

301

backgroundColor

302

}}

303

/>

304

);

305

}

306

```

307

308

### Animated.ValueXY

309

2D animated value class for driving pan gestures and multi-dimensional animations.

310

311

```javascript { .api }

312

class AnimatedValueXY extends AnimatedNode {

313

x: AnimatedValue;

314

y: AnimatedValue;

315

316

constructor(valueIn?: { x: number | AnimatedValue; y: number | AnimatedValue }, config?: AnimatedValueConfig): AnimatedValueXY;

317

setValue(value: { x: number; y: number }): void;

318

setOffset(offset: { x: number; y: number }): void;

319

flattenOffset(): void;

320

extractOffset(): void;

321

stopAnimation(callback?: (value: { x: number; y: number }) => void): void;

322

resetAnimation(callback?: (value: { x: number; y: number }) => void): void;

323

addListener(callback: ValueXYListenerCallback): string;

324

removeListener(id: string): void;

325

removeAllListeners(): void;

326

getLayout(): { left: AnimatedValue; top: AnimatedValue };

327

getTranslateTransform(): [{ translateX: AnimatedValue }, { translateY: AnimatedValue }];

328

}

329

```

330

331

**Usage:**

332

```javascript

333

// Pan gesture with ValueXY

334

function DraggableBox() {

335

const pan = new Animated.ValueXY();

336

const panGesture = PanGestureHandler.create({

337

onGestureEvent: Animated.event(

338

[{ nativeEvent: { translationX: pan.x, translationY: pan.y } }],

339

{ useNativeDriver: false }

340

),

341

onHandlerStateChange: (event) => {

342

if (event.nativeEvent.oldState === State.ACTIVE) {

343

// Snap back to center

344

Animated.spring(pan, {

345

toValue: { x: 0, y: 0 },

346

useNativeDriver: false

347

}).start();

348

}

349

}

350

});

351

352

return (

353

<PanGestureHandler {...panGesture}>

354

<Animated.View

355

style={{

356

transform: pan.getTranslateTransform(),

357

width: 100,

358

height: 100,

359

backgroundColor: 'blue'

360

}}

361

/>

362

</PanGestureHandler>

363

);

364

}

365

366

// Complex 2D animation

367

function Orbit() {

368

const position = new Animated.ValueXY({ x: 0, y: 0 });

369

const angle = new Animated.Value(0);

370

371

React.useEffect(() => {

372

const animateOrbit = () => {

373

const radius = 50;

374

angle.setValue(0);

375

376

Animated.timing(angle, {

377

toValue: 2 * Math.PI,

378

duration: 2000,

379

useNativeDriver: false

380

}).start(() => animateOrbit());

381

};

382

383

animateOrbit();

384

}, []);

385

386

// Convert polar to cartesian coordinates

387

const x = Animated.multiply(

388

Animated.add(Math.cos, angle),

389

radius

390

);

391

const y = Animated.multiply(

392

Animated.add(Math.sin, angle),

393

radius

394

);

395

396

return (

397

<Animated.View

398

style={{

399

position: 'absolute',

400

left: x,

401

top: y,

402

width: 20,

403

height: 20,

404

backgroundColor: 'red',

405

borderRadius: 10

406

}}

407

/>

408

);

409

}

410

```

411

412

### Animated.Color

413

Animated value class for color animations with RGBA channel support.

414

415

```javascript { .api }

416

class AnimatedColor extends AnimatedNode {

417

r: AnimatedValue;

418

g: AnimatedValue;

419

b: AnimatedValue;

420

a: AnimatedValue;

421

422

constructor(valueIn?: string | { r: number; g: number; b: number; a: number }): AnimatedColor;

423

setValue(value: string): void;

424

}

425

```

426

427

## Animation Functions

428

429

### timing()

430

Animates a value along a timed easing curve with configurable duration and easing function.

431

432

```javascript { .api }

433

Animated.timing(

434

value: AnimatedValue | AnimatedValueXY | AnimatedColor,

435

config: {

436

toValue: number | AnimatedValue | { x: number; y: number } | string;

437

duration?: number; // default: 500

438

easing?: EasingFunction; // default: Easing.inOut(Easing.ease)

439

delay?: number; // default: 0

440

useNativeDriver?: boolean; // default: false

441

onComplete?: (result: EndResult) => void;

442

}

443

): CompositeAnimation

444

```

445

446

**Usage:**

447

```javascript

448

// Basic timing animation

449

const opacity = new Animated.Value(0);

450

451

Animated.timing(opacity, {

452

toValue: 1,

453

duration: 300,

454

useNativeDriver: false

455

}).start();

456

457

// Custom easing functions

458

import { Easing } from "react-native-web";

459

460

Animated.timing(opacity, {

461

toValue: 1,

462

duration: 500,

463

easing: Easing.bezier(0.25, 0.1, 0.25, 1), // Custom bezier

464

useNativeDriver: false

465

}).start();

466

467

// Sequential timing with callbacks

468

function SequentialAnimation() {

469

const slideIn = new Animated.Value(-100);

470

const fadeIn = new Animated.Value(0);

471

472

const animateIn = () => {

473

Animated.timing(slideIn, {

474

toValue: 0,

475

duration: 300,

476

easing: Easing.out(Easing.back(1.7)),

477

useNativeDriver: false

478

}).start(({ finished }) => {

479

if (finished) {

480

Animated.timing(fadeIn, {

481

toValue: 1,

482

duration: 200,

483

useNativeDriver: false

484

}).start();

485

}

486

});

487

};

488

489

return (

490

<Animated.View

491

style={{

492

transform: [{ translateX: slideIn }],

493

opacity: fadeIn

494

}}

495

/>

496

);

497

}

498

```

499

500

### spring()

501

Animates a value according to an analytical spring model based on damped harmonic oscillation.

502

503

```javascript { .api }

504

Animated.spring(

505

value: AnimatedValue | AnimatedValueXY | AnimatedColor,

506

config: {

507

toValue: number | AnimatedValue | { x: number; y: number };

508

restDisplacementThreshold?: number; // default: 0.001

509

restSpeedThreshold?: number; // default: 0.001

510

velocity?: number | { x: number; y: number }; // default: 0

511

bounciness?: number; // default: 8

512

speed?: number; // default: 12

513

tension?: number; // alternative to bounciness/speed

514

friction?: number; // alternative to bounciness/speed

515

stiffness?: number; // alternative spring config

516

damping?: number; // alternative spring config

517

mass?: number; // default: 1

518

useNativeDriver?: boolean; // default: false

519

onComplete?: (result: EndResult) => void;

520

}

521

): CompositeAnimation

522

```

523

524

**Usage:**

525

```javascript

526

// Bouncy spring animation

527

const scale = new Animated.Value(0);

528

529

Animated.spring(scale, {

530

toValue: 1,

531

bounciness: 15,

532

speed: 8,

533

useNativeDriver: false

534

}).start();

535

536

// Physics-based spring

537

Animated.spring(scale, {

538

toValue: 1,

539

tension: 100,

540

friction: 8,

541

velocity: 0.5,

542

useNativeDriver: false

543

}).start();

544

545

// Interactive spring with gesture

546

function SpringButton({ onPress, children }) {

547

const scale = new Animated.Value(1);

548

const opacity = new Animated.Value(1);

549

550

const animateIn = () => {

551

Animated.parallel([

552

Animated.spring(scale, {

553

toValue: 0.95,

554

tension: 300,

555

friction: 10,

556

useNativeDriver: false

557

}),

558

Animated.timing(opacity, {

559

toValue: 0.8,

560

duration: 100,

561

useNativeDriver: false

562

})

563

]).start();

564

};

565

566

const animateOut = () => {

567

Animated.parallel([

568

Animated.spring(scale, {

569

toValue: 1,

570

tension: 300,

571

friction: 10,

572

useNativeDriver: false

573

}),

574

Animated.timing(opacity, {

575

toValue: 1,

576

duration: 100,

577

useNativeDriver: false

578

})

579

]).start();

580

};

581

582

return (

583

<TouchableWithoutFeedback

584

onPressIn={animateIn}

585

onPressOut={animateOut}

586

onPress={onPress}

587

>

588

<Animated.View

589

style={{

590

transform: [{ scale }],

591

opacity

592

}}

593

>

594

{children}

595

</Animated.View>

596

</TouchableWithoutFeedback>

597

);

598

}

599

```

600

601

### decay()

602

Animates a value from an initial velocity to zero based on a decay coefficient.

603

604

```javascript { .api }

605

Animated.decay(

606

value: AnimatedValue | AnimatedValueXY | AnimatedColor,

607

config: {

608

velocity: number | { x: number; y: number };

609

deceleration?: number; // default: 0.998

610

useNativeDriver?: boolean; // default: false

611

onComplete?: (result: EndResult) => void;

612

}

613

): CompositeAnimation

614

```

615

616

**Usage:**

617

```javascript

618

// Scroll momentum simulation

619

function MomentumScroll() {

620

const scrollY = new Animated.Value(0);

621

let lastScrollY = 0;

622

let velocity = 0;

623

624

const handleScroll = (event) => {

625

const currentScrollY = event.nativeEvent.contentOffset.y;

626

velocity = currentScrollY - lastScrollY;

627

lastScrollY = currentScrollY;

628

scrollY.setValue(currentScrollY);

629

};

630

631

const handleScrollEnd = () => {

632

if (Math.abs(velocity) > 0.1) {

633

Animated.decay(scrollY, {

634

velocity: velocity,

635

deceleration: 0.995,

636

useNativeDriver: false

637

}).start();

638

}

639

};

640

641

return (

642

<ScrollView

643

onScroll={handleScroll}

644

onScrollEndDrag={handleScrollEnd}

645

scrollEventThrottle={16}

646

>

647

{/* Content */}

648

</ScrollView>

649

);

650

}

651

```

652

653

## Composition Functions

654

655

### parallel()

656

Starts multiple animations simultaneously with optional coordination.

657

658

```javascript { .api }

659

Animated.parallel(

660

animations: CompositeAnimation[],

661

config?: {

662

stopTogether?: boolean; // default: true

663

}

664

): CompositeAnimation

665

```

666

667

### sequence()

668

Runs animations in sequential order, waiting for each to complete.

669

670

```javascript { .api }

671

Animated.sequence(animations: CompositeAnimation[]): CompositeAnimation

672

```

673

674

### stagger()

675

Starts animations in sequence with successive delays.

676

677

```javascript { .api }

678

Animated.stagger(

679

time: number,

680

animations: CompositeAnimation[]

681

): CompositeAnimation

682

```

683

684

### loop()

685

Continuously repeats an animation with configurable iterations.

686

687

```javascript { .api }

688

Animated.loop(

689

animation: CompositeAnimation,

690

config?: {

691

iterations?: number; // default: -1 (infinite)

692

resetBeforeIteration?: boolean; // default: true

693

}

694

): CompositeAnimation

695

```

696

697

**Usage:**

698

```javascript

699

// Complex choreographed animation

700

function StaggeredCards() {

701

const cards = [0, 1, 2, 3].map(() => ({

702

opacity: new Animated.Value(0),

703

translateY: new Animated.Value(50),

704

scale: new Animated.Value(0.8)

705

}));

706

707

const animateIn = () => {

708

const cardAnimations = cards.map(({ opacity, translateY, scale }) =>

709

Animated.parallel([

710

Animated.timing(opacity, {

711

toValue: 1,

712

duration: 300,

713

useNativeDriver: false

714

}),

715

Animated.spring(translateY, {

716

toValue: 0,

717

tension: 100,

718

friction: 8,

719

useNativeDriver: false

720

}),

721

Animated.spring(scale, {

722

toValue: 1,

723

tension: 120,

724

friction: 7,

725

useNativeDriver: false

726

})

727

])

728

);

729

730

// Stagger the card animations

731

Animated.stagger(100, cardAnimations).start();

732

};

733

734

const pulseAnimation = () => {

735

const pulseScale = new Animated.Value(1);

736

737

return Animated.loop(

738

Animated.sequence([

739

Animated.timing(pulseScale, {

740

toValue: 1.05,

741

duration: 800,

742

useNativeDriver: false

743

}),

744

Animated.timing(pulseScale, {

745

toValue: 1,

746

duration: 800,

747

useNativeDriver: false

748

})

749

]),

750

{ iterations: -1 }

751

);

752

};

753

754

return (

755

<View>

756

{cards.map(({ opacity, translateY, scale }, index) => (

757

<Animated.View

758

key={index}

759

style={{

760

opacity,

761

transform: [{ translateY }, { scale }]

762

}}

763

>

764

<Text>Card {index + 1}</Text>

765

</Animated.View>

766

))}

767

</View>

768

);

769

}

770

```

771

772

## Math Operations

773

774

Combine animated values using mathematical operations for complex derived animations.

775

776

```javascript { .api }

777

Animated.add(a: AnimatedNode | number, b: AnimatedNode | number): AnimatedAddition;

778

Animated.subtract(a: AnimatedNode | number, b: AnimatedNode | number): AnimatedSubtraction;

779

Animated.multiply(a: AnimatedNode | number, b: AnimatedNode | number): AnimatedMultiplication;

780

Animated.divide(a: AnimatedNode | number, b: AnimatedNode | number): AnimatedDivision;

781

Animated.modulo(a: AnimatedNode, modulus: number): AnimatedModulo;

782

Animated.diffClamp(a: AnimatedNode, min: number, max: number): AnimatedDiffClamp;

783

```

784

785

**Usage:**

786

```javascript

787

// Complex derived animations

788

function ParallaxHeader() {

789

const scrollY = new Animated.Value(0);

790

const headerHeight = 200;

791

792

// Clamp scroll for header transformation

793

const headerTranslateY = Animated.diffClamp(

794

scrollY,

795

0,

796

headerHeight

797

).interpolate({

798

inputRange: [0, headerHeight],

799

outputRange: [0, -headerHeight],

800

extrapolate: 'clamp'

801

});

802

803

// Combine multiple values

804

const headerScale = Animated.add(

805

1,

806

Animated.divide(scrollY, headerHeight * 2)

807

);

808

809

const headerOpacity = Animated.subtract(

810

1,

811

Animated.divide(scrollY, headerHeight)

812

);

813

814

return (

815

<View>

816

<Animated.View

817

style={{

818

height: headerHeight,

819

transform: [

820

{ translateY: headerTranslateY },

821

{ scale: headerScale }

822

],

823

opacity: headerOpacity

824

}}

825

>

826

<Text>Parallax Header</Text>

827

</Animated.View>

828

829

<ScrollView

830

onScroll={Animated.event(

831

[{ nativeEvent: { contentOffset: { y: scrollY } } }],

832

{ useNativeDriver: false }

833

)}

834

scrollEventThrottle={16}

835

>

836

{/* Content */}

837

</ScrollView>

838

</View>

839

);

840

}

841

842

// Mathematical operations for physics

843

function PhysicsAnimation() {

844

const x = new Animated.Value(0);

845

const velocity = new Animated.Value(0);

846

847

// Kinetic energy calculation: KE = 0.5 * m * v²

848

const kineticEnergy = Animated.multiply(

849

0.5,

850

Animated.multiply(velocity, velocity)

851

);

852

853

// Oscillation with sine wave

854

const time = new Animated.Value(0);

855

const amplitude = 50;

856

857

const sinePosition = Animated.multiply(

858

amplitude,

859

// Note: In real implementation, you'd need to use interpolation

860

// for trigonometric functions

861

time.interpolate({

862

inputRange: [0, Math.PI * 2],

863

outputRange: [0, 1, 0, -1, 0],

864

extrapolate: 'extend'

865

})

866

);

867

868

return (

869

<Animated.View

870

style={{

871

transform: [{ translateX: sinePosition }]

872

}}

873

/>

874

);

875

}

876

```

877

878

## Event Handling

879

880

### Animated.event()

881

Maps gesture or scroll events directly to animated values for high-performance interactions.

882

883

```javascript { .api }

884

Animated.event(

885

argMapping: Mapping[],

886

config?: {

887

useNativeDriver?: boolean; // default: false

888

listener?: Function;

889

}

890

): Function

891

```

892

893

**Usage:**

894

```javascript

895

// Scroll-driven animations

896

function ScrollParallax() {

897

const scrollY = new Animated.Value(0);

898

899

return (

900

<ScrollView

901

onScroll={Animated.event(

902

[{ nativeEvent: { contentOffset: { y: scrollY } } }],

903

{

904

useNativeDriver: false,

905

listener: (event) => {

906

// Additional scroll handling

907

console.log('Scroll position:', event.nativeEvent.contentOffset.y);

908

}

909

}

910

)}

911

scrollEventThrottle={16}

912

>

913

<Animated.View

914

style={{

915

transform: [{

916

translateY: scrollY.interpolate({

917

inputRange: [0, 100],

918

outputRange: [0, -50],

919

extrapolate: 'clamp'

920

})

921

}]

922

}}

923

>

924

{/* Parallax content */}

925

</Animated.View>

926

</ScrollView>

927

);

928

}

929

930

// Pan gesture handling

931

function PanAnimation() {

932

const pan = new Animated.ValueXY();

933

934

return (

935

<View>

936

<Animated.View

937

{...PanResponder.create({

938

onMoveShouldSetPanResponder: () => true,

939

onPanResponderGrant: () => {

940

pan.setOffset({

941

x: pan.x._value,

942

y: pan.y._value

943

});

944

},

945

onPanResponderMove: Animated.event(

946

[null, { dx: pan.x, dy: pan.y }],

947

{ useNativeDriver: false }

948

),

949

onPanResponderRelease: () => {

950

pan.flattenOffset();

951

Animated.spring(pan, {

952

toValue: { x: 0, y: 0 },

953

useNativeDriver: false

954

}).start();

955

}

956

}).panHandlers}

957

style={{

958

transform: pan.getTranslateTransform()

959

}}

960

>

961

{/* Draggable content */}

962

</Animated.View>

963

</View>

964

);

965

}

966

```

967

968

## Animated Components

969

970

Pre-built animated versions of common React Native components.

971

972

```javascript { .api }

973

const AnimatedComponents: {

974

View: AnimatedComponent<typeof View>;

975

Text: AnimatedComponent<typeof Text>;

976

Image: AnimatedComponent<typeof Image>;

977

ScrollView: AnimatedComponent<typeof ScrollView>;

978

FlatList: AnimatedComponent<typeof FlatList>;

979

SectionList: AnimatedComponent<typeof SectionList>;

980

};

981

```

982

983

### createAnimatedComponent()

984

Creates animated versions of custom components.

985

986

```javascript { .api }

987

Animated.createAnimatedComponent<T>(Component: T): T

988

```

989

990

**Usage:**

991

```javascript

992

// Create custom animated component

993

const AnimatedTouchableOpacity = Animated.createAnimatedComponent(TouchableOpacity);

994

995

function CustomAnimatedButton({ onPress, children }) {

996

const scale = new Animated.Value(1);

997

const opacity = new Animated.Value(1);

998

999

const handlePressIn = () => {

1000

Animated.parallel([

1001

Animated.spring(scale, {

1002

toValue: 0.95,

1003

useNativeDriver: false

1004

}),

1005

Animated.timing(opacity, {

1006

toValue: 0.7,

1007

duration: 100,

1008

useNativeDriver: false

1009

})

1010

]).start();

1011

};

1012

1013

const handlePressOut = () => {

1014

Animated.parallel([

1015

Animated.spring(scale, {

1016

toValue: 1,

1017

useNativeDriver: false

1018

}),

1019

Animated.timing(opacity, {

1020

toValue: 1,

1021

duration: 100,

1022

useNativeDriver: false

1023

})

1024

]).start();

1025

};

1026

1027

return (

1028

<AnimatedTouchableOpacity

1029

onPress={onPress}

1030

onPressIn={handlePressIn}

1031

onPressOut={handlePressOut}

1032

style={{

1033

transform: [{ scale }],

1034

opacity

1035

}}

1036

>

1037

{children}

1038

</AnimatedTouchableOpacity>

1039

);

1040

}

1041

1042

// Advanced custom component with multiple animated properties

1043

const AnimatedGradientView = Animated.createAnimatedComponent(

1044

({ colors, style, children, ...props }) => (

1045

<View

1046

{...props}

1047

style={[

1048

{

1049

background: `linear-gradient(45deg, ${colors.join(', ')})`

1050

},

1051

style

1052

]}

1053

>

1054

{children}

1055

</View>

1056

)

1057

);

1058

```

1059

1060

## Interpolation

1061

1062

Transform animated values into different ranges and types for versatile property mapping.

1063

1064

```javascript { .api }

1065

animatedValue.interpolate({

1066

inputRange: number[];

1067

outputRange: (number | string)[];

1068

easing?: EasingFunction;

1069

extrapolate?: 'extend' | 'identity' | 'clamp';

1070

extrapolateLeft?: 'extend' | 'identity' | 'clamp';

1071

extrapolateRight?: 'extend' | 'identity' | 'clamp';

1072

}): AnimatedInterpolation

1073

```

1074

1075

**Usage:**

1076

```javascript

1077

// Color interpolation

1078

function ColorTransition() {

1079

const animatedValue = new Animated.Value(0);

1080

1081

const backgroundColor = animatedValue.interpolate({

1082

inputRange: [0, 0.5, 1],

1083

outputRange: ['#ff0000', '#ffff00', '#00ff00']

1084

});

1085

1086

const textColor = animatedValue.interpolate({

1087

inputRange: [0, 1],

1088

outputRange: ['rgba(255,255,255,1)', 'rgba(0,0,0,1)']

1089

});

1090

1091

return (

1092

<Animated.View style={{ backgroundColor }}>

1093

<Animated.Text style={{ color: textColor }}>

1094

Color Transition

1095

</Animated.Text>

1096

</Animated.View>

1097

);

1098

}

1099

1100

// Multi-property interpolation

1101

function ComplexInterpolation() {

1102

const scrollY = new Animated.Value(0);

1103

1104

// Multiple interpolated properties from single value

1105

const headerOpacity = scrollY.interpolate({

1106

inputRange: [0, 50, 100],

1107

outputRange: [1, 0.5, 0],

1108

extrapolate: 'clamp'

1109

});

1110

1111

const headerScale = scrollY.interpolate({

1112

inputRange: [0, 100],

1113

outputRange: [1, 0.8],

1114

extrapolate: 'clamp'

1115

});

1116

1117

const titleFontSize = scrollY.interpolate({

1118

inputRange: [0, 100],

1119

outputRange: [24, 18],

1120

extrapolate: 'clamp'

1121

});

1122

1123

const borderRadius = scrollY.interpolate({

1124

inputRange: [0, 50],

1125

outputRange: [0, 15],

1126

extrapolate: 'clamp'

1127

});

1128

1129

return (

1130

<Animated.View

1131

style={{

1132

opacity: headerOpacity,

1133

transform: [{ scale: headerScale }],

1134

borderRadius

1135

}}

1136

>

1137

<Animated.Text

1138

style={{

1139

fontSize: titleFontSize

1140

}}

1141

>

1142

Dynamic Header

1143

</Animated.Text>

1144

</Animated.View>

1145

);

1146

}

1147

```

1148

1149

## Web-Specific Implementation

1150

1151

React Native Web's Animated implementation provides full compatibility with React Native's API while leveraging web-native CSS transitions and transforms for optimal performance.

1152

1153

**Key Features:**

1154

- CSS-based animations for better performance

1155

- Hardware acceleration through CSS transforms

1156

- Full interpolation support including colors and complex values

1157

- Event-driven animations with `Animated.event()`

1158

- Composition and mathematical operations

1159

- Support for custom easing functions

1160

1161

**Performance Notes:**

1162

- Transform animations (translateX, scale, rotate) are hardware accelerated

1163

- Opacity animations perform well across all browsers

1164

- Color interpolations are computed in JavaScript

1165

- Large numbers of simultaneous animations may impact performance

1166

- Consider using `useNativeDriver: true` for transform and opacity animations when available

1167

1168

## Types

1169

1170

```javascript { .api }

1171

interface CompositeAnimation {

1172

start(callback?: EndCallback): void;

1173

stop(): void;

1174

reset(): void;

1175

_startNativeLoop(iterations?: number): void;

1176

_isUsingNativeDriver(): boolean;

1177

}

1178

1179

interface AnimatedValueConfig {

1180

useNativeDriver?: boolean;

1181

}

1182

1183

interface TimingAnimationConfig {

1184

toValue: number | AnimatedValue;

1185

duration?: number;

1186

easing?: EasingFunction;

1187

delay?: number;

1188

useNativeDriver?: boolean;

1189

onComplete?: (result: EndResult) => void;

1190

}

1191

1192

interface SpringAnimationConfig {

1193

toValue: number | AnimatedValue;

1194

restDisplacementThreshold?: number;

1195

restSpeedThreshold?: number;

1196

velocity?: number;

1197

bounciness?: number;

1198

speed?: number;

1199

tension?: number;

1200

friction?: number;

1201

stiffness?: number;

1202

damping?: number;

1203

mass?: number;

1204

useNativeDriver?: boolean;

1205

onComplete?: (result: EndResult) => void;

1206

}

1207

1208

interface DecayAnimationConfig {

1209

velocity: number;

1210

deceleration?: number;

1211

useNativeDriver?: boolean;

1212

onComplete?: (result: EndResult) => void;

1213

}

1214

1215

interface ParallelConfig {

1216

stopTogether?: boolean;

1217

}

1218

1219

interface LoopAnimationConfig {

1220

iterations?: number;

1221

resetBeforeIteration?: boolean;

1222

}

1223

1224

interface InterpolationConfigType {

1225

inputRange: number[];

1226

outputRange: (number | string)[];

1227

easing?: EasingFunction;

1228

extrapolate?: 'extend' | 'identity' | 'clamp';

1229

extrapolateLeft?: 'extend' | 'identity' | 'clamp';

1230

extrapolateRight?: 'extend' | 'identity' | 'clamp';

1231

}

1232

1233

interface EndResult {

1234

finished: boolean;

1235

}

1236

1237

type EndCallback = (result: EndResult) => void;

1238

type ValueListenerCallback = (state: { value: number }) => void;

1239

type ValueXYListenerCallback = (state: { value: { x: number; y: number } }) => void;

1240

1241

type Mapping = { [key: string]: any } | AnimatedValue | null;

1242

1243

interface EventConfig {

1244

useNativeDriver?: boolean;

1245

listener?: Function;

1246

}

1247

```