0
# Animation Integration
1
2
Animation utilities and React Native Reanimated integration for creating smooth, performant animations in React Native Skia.
3
4
## Capabilities
5
6
### Core Animation Functions
7
8
```typescript { .api }
9
/**
10
* Maps input value to output range with extrapolation control
11
* @param x - Input value to interpolate
12
* @param input - Input range array (must be monotonically increasing)
13
* @param output - Output range array (same length as input)
14
* @param type - Extrapolation behavior outside input range
15
* @returns Interpolated output value
16
*/
17
function interpolate(
18
x: number,
19
input: readonly number[],
20
output: readonly number[],
21
type?: ExtrapolationType
22
): number;
23
24
type ExtrapolationType = "extend" | "clamp" | "identity";
25
26
/**
27
* Interpolates between multiple colors
28
* @param value - Input value (typically 0.0 to 1.0)
29
* @param inputRange - Input range for color interpolation
30
* @param outputRange - Array of colors to interpolate between
31
* @returns Color as number array [r, g, b, a]
32
*/
33
function interpolateColors(
34
value: number,
35
inputRange: number[],
36
outputRange: Color[]
37
): number[];
38
39
/**
40
* Mixes two colors with a blend factor
41
* @param value - Blend factor (0.0 = first color, 1.0 = second color)
42
* @param x - First color
43
* @param y - Second color
44
* @returns Mixed color as Float32Array
45
*/
46
function mixColors(value: number, x: Color, y: Color): Float32Array;
47
48
/**
49
* Mixes two vectors with a blend factor
50
* @param value - Blend factor (0.0 = first vector, 1.0 = second vector)
51
* @param from - First vector
52
* @param to - Second vector
53
* @returns Mixed vector
54
*/
55
function mixVector(value: number, from: Vector, to: Vector): Vector;
56
```
57
58
### Animation Prop System
59
60
React Native Skia supports animated properties through the SkiaProps type system.
61
62
```typescript { .api }
63
/**
64
* Wrapper type that makes all properties of T potentially animated
65
*/
66
type SkiaProps<T> = {
67
[K in keyof T]: T[K] | SharedValue<T[K]> | DerivedValue<T[K]>;
68
};
69
70
/**
71
* Single animated property type
72
*/
73
type AnimatedProp<T> = T | SharedValue<T> | DerivedValue<T>;
74
75
/**
76
* Props with optional default values that can be animated
77
*/
78
type SkiaDefaultProps<T, N> = SkiaProps<T> & {
79
[K in keyof N]: AnimatedProp<N[K]>;
80
};
81
```
82
83
### Reanimated Integration
84
85
React Native Skia integrates seamlessly with React Native Reanimated for smooth animations.
86
87
```typescript { .api }
88
// Animation hooks from external/reanimated module
89
90
/**
91
* Hook for animated image loading and updates
92
* @param imageUri - Image URI that can be animated
93
* @returns Animated image value
94
*/
95
function useAnimatedImageValue(imageUri: SharedValue<string>): SharedValue<SkImage | null>;
96
97
/**
98
* Hook for video playback integration with animations
99
* @param url - Video URL
100
* @returns Video object with frame access
101
*/
102
function useVideo(url: string): Video | null;
103
```
104
105
### Animation Utilities
106
107
```typescript { .api }
108
// Render helpers for animated content
109
interface RenderHelpers {
110
/** Helper functions for rendering animated content */
111
// Implementation details depend on internal architecture
112
}
113
114
// Interpolation utilities
115
interface Interpolators {
116
/** Vector interpolation utilities */
117
interpolateVector: (
118
value: number,
119
inputRange: number[],
120
outputRange: Vector[]
121
) => Vector;
122
123
/** Path interpolation for morphing shapes */
124
interpolatePaths: (
125
value: number,
126
inputRange: number[],
127
outputRange: PathDef[]
128
) => PathDef;
129
}
130
131
// Texture and buffer management for animations
132
interface TextureUtils {
133
/** Texture sharing utilities with Reanimated */
134
// Used internally for performance optimization
135
}
136
137
interface BufferUtils {
138
/** Buffer management utilities */
139
// Used internally for memory management
140
}
141
```
142
143
## Usage Examples
144
145
### Basic Property Animation
146
147
```typescript
148
import React, { useEffect } from "react";
149
import { Canvas, Circle, Paint } from "@shopify/react-native-skia";
150
import { useSharedValue, withRepeat, withTiming } from "react-native-reanimated";
151
152
function AnimatedCircle() {
153
const radius = useSharedValue(20);
154
155
useEffect(() => {
156
radius.value = withRepeat(
157
withTiming(50, { duration: 1000 }),
158
-1, // infinite
159
true // reverse
160
);
161
}, []);
162
163
return (
164
<Canvas style={{ width: 200, height: 200 }}>
165
<Circle cx={100} cy={100} r={radius}>
166
<Paint color="blue" />
167
</Circle>
168
</Canvas>
169
);
170
}
171
```
172
173
### Color Animation
174
175
```typescript
176
import React, { useEffect } from "react";
177
import { Canvas, Circle, Paint } from "@shopify/react-native-skia";
178
import { useSharedValue, withRepeat, withTiming, useDerivedValue } from "react-native-reanimated";
179
import { interpolateColors } from "@shopify/react-native-skia";
180
181
function ColorAnimatedCircle() {
182
const progress = useSharedValue(0);
183
184
const animatedColor = useDerivedValue(() => {
185
return interpolateColors(
186
progress.value,
187
[0, 1],
188
["red", "blue"]
189
);
190
});
191
192
useEffect(() => {
193
progress.value = withRepeat(
194
withTiming(1, { duration: 2000 }),
195
-1,
196
true
197
);
198
}, []);
199
200
return (
201
<Canvas style={{ width: 200, height: 200 }}>
202
<Circle cx={100} cy={100} r={40}>
203
<Paint color={animatedColor} />
204
</Circle>
205
</Canvas>
206
);
207
}
208
```
209
210
### Transform Animation
211
212
```typescript
213
import React, { useEffect } from "react";
214
import { Canvas, Rect, Paint } from "@shopify/react-native-skia";
215
import { useSharedValue, withRepeat, withTiming } from "react-native-reanimated";
216
217
function RotatingRect() {
218
const rotation = useSharedValue(0);
219
220
useEffect(() => {
221
rotation.value = withRepeat(
222
withTiming(360, { duration: 2000 }),
223
-1,
224
false
225
);
226
}, []);
227
228
return (
229
<Canvas style={{ width: 200, height: 200 }}>
230
<Rect
231
x={75}
232
y={75}
233
width={50}
234
height={50}
235
origin={{ x: 100, y: 100 }}
236
transform={[{ rotate: rotation }]}
237
>
238
<Paint color="green" />
239
</Rect>
240
</Canvas>
241
);
242
}
243
```
244
245
### Complex Animation with Multiple Properties
246
247
```typescript
248
import React, { useEffect } from "react";
249
import { Canvas, Circle, Paint, LinearGradient } from "@shopify/react-native-skia";
250
import {
251
useSharedValue,
252
withRepeat,
253
withTiming,
254
useDerivedValue,
255
withSequence
256
} from "react-native-reanimated";
257
import { interpolate } from "@shopify/react-native-skia";
258
259
function ComplexAnimation() {
260
const progress = useSharedValue(0);
261
262
const radius = useDerivedValue(() => {
263
return interpolate(progress.value, [0, 1], [20, 60]);
264
});
265
266
const opacity = useDerivedValue(() => {
267
return interpolate(progress.value, [0, 0.5, 1], [1, 0.3, 1]);
268
});
269
270
const translateX = useDerivedValue(() => {
271
return interpolate(progress.value, [0, 1], [50, 150], "clamp");
272
});
273
274
useEffect(() => {
275
progress.value = withRepeat(
276
withSequence(
277
withTiming(1, { duration: 1500 }),
278
withTiming(0, { duration: 1500 })
279
),
280
-1,
281
false
282
);
283
}, []);
284
285
return (
286
<Canvas style={{ width: 200, height: 200 }}>
287
<Circle
288
cx={translateX}
289
cy={100}
290
r={radius}
291
opacity={opacity}
292
>
293
<LinearGradient
294
start={{ x: 0, y: 0 }}
295
end={{ x: 100, y: 0 }}
296
colors={["purple", "pink"]}
297
/>
298
</Circle>
299
</Canvas>
300
);
301
}
302
```
303
304
### Gesture-Driven Animation
305
306
```typescript
307
import React from "react";
308
import { Canvas, Circle, Paint } from "@shopify/react-native-skia";
309
import { useSharedValue } from "react-native-reanimated";
310
import { Gesture, GestureDetector } from "react-native-gesture-handler";
311
312
function GestureAnimatedCircle() {
313
const translateX = useSharedValue(100);
314
const translateY = useSharedValue(100);
315
316
const panGesture = Gesture.Pan()
317
.onUpdate((event) => {
318
translateX.value = event.translationX + 100;
319
translateY.value = event.translationY + 100;
320
});
321
322
return (
323
<GestureDetector gesture={panGesture}>
324
<Canvas style={{ width: 200, height: 200 }}>
325
<Circle cx={translateX} cy={translateY} r={25}>
326
<Paint color="orange" />
327
</Circle>
328
</Canvas>
329
</GestureDetector>
330
);
331
}
332
```
333
334
## Animation Performance Tips
335
336
1. **Use SharedValues**: Always use Reanimated's SharedValue for animated properties
337
2. **Prefer useDerivedValue**: Use useDerivedValue for computed animated values
338
3. **Minimize Re-renders**: Keep animated logic in the UI thread when possible
339
4. **Batch Updates**: Group related property changes together
340
5. **Use runOnUI**: For complex calculations, use runOnUI to run on the UI thread
341
342
## Core Types
343
344
```typescript { .api }
345
// Reanimated types (from react-native-reanimated)
346
type SharedValue<T> = {
347
value: T;
348
};
349
350
type DerivedValue<T> = {
351
readonly value: T;
352
};
353
354
// Animation prop types
355
type AnimatedProp<T> = T | SharedValue<T> | DerivedValue<T>;
356
357
type SkiaProps<T> = {
358
[K in keyof T]: AnimatedProp<T[K]>;
359
};
360
361
// Interpolation types
362
type ExtrapolationType = "extend" | "clamp" | "identity";
363
364
// Common animated types
365
type Color = string | number | Float32Array;
366
type Vector = SkPoint | { x: number; y: number };
367
type PathDef = string | SkPath;
368
369
// Transform types for animation
370
type Transform3d =
371
| { translateX: number }
372
| { translateY: number }
373
| { scale: number }
374
| { scaleX: number }
375
| { scaleY: number }
376
| { rotate: number }
377
| { rotateX: number }
378
| { rotateY: number }
379
| { rotateZ: number }
380
| { skewX: number }
381
| { skewY: number };
382
```