or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation-utilities.mdcard-animations.mdheader-animations.mdindex.mdstack-navigation.mdtransition-presets.mdtransition-specs.md

animation-utilities.mddocs/

0

# Animation Utilities

1

2

Utility hooks and context providers for accessing animation values and gesture handlers within screen components, enabling custom animations and gesture-aware components.

3

4

## Capabilities

5

6

### useCardAnimation

7

8

Hook that provides access to card animation interpolation properties within stack screen components.

9

10

```typescript { .api }

11

/**

12

* Hook to access card animation values within stack screens

13

* @returns Card animation interpolation properties

14

* @throws Error if called outside of a stack screen context

15

*/

16

function useCardAnimation(): StackCardInterpolationProps;

17

```

18

19

**Usage Examples:**

20

21

```typescript

22

import React from 'react';

23

import { Animated, View } from 'react-native';

24

import { useCardAnimation } from '@react-navigation/stack';

25

26

function AnimatedScreen() {

27

const { current, closing, swiping } = useCardAnimation();

28

29

// Create custom animations based on card animation progress

30

const customOpacity = current.progress.interpolate({

31

inputRange: [0, 1],

32

outputRange: [0.3, 1],

33

});

34

35

const customScale = current.progress.interpolate({

36

inputRange: [0, 1],

37

outputRange: [0.9, 1],

38

});

39

40

const customRotation = current.progress.interpolate({

41

inputRange: [0, 1],

42

outputRange: ['-5deg', '0deg'],

43

});

44

45

return (

46

<Animated.View

47

style={{

48

flex: 1,

49

opacity: customOpacity,

50

transform: [

51

{ scale: customScale },

52

{ rotate: customRotation },

53

],

54

}}

55

>

56

<View style={{ padding: 20 }}>

57

<Text>Custom Animated Content</Text>

58

59

{/* Animate based on swipe gesture */}

60

<Animated.View

61

style={{

62

opacity: swiping.interpolate({

63

inputRange: [0, 1],

64

outputRange: [1, 0.5],

65

}),

66

}}

67

>

68

<Text>This fades during swipe gestures</Text>

69

</Animated.View>

70

71

{/* Animate based on closing state */}

72

<Animated.View

73

style={{

74

transform: [{

75

translateY: closing.interpolate({

76

inputRange: [0, 1],

77

outputRange: [0, -20],

78

}),

79

}],

80

}}

81

>

82

<Text>This moves up when closing</Text>

83

</Animated.View>

84

</View>

85

</Animated.View>

86

);

87

}

88

```

89

90

### useGestureHandlerRef

91

92

Hook that provides access to the gesture handler reference for coordinating custom gestures with navigation gestures.

93

94

```typescript { .api }

95

/**

96

* Hook to access gesture handler ref within stack screens

97

* @returns Gesture handler reference for coordination with navigation gestures

98

* @throws Error if called outside of a stack screen context

99

*/

100

function useGestureHandlerRef(): React.Ref<PanGestureHandler>;

101

```

102

103

**Usage Examples:**

104

105

```typescript

106

import React from 'react';

107

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

108

import { useGestureHandlerRef } from '@react-navigation/stack';

109

110

function GestureAwareScreen() {

111

const navigationGestureRef = useGestureHandlerRef();

112

const customGestureRef = useRef();

113

114

const handleGestureEvent = (event) => {

115

// Custom gesture handling that works with navigation gestures

116

console.log('Custom gesture:', event.nativeEvent);

117

};

118

119

const handleStateChange = (event) => {

120

if (event.nativeEvent.state === State.END) {

121

console.log('Custom gesture ended');

122

}

123

};

124

125

return (

126

<PanGestureHandler

127

ref={customGestureRef}

128

onGestureEvent={handleGestureEvent}

129

onHandlerStateChange={handleStateChange}

130

simultaneousHandlers={navigationGestureRef} // Allow simultaneous gestures

131

>

132

<View style={{ flex: 1 }}>

133

<Text>Swipe me while navigation gestures still work!</Text>

134

</View>

135

</PanGestureHandler>

136

);

137

}

138

```

139

140

### CardAnimationContext

141

142

React context that provides card animation interpolation properties to child components.

143

144

```typescript { .api }

145

/**

146

* Context providing card animation interpolation props to child components

147

* Value is undefined when not within a stack screen

148

*/

149

const CardAnimationContext: React.Context<StackCardInterpolationProps | undefined>;

150

```

151

152

**Usage Examples:**

153

154

```typescript

155

import React, { useContext } from 'react';

156

import { CardAnimationContext } from '@react-navigation/stack';

157

158

function CustomAnimatedComponent() {

159

const animationProps = useContext(CardAnimationContext);

160

161

if (!animationProps) {

162

// Not within a stack screen, render without animation

163

return <StaticComponent />;

164

}

165

166

const { current, next, closing } = animationProps;

167

168

const animatedOpacity = current.progress.interpolate({

169

inputRange: [0, 1],

170

outputRange: [0, 1],

171

});

172

173

return (

174

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

175

<Text>Animated based on card transition</Text>

176

</Animated.View>

177

);

178

}

179

180

// Provider usage (automatically provided by stack navigator)

181

function CustomScreen() {

182

return (

183

<View>

184

<CustomAnimatedComponent />

185

</View>

186

);

187

}

188

```

189

190

### GestureHandlerRefContext

191

192

React context that provides the gesture handler reference for coordinating custom gestures.

193

194

```typescript { .api }

195

/**

196

* Context providing gesture handler ref to child components

197

* Value is null when not within a stack screen

198

*/

199

const GestureHandlerRefContext: React.Context<React.Ref<PanGestureHandler> | null>;

200

```

201

202

**Usage Examples:**

203

204

```typescript

205

import React, { useContext } from 'react';

206

import { PanGestureHandler } from 'react-native-gesture-handler';

207

import { GestureHandlerRefContext } from '@react-navigation/stack';

208

209

function NestedGestureComponent() {

210

const navigationGestureRef = useContext(GestureHandlerRefContext);

211

212

return (

213

<PanGestureHandler

214

simultaneousHandlers={navigationGestureRef}

215

onGestureEvent={(event) => {

216

// Handle custom gesture while preserving navigation gestures

217

console.log('Nested gesture:', event.nativeEvent);

218

}}

219

>

220

<View style={{ padding: 20, backgroundColor: 'lightblue' }}>

221

<Text>This area has custom gestures that work with navigation</Text>

222

</View>

223

</PanGestureHandler>

224

);

225

}

226

```

227

228

## Advanced Animation Patterns

229

230

### Coordinated Animations

231

232

Combine multiple animation utilities for complex effects:

233

234

```typescript

235

import { useCardAnimation, useGestureHandlerRef } from '@react-navigation/stack';

236

237

function AdvancedAnimatedScreen() {

238

const { current, next, closing, swiping } = useCardAnimation();

239

const gestureRef = useGestureHandlerRef();

240

241

// Parallax effect with background

242

const backgroundTranslateX = current.progress.interpolate({

243

inputRange: [0, 1],

244

outputRange: [100, 0],

245

});

246

247

// Content animation with gesture awareness

248

const contentOpacity = Animated.multiply(

249

current.progress,

250

swiping.interpolate({

251

inputRange: [0, 1],

252

outputRange: [1, 0.7],

253

})

254

);

255

256

return (

257

<View style={{ flex: 1 }}>

258

{/* Animated background */}

259

<Animated.View

260

style={{

261

position: 'absolute',

262

top: 0,

263

left: 0,

264

right: 0,

265

bottom: 0,

266

backgroundColor: 'lightblue',

267

transform: [{ translateX: backgroundTranslateX }],

268

}}

269

/>

270

271

{/* Animated content */}

272

<Animated.View

273

style={{

274

flex: 1,

275

opacity: contentOpacity,

276

}}

277

>

278

<Text>Advanced coordinated animation</Text>

279

</Animated.View>

280

</View>

281

);

282

}

283

```

284

285

### Conditional Animations

286

287

Use animation context for conditional rendering and animations:

288

289

```typescript

290

function ConditionalAnimationScreen() {

291

const animationProps = useCardAnimation();

292

const isAnimating = animationProps ? animationProps.current.progress._value < 1 : false;

293

294

return (

295

<View style={{ flex: 1 }}>

296

{isAnimating ? (

297

<LoadingComponent />

298

) : (

299

<MainContent />

300

)}

301

302

{animationProps && (

303

<Animated.View

304

style={{

305

position: 'absolute',

306

bottom: 20,

307

right: 20,

308

opacity: animationProps.current.progress.interpolate({

309

inputRange: [0.8, 1],

310

outputRange: [0, 1],

311

extrapolate: 'clamp',

312

}),

313

}}

314

>

315

<FloatingActionButton />

316

</Animated.View>

317

)}

318

</View>

319

);

320

}

321

```

322

323

## Animation Properties Reference

324

325

### StackCardInterpolationProps

326

327

Complete properties available through animation utilities:

328

329

```typescript { .api }

330

interface StackCardInterpolationProps {

331

current: {

332

progress: Animated.AnimatedInterpolation<number>;

333

};

334

next?: {

335

progress: Animated.AnimatedInterpolation<number>;

336

};

337

index: number;

338

closing: Animated.AnimatedInterpolation<0 | 1>;

339

swiping: Animated.AnimatedInterpolation<0 | 1>;

340

inverted: Animated.AnimatedInterpolation<-1 | 1>;

341

layouts: {

342

screen: Layout;

343

};

344

insets: {

345

top: number;

346

right: number;

347

bottom: number;

348

left: number;

349

};

350

}

351

352

interface Layout {

353

width: number;

354

height: number;

355

}

356

```

357

358

These properties enable:

359

- **current.progress**: Animation progress of the current screen (0 to 1)

360

- **next.progress**: Animation progress of the next screen in stack (if exists)

361

- **closing**: Whether the screen is closing (1) or opening (0)

362

- **swiping**: Whether user is actively swiping (1) or not (0)

363

- **inverted**: Animation direction multiplier (-1 for RTL, 1 for LTR)

364

- **layouts.screen**: Screen dimensions for responsive animations

365

- **insets**: Safe area insets for proper positioning