Documentation Index
Fetch the complete documentation index at: https://mintlify.com/shopify/react-native-skia/llms.txt
Use this file to discover all available pages before exploring further.
Interpolation functions map input values to output values, enabling smooth transitions and animations. React Native Skia provides utilities for interpolating numbers, colors, vectors, and paths.
interpolate
Maps a value from an input range to an output range.
import { interpolate } from "@shopify/react-native-skia";
// Basic interpolation
const value = interpolate(50, [0, 100], [0, 1]);
console.log(value); // 0.5
// Non-linear mapping
const scaled = interpolate(50, [0, 100], [0, 200]);
console.log(scaled); // 100
Function Signature
function interpolate(
value: number,
inputRange: number[],
outputRange: number[],
options?: ExtrapolationType
): number
Parameters
The input value to interpolate
Array of input values (must be monotonically increasing)
Array of output values (same length as inputRange)
Extrapolation behavior:
"extend": Continues the pattern beyond the range (default)
"clamp": Clamps to the nearest edge value
"identity": Returns the input value unchanged
{ extrapolateLeft: Extrapolate, extrapolateRight: Extrapolate }
Examples
Linear Interpolation
// Map progress (0-1) to position (0-300)
const progress = 0.5;
const position = interpolate(progress, [0, 1], [0, 300]);
// position = 150
Multi-Point Interpolation
// Ease in-out effect
const progress = 0.5;
const eased = interpolate(
progress,
[0, 0.25, 0.75, 1],
[0, 0.1, 0.9, 1]
);
import { Extrapolate } from "@shopify/react-native-skia";
// Clamp to range
const value = interpolate(150, [0, 100], [0, 1], "clamp");
// value = 1 (clamped)
// Extend beyond range
const extended = interpolate(150, [0, 100], [0, 1], "extend");
// extended = 1.5 (extended)
// Different extrapolation on each side
const mixed = interpolate(150, [0, 100], [0, 1], {
extrapolateLeft: Extrapolate.CLAMP,
extrapolateRight: Extrapolate.EXTEND,
});
interpolateColors
Interpolates between colors.
import { interpolateColors } from "@shopify/react-native-skia";
const progress = 0.5;
const color = interpolateColors(
progress,
[0, 1],
["red", "blue"]
);
// Returns an RGBA color array
Function Signature
function interpolateColors(
value: number,
inputRange: number[],
outputRange: Color[]
): SkColor
Examples
Gradient Effect
import { useSharedValue, useDerivedValue } from "react-native-reanimated";
import { Canvas, Circle, interpolateColors } from "@shopify/react-native-skia";
export default function ColorTransition() {
const progress = useSharedValue(0);
useEffect(() => {
progress.value = withRepeat(
withTiming(1, { duration: 2000 }),
-1,
true
);
}, []);
const color = useDerivedValue(() => {
return interpolateColors(
progress.value,
[0, 0.5, 1],
["red", "yellow", "green"]
);
});
return (
<Canvas style={{ flex: 1 }}>
<Circle cx={150} cy={150} r={100} color={color} />
</Canvas>
);
}
mixColors
Mixes two colors by a factor.
import { mixColors } from "@shopify/react-native-skia";
const mixed = mixColors(0.5, "red", "blue");
// Returns a color halfway between red and blue
Function Signature
function mixColors(
value: number,
color1: Color,
color2: Color
): SkColor
interpolatePaths
Interpolates between path shapes.
import { interpolatePaths, Skia } from "@shopify/react-native-skia";
const path1 = Skia.Path.MakeFromSVGString("M 0 0 L 100 0 L 50 100 Z");
const path2 = Skia.Path.MakeFromSVGString("M 0 100 L 100 100 L 50 0 Z");
const morphed = interpolatePaths(0.5, [0, 1], [path1, path2]);
Function Signature
function interpolatePaths(
value: number,
inputRange: number[],
outputRange: SkPath[],
options?: ExtrapolationType,
output?: SkPath
): SkPath
Requirements
- Paths must be interpolatable (same number of points and commands)
- Use
path1.isInterpolatable(path2) to check compatibility
Examples
Morphing Shapes
import { useSharedValue, useDerivedValue, withRepeat, withTiming } from "react-native-reanimated";
import { Canvas, Path, interpolatePaths, Skia } from "@shopify/react-native-skia";
import { useEffect } from "react";
const triangle = Skia.Path.MakeFromSVGString("M 50 0 L 100 100 L 0 100 Z");
const square = Skia.Path.MakeFromSVGString("M 0 0 L 100 0 L 100 100 L 0 100 Z");
export default function MorphingShape() {
const progress = useSharedValue(0);
useEffect(() => {
progress.value = withRepeat(
withTiming(1, { duration: 2000 }),
-1,
true
);
}, []);
const path = useDerivedValue(() => {
return interpolatePaths(
progress.value,
[0, 1],
[triangle, square]
);
});
return (
<Canvas style={{ flex: 1 }}>
<Path path={path} color="purple" />
</Canvas>
);
}
interpolateVector
Interpolates between 2D vectors.
import { interpolateVector } from "@shopify/react-native-skia";
const start = { x: 0, y: 0 };
const end = { x: 100, y: 100 };
const point = interpolateVector(0.5, [0, 1], [start, end]);
// point = { x: 50, y: 50 }
Using with Animations
Animated Position
import { useSharedValue, useDerivedValue } from "react-native-reanimated";
import { Canvas, Circle, interpolate } from "@shopify/react-native-skia";
const progress = useSharedValue(0);
const x = useDerivedValue(() => {
return interpolate(progress.value, [0, 1], [50, 250]);
});
const y = useDerivedValue(() => {
return interpolate(progress.value, [0, 1], [100, 300]);
});
<Circle cx={x} cy={y} r={30} color="blue" />
Animated Scale
const progress = useSharedValue(0);
const scale = useDerivedValue(() => {
return interpolate(
progress.value,
[0, 0.5, 1],
[1, 1.5, 1],
"clamp"
);
});
<Circle
cx={150}
cy={150}
r={() => 50 * scale.value}
color="green"
/>
Animated Rotation
const progress = useSharedValue(0);
const rotation = useDerivedValue(() => {
return interpolate(
progress.value,
[0, 1],
[0, Math.PI * 2]
);
});
<Rect
x={0}
y={0}
width={100}
height={100}
color="red"
origin={{ x: 50, y: 50 }}
transform={[{ rotate: rotation }]}
/>
Easing Functions
Combine with easing for natural motion:
import { Easing } from "react-native-reanimated";
import { interpolate } from "@shopify/react-native-skia";
const progress = useSharedValue(0);
const eased = useDerivedValue(() => {
// Apply easing
const easedProgress = Easing.bezier(0.25, 0.1, 0.25, 1)(progress.value);
// Then interpolate
return interpolate(easedProgress, [0, 1], [0, 300]);
});
Common Patterns
Fade In/Out
const opacity = useDerivedValue(() => {
return interpolate(
progress.value,
[0, 0.3, 0.7, 1],
[0, 1, 1, 0],
"clamp"
);
});
Bounce Effect
const scale = useDerivedValue(() => {
return interpolate(
progress.value,
[0, 0.25, 0.5, 0.75, 1],
[1, 1.2, 0.9, 1.05, 1]
);
});
const scrollY = useSharedValue(0);
const backgroundY = useDerivedValue(() => {
return interpolate(
scrollY.value,
[0, 500],
[0, -100], // Slower movement
"extend"
);
});
const foregroundY = useDerivedValue(() => {
return interpolate(
scrollY.value,
[0, 500],
[0, -200], // Faster movement
"extend"
);
});
- Use
useDerivedValue for interpolation in animations
- Mark interpolation functions as worklets with
"worklet"
- Avoid creating new arrays in interpolate calls
- Reuse output ranges when possible
- For path interpolation, check
isInterpolatable() first
- Use
"clamp" extrapolation to prevent unexpected values
import { Extrapolate } from "@shopify/react-native-skia";
// Clamp to edges
Extrapolate.CLAMP
// Continue the pattern
Extrapolate.EXTEND
// Return input value unchanged
Extrapolate.IDENTITY