or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animated-components.mdanimation-functions.mdconfiguration-utilities.mdcore-reactive-system.mdcss-integration.mdevent-handling.mdindex.mdinterpolation-easing.mdlayout-animations.mdplatform-functions.mdscreen-transitions.mdtesting-utilities.mdworklet-functions.md

platform-functions.mddocs/

0

# Platform Functions

1

2

Utilities for measuring components, scrolling, native platform integration, and accessing platform-specific functionality for optimal performance and native behavior.

3

4

## Capabilities

5

6

### Component Measurement

7

8

Functions for measuring component dimensions and positions.

9

10

```typescript { .api }

11

/**

12

* Measures the dimensions and position of a component

13

* @param ref - Animated ref to the component to measure

14

* @returns MeasuredDimensions object or null if measurement fails

15

*/

16

function measure(ref: AnimatedRef<any>): MeasuredDimensions | null;

17

18

/**

19

* Gets relative coordinates within a component

20

* @param ref - Animated ref to the reference component

21

* @param x - X coordinate to convert

22

* @param y - Y coordinate to convert

23

* @returns ComponentCoords object or null if conversion fails

24

*/

25

function getRelativeCoords(

26

ref: AnimatedRef<any>,

27

x: number,

28

y: number

29

): ComponentCoords | null;

30

31

interface MeasuredDimensions {

32

/** Component x position relative to its parent */

33

x: number;

34

/** Component y position relative to its parent */

35

y: number;

36

/** Component width */

37

width: number;

38

/** Component height */

39

height: number;

40

/** Component x position relative to the screen */

41

pageX: number;

42

/** Component y position relative to the screen */

43

pageY: number;

44

}

45

46

interface ComponentCoords {

47

/** X coordinate relative to the component */

48

x: number;

49

/** Y coordinate relative to the component */

50

y: number;

51

}

52

```

53

54

**Usage Examples:**

55

56

```typescript

57

import React, { useRef } from "react";

58

import Animated, {

59

useAnimatedRef,

60

measure,

61

getRelativeCoords,

62

useSharedValue,

63

useAnimatedStyle,

64

runOnUI,

65

runOnJS

66

} from "react-native-reanimated";

67

import { Button } from "react-native";

68

69

const MeasurementExample = () => {

70

const containerRef = useAnimatedRef();

71

const targetRef = useAnimatedRef();

72

const ballPosition = useSharedValue({ x: 50, y: 50 });

73

74

// Measure component dimensions

75

const measureComponent = () => {

76

runOnUI(() => {

77

'worklet';

78

const dimensions = measure(targetRef);

79

if (dimensions) {

80

runOnJS(console.log)('Component dimensions:', dimensions);

81

// Use measurements for animations

82

ballPosition.value = {

83

x: dimensions.width / 2,

84

y: dimensions.height / 2

85

};

86

}

87

})();

88

};

89

90

// Convert screen coordinates to component-relative coordinates

91

const handlePress = (event: any) => {

92

const { locationX, locationY } = event.nativeEvent;

93

94

runOnUI(() => {

95

'worklet';

96

const coords = getRelativeCoords(containerRef, locationX, locationY);

97

if (coords) {

98

ballPosition.value = coords;

99

runOnJS(console.log)('Relative coordinates:', coords);

100

}

101

})();

102

};

103

104

const ballStyle = useAnimatedStyle(() => ({

105

transform: [

106

{ translateX: ballPosition.value.x - 25 }, // Center the ball

107

{ translateY: ballPosition.value.y - 25 },

108

],

109

}));

110

111

return (

112

<>

113

<Button title="Measure Target" onPress={measureComponent} />

114

115

<Animated.View

116

ref={containerRef}

117

onTouchEnd={handlePress}

118

style={{

119

width: 300,

120

height: 200,

121

backgroundColor: "lightgray",

122

margin: 20,

123

borderRadius: 10,

124

position: "relative",

125

}}

126

>

127

<Animated.Text>Touch anywhere to move the ball</Animated.Text>

128

129

{/* Target component to measure */}

130

<Animated.View

131

ref={targetRef}

132

style={{

133

width: 100,

134

height: 100,

135

backgroundColor: "lightblue",

136

position: "absolute",

137

top: 20,

138

right: 20,

139

borderRadius: 5,

140

}}

141

>

142

<Animated.Text>Target</Animated.Text>

143

</Animated.View>

144

145

{/* Animated ball */}

146

<Animated.View

147

style={[

148

{

149

width: 50,

150

height: 50,

151

backgroundColor: "red",

152

borderRadius: 25,

153

position: "absolute",

154

},

155

ballStyle,

156

]}

157

/>

158

</Animated.View>

159

</>

160

);

161

};

162

```

163

164

### Scrolling Control

165

166

Programmatic scrolling control for ScrollView and other scrollable components.

167

168

```typescript { .api }

169

/**

170

* Programmatically scrolls a scrollable component

171

* @param ref - Animated ref to the scrollable component

172

* @param x - X coordinate to scroll to

173

* @param y - Y coordinate to scroll to

174

* @param animated - Whether to animate the scroll

175

*/

176

function scrollTo(

177

ref: AnimatedRef<any>,

178

x: number,

179

y: number,

180

animated: boolean

181

): void;

182

```

183

184

**Usage Examples:**

185

186

```typescript

187

import React from "react";

188

import Animated, {

189

useAnimatedRef,

190

scrollTo,

191

useSharedValue,

192

useAnimatedScrollHandler,

193

runOnUI

194

} from "react-native-reanimated";

195

import { Button } from "react-native";

196

197

const ScrollControlExample = () => {

198

const scrollRef = useAnimatedRef();

199

const scrollY = useSharedValue(0);

200

201

// Track scroll position

202

const scrollHandler = useAnimatedScrollHandler({

203

onScroll: (event) => {

204

scrollY.value = event.contentOffset.y;

205

},

206

});

207

208

// Scroll to specific positions

209

const scrollToTop = () => {

210

runOnUI(() => {

211

'worklet';

212

scrollTo(scrollRef, 0, 0, true);

213

})();

214

};

215

216

const scrollToMiddle = () => {

217

runOnUI(() => {

218

'worklet';

219

scrollTo(scrollRef, 0, 500, true);

220

})();

221

};

222

223

const scrollToBottom = () => {

224

runOnUI(() => {

225

'worklet';

226

scrollTo(scrollRef, 0, 1500, true);

227

})();

228

};

229

230

// Smooth scrolling animation

231

const smoothScrollTo = (targetY: number) => {

232

runOnUI(() => {

233

'worklet';

234

const startY = scrollY.value;

235

const distance = targetY - startY;

236

const duration = Math.abs(distance) / 2; // Adjust speed based on distance

237

238

// Custom smooth scroll implementation

239

const startTime = Date.now();

240

const animate = () => {

241

'worklet';

242

const elapsed = Date.now() - startTime;

243

const progress = Math.min(elapsed / duration, 1);

244

const easeProgress = 1 - Math.pow(1 - progress, 3); // Ease out cubic

245

246

const currentY = startY + distance * easeProgress;

247

scrollTo(scrollRef, 0, currentY, false);

248

249

if (progress < 1) {

250

// Continue animation

251

setTimeout(() => animate(), 16); // ~60fps

252

}

253

};

254

255

animate();

256

})();

257

};

258

259

return (

260

<>

261

<Button title="Scroll to Top" onPress={scrollToTop} />

262

<Button title="Scroll to Middle" onPress={scrollToMiddle} />

263

<Button title="Scroll to Bottom" onPress={scrollToBottom} />

264

<Button title="Smooth Scroll to 800" onPress={() => smoothScrollTo(800)} />

265

266

<Animated.ScrollView

267

ref={scrollRef}

268

onScroll={scrollHandler}

269

scrollEventThrottle={16}

270

style={{ height: 400 }}

271

>

272

{/* Content to scroll through */}

273

{Array.from({ length: 100 }).map((_, index) => (

274

<Animated.View

275

key={index}

276

style={{

277

height: 60,

278

backgroundColor: index % 2 ? "white" : "lightgray",

279

justifyContent: "center",

280

alignItems: "center",

281

borderBottomWidth: 1,

282

borderBottomColor: "gray",

283

}}

284

>

285

<Animated.Text>Item {index} - Y: {index * 60}</Animated.Text>

286

</Animated.View>

287

))}

288

</Animated.ScrollView>

289

</>

290

);

291

};

292

```

293

294

### Native Props Manipulation

295

296

Direct manipulation of native component properties for performance-critical updates.

297

298

```typescript { .api }

299

/**

300

* Sets native properties on a component directly

301

* @param ref - Animated ref to the component

302

* @param props - Object containing properties to set

303

*/

304

function setNativeProps(ref: AnimatedRef<any>, props: object): void;

305

306

/**

307

* Dispatches a command to a native component

308

* @param ref - Animated ref to the component

309

* @param commandName - Name of the command to dispatch

310

* @param args - Optional arguments for the command

311

*/

312

function dispatchCommand(

313

ref: AnimatedRef<any>,

314

commandName: string,

315

args?: any[]

316

): void;

317

318

/**

319

* Gets a property value from a native component

320

* @param ref - Animated ref to the component

321

* @param prop - Property name to get

322

* @returns Property value

323

*/

324

function getViewProp(ref: AnimatedRef<any>, prop: string): any;

325

```

326

327

**Usage Examples:**

328

329

```typescript

330

import React from "react";

331

import { TextInput } from "react-native";

332

import Animated, {

333

useAnimatedRef,

334

setNativeProps,

335

dispatchCommand,

336

getViewProp,

337

useSharedValue,

338

useAnimatedStyle,

339

runOnUI,

340

runOnJS

341

} from "react-native-reanimated";

342

import { Button } from "react-native";

343

344

const NativePropsExample = () => {

345

const textInputRef = useAnimatedRef();

346

const viewRef = useAnimatedRef();

347

const opacity = useSharedValue(1);

348

349

// Direct native prop manipulation

350

const changeInputProps = () => {

351

runOnUI(() => {

352

'worklet';

353

setNativeProps(textInputRef, {

354

text: "Updated via native props!",

355

placeholder: "Native update",

356

backgroundColor: "#ffeeee",

357

});

358

})();

359

};

360

361

// Focus input using dispatch command

362

const focusInput = () => {

363

runOnUI(() => {

364

'worklet';

365

dispatchCommand(textInputRef, "focus", []);

366

})();

367

};

368

369

// Blur input using dispatch command

370

const blurInput = () => {

371

runOnUI(() => {

372

'worklet';

373

dispatchCommand(textInputRef, "blur", []);

374

})();

375

};

376

377

// Get view properties

378

const getViewProperties = () => {

379

runOnUI(() => {

380

'worklet';

381

const opacity = getViewProp(viewRef, "opacity");

382

const backgroundColor = getViewProp(viewRef, "backgroundColor");

383

384

runOnJS(console.log)("View opacity:", opacity);

385

runOnJS(console.log)("View backgroundColor:", backgroundColor);

386

})();

387

};

388

389

// Batch native updates for performance

390

const batchNativeUpdates = () => {

391

runOnUI(() => {

392

'worklet';

393

// Multiple native updates in single UI frame

394

setNativeProps(viewRef, {

395

backgroundColor: `hsl(${Math.random() * 360}, 70%, 80%)`,

396

borderRadius: Math.random() * 20,

397

borderWidth: Math.random() * 5,

398

});

399

400

setNativeProps(textInputRef, {

401

fontSize: 14 + Math.random() * 10,

402

color: Math.random() > 0.5 ? "black" : "blue",

403

});

404

})();

405

};

406

407

const animatedStyle = useAnimatedStyle(() => ({

408

opacity: opacity.value,

409

}));

410

411

return (

412

<>

413

<Button title="Change Input Props" onPress={changeInputProps} />

414

<Button title="Focus Input" onPress={focusInput} />

415

<Button title="Blur Input" onPress={blurInput} />

416

<Button title="Get View Props" onPress={getViewProperties} />

417

<Button title="Batch Updates" onPress={batchNativeUpdates} />

418

419

<Animated.View

420

ref={viewRef}

421

style={[

422

{

423

width: 200,

424

height: 100,

425

backgroundColor: "lightblue",

426

margin: 20,

427

padding: 10,

428

borderRadius: 10,

429

},

430

animatedStyle,

431

]}

432

>

433

<TextInput

434

ref={textInputRef}

435

style={{

436

height: 40,

437

borderWidth: 1,

438

borderColor: "gray",

439

borderRadius: 5,

440

paddingHorizontal: 10,

441

backgroundColor: "white",

442

}}

443

placeholder="Type something..."

444

/>

445

</Animated.View>

446

</>

447

);

448

};

449

```

450

451

### Gesture Integration

452

453

Integration with gesture handling systems for advanced touch interactions.

454

455

```typescript { .api }

456

/**

457

* Sets the state of a gesture handler

458

* @param handlerTag - Tag identifying the gesture handler

459

* @param newState - New state to set for the handler

460

*/

461

function setGestureState(handlerTag: number, newState: number): void;

462

```

463

464

**Usage Example:**

465

466

```typescript

467

import React from "react";

468

import Animated, {

469

useSharedValue,

470

useAnimatedStyle,

471

useAnimatedGestureHandler,

472

setGestureState,

473

runOnUI

474

} from "react-native-reanimated";

475

import { PanGestureHandler, State } from "react-native-gesture-handler";

476

477

const GestureIntegrationExample = () => {

478

const translateX = useSharedValue(0);

479

const translateY = useSharedValue(0);

480

const gestureHandlerTag = useSharedValue(0);

481

482

// Gesture handler with state control

483

const gestureHandler = useAnimatedGestureHandler({

484

onStart: (_, context) => {

485

context.startX = translateX.value;

486

context.startY = translateY.value;

487

},

488

onActive: (event, context) => {

489

translateX.value = context.startX + event.translationX;

490

translateY.value = context.startY + event.translationY;

491

492

// Control gesture state based on conditions

493

if (Math.abs(event.translationX) > 200) {

494

// Cancel gesture if moved too far

495

setGestureState(gestureHandlerTag.value, State.CANCELLED);

496

}

497

},

498

onEnd: (event) => {

499

// Snap back to center if released

500

if (Math.abs(translateX.value) > 100 || Math.abs(translateY.value) > 100) {

501

translateX.value = withSpring(0);

502

translateY.value = withSpring(0);

503

}

504

},

505

});

506

507

// Programmatic gesture control

508

const resetGesture = () => {

509

runOnUI(() => {

510

'worklet';

511

setGestureState(gestureHandlerTag.value, State.END);

512

translateX.value = withSpring(0);

513

translateY.value = withSpring(0);

514

})();

515

};

516

517

const animatedStyle = useAnimatedStyle(() => ({

518

transform: [

519

{ translateX: translateX.value },

520

{ translateY: translateY.value },

521

],

522

}));

523

524

return (

525

<>

526

<Button title="Reset Gesture" onPress={resetGesture} />

527

528

<PanGestureHandler

529

onGestureEvent={gestureHandler}

530

onHandlerStateChange={(event) => {

531

gestureHandlerTag.value = event.nativeEvent.handlerTag;

532

}}

533

>

534

<Animated.View

535

style={[

536

{

537

width: 100,

538

height: 100,

539

backgroundColor: "lightcoral",

540

borderRadius: 10,

541

margin: 50,

542

},

543

animatedStyle,

544

]}

545

>

546

<Animated.Text style={{ textAlign: "center", marginTop: 35 }}>

547

Drag me!

548

</Animated.Text>

549

</Animated.View>

550

</PanGestureHandler>

551

</>

552

);

553

};

554

```

555

556

### Platform-Specific Utilities

557

558

Utilities for handling platform differences and native integration.

559

560

**Version and Configuration Checks:**

561

562

```typescript

563

import {

564

isConfigured,

565

isReanimated3,

566

reanimatedVersion

567

} from "react-native-reanimated";

568

569

// Check if Reanimated is properly configured

570

if (isConfigured()) {

571

console.log("Reanimated is ready");

572

}

573

574

// Check version

575

if (isReanimated3()) {

576

console.log("Using Reanimated 3+");

577

}

578

579

console.log("Reanimated version:", reanimatedVersion);

580

```

581

582

**Configuration and Debugging:**

583

584

```typescript

585

import {

586

configureReanimatedLogger,

587

ReanimatedLogLevel,

588

enableLayoutAnimations

589

} from "react-native-reanimated";

590

591

// Configure logging

592

configureReanimatedLogger({

593

level: ReanimatedLogLevel.warn,

594

strict: false,

595

});

596

597

// Enable layout animations (required for some platforms)

598

enableLayoutAnimations(true);

599

```

600

601

### Performance Monitoring

602

603

Monitor and optimize animation performance using built-in tools.

604

605

```typescript { .api }

606

/**

607

* Performance monitoring component for tracking animation performance

608

*/

609

const PerformanceMonitor: React.ComponentType<PerformanceMonitorProps>;

610

611

interface PerformanceMonitorProps {

612

/** Whether to show performance overlay */

613

enabled?: boolean;

614

/** Callback for performance data */

615

onPerformanceData?: (data: PerformanceData) => void;

616

}

617

618

interface PerformanceData {

619

/** Frames per second */

620

fps: number;

621

/** JavaScript thread usage */

622

jsThreadUsage: number;

623

/** UI thread usage */

624

uiThreadUsage: number;

625

/** Memory usage */

626

memoryUsage: number;

627

}

628

```

629

630

**Usage Example:**

631

632

```typescript

633

import React, { useState } from "react";

634

import Animated, {

635

PerformanceMonitor,

636

useSharedValue,

637

useAnimatedStyle,

638

withRepeat,

639

withTiming

640

} from "react-native-reanimated";

641

642

const PerformanceExample = () => {

643

const [performanceEnabled, setPerformanceEnabled] = useState(false);

644

const rotation = useSharedValue(0);

645

646

const animatedStyle = useAnimatedStyle(() => ({

647

transform: [{ rotate: `${rotation.value}deg` }],

648

}));

649

650

const startHeavyAnimation = () => {

651

rotation.value = withRepeat(

652

withTiming(360, { duration: 100 }),

653

-1,

654

false

655

);

656

};

657

658

const handlePerformanceData = (data: PerformanceData) => {

659

console.log("Performance:", data);

660

};

661

662

return (

663

<>

664

<PerformanceMonitor

665

enabled={performanceEnabled}

666

onPerformanceData={handlePerformanceData}

667

/>

668

669

<Button

670

title={`Performance Monitor: ${performanceEnabled ? "ON" : "OFF"}`}

671

onPress={() => setPerformanceEnabled(!performanceEnabled)}

672

/>

673

674

<Button title="Start Heavy Animation" onPress={startHeavyAnimation} />

675

676

<Animated.View

677

style={[

678

{

679

width: 100,

680

height: 100,

681

backgroundColor: "lightgreen",

682

margin: 20,

683

},

684

animatedStyle,

685

]}

686

/>

687

</>

688

);

689

};

690

```

691

692

## Type Definitions

693

694

```typescript { .api }

695

interface AnimatedRef<T> {

696

current: T | null;

697

(component?: T | null): void;

698

}

699

700

interface SerializableRef {

701

__reanimatedSerializableRef: true;

702

__value: number;

703

}

704

705

type NativeMethods = {

706

measure(callback: (x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void): void;

707

measureInWindow(callback: (x: number, y: number, width: number, height: number) => void): void;

708

measureLayout(

709

relativeToNativeNode: number,

710

onSuccess: (left: number, top: number, width: number, height: number) => void,

711

onFail: () => void

712

): void;

713

setNativeProps(nativeProps: object): void;

714

focus(): void;

715

blur(): void;

716

};

717

718

enum ReanimatedLogLevel {

719

debug = 0,

720

info = 1,

721

warn = 2,

722

error = 3,

723

}

724

725

interface LoggerConfig {

726

level?: ReanimatedLogLevel;

727

strict?: boolean;

728

}

729

```

730

731

## Best Practices

732

733

### Performance Optimization

734

735

1. **Batch native updates**: Group multiple `setNativeProps` calls together

736

2. **Use appropriate measurement timing**: Measure after layout is complete

737

3. **Cache measurement results**: Store dimensions in shared values when possible

738

4. **Minimize cross-thread communication**: Keep measurements on UI thread when possible

739

5. **Profile with PerformanceMonitor**: Monitor FPS and thread usage

740

741

### Platform Considerations

742

743

1. **Test on all target platforms**: iOS, Android, and Web have different behaviors

744

2. **Handle platform-specific features**: Some functions may not be available on all platforms

745

3. **Use native props judiciously**: Direct native manipulation bypasses React's reconciliation

746

4. **Consider accessibility**: Ensure platform functions don't break accessibility features

747

748

### Common Patterns

749

750

1. **Responsive layouts**: Use measurements to create adaptive UIs

751

2. **Custom gesture handling**: Combine with gesture libraries for complex interactions

752

3. **Performance monitoring**: Track animation performance in development builds

753

4. **Smooth scrolling**: Implement custom scroll behaviors with `scrollTo`