Matrices are used to transform graphics objects in 2D space. React Native Skia provides both 3x3 matrices for 2D transforms and 4x4 matrices for 3D transforms.
Creating Matrices
Identity Matrix
import { Skia } from "@shopify/react-native-skia";
const matrix = Skia.Matrix(); // Identity matrix
From Array
// 3x3 matrix (9 values)
const matrix = Skia.Matrix([
1, 0, 0,
0, 1, 0,
0, 0, 1,
]);
Matrix Methods
Translation
translate
(x: number, y: number) => SkMatrix
Translates (moves) by x, yconst matrix = Skia.Matrix();
matrix.translate(50, 100);
Rotation
rotate
(radians: number) => SkMatrix
Rotates by angle in radiansconst matrix = Skia.Matrix();
matrix.rotate(Math.PI / 4); // 45 degrees
Scale
scale
(x: number, y?: number) => SkMatrix
Scales by x and y factors. If y is omitted, uses x for both.const matrix = Skia.Matrix();
matrix.scale(2, 2); // Double size
matrix.scale(0.5); // Half size
Skew
skew
(x: number, y: number) => SkMatrix
Skews by x and y angles in radiansconst matrix = Skia.Matrix();
matrix.skew(0.5, 0); // Skew horizontally
Concatenation
concat
(matrix: InputMatrix) => SkMatrix
Multiplies this matrix with anotherconst m1 = Skia.Matrix().translate(50, 50);
const m2 = Skia.Matrix().rotate(Math.PI / 4);
const combined = m1.concat(m2);
Post-Operations
These apply transformations after the current matrix:
postTranslate
(x: number, y: number) => SkMatrix
Post-multiplies a translation
postRotate
(radians: number) => SkMatrix
Post-multiplies a rotation
postScale
(x: number, y?: number) => SkMatrix
Post-multiplies a scale
postSkew
(x: number, y: number) => SkMatrix
Post-multiplies a skew
Identity
Resets to identity matrix
Get Values
Returns the 9 matrix values as an arrayconst values = matrix.get();
console.log(values); // [1, 0, 0, 0, 1, 0, 0, 0, 1]
The declarative API uses transform objects:
import { Canvas, Rect } from "@shopify/react-native-skia";
<Canvas style={{ flex: 1 }}>
<Rect
x={0}
y={0}
width={100}
height={100}
color="blue"
transform={[
{ translateX: 100 },
{ translateY: 100 },
{ rotate: Math.PI / 4 },
{ scale: 1.5 },
]}
/>
</Canvas>
Translation
{ translateX: 50 }
{ translateY: 100 }
{ translate: [50, 100] }
Rotation
{ rotate: Math.PI / 4 } // Around origin (0, 0)
{ rotateZ: Math.PI / 4 } // Same as rotate
Scale
{ scale: 2 } // Uniform scale
{ scaleX: 2 }
{ scaleY: 0.5 }
Skew
{ skewX: 0.5 }
{ skewY: 0.5 }
Matrix
{ matrix: [1, 0, 0, 0, 1, 0, 0, 0, 1] }
Specify the origin point for transformations:
import { Canvas, Rect } from "@shopify/react-native-skia";
<Canvas style={{ flex: 1 }}>
<Rect
x={0}
y={0}
width={100}
height={100}
color="red"
origin={{ x: 50, y: 50 }} // Rotate around center
transform={[
{ rotate: Math.PI / 4 },
]}
/>
</Canvas>
For 3D transformations:
import { Canvas, Rect } from "@shopify/react-native-skia";
<Canvas style={{ flex: 1 }}>
<Rect
x={0}
y={0}
width={100}
height={100}
color="green"
transform={[
{ perspective: 500 },
{ rotateY: Math.PI / 6 },
]}
/>
</Canvas>
{ perspective: 500 }
{ rotateX: angle }
{ rotateY: angle }
{ rotateZ: angle }
{ translateZ: distance }
Examples
Rotate Around Center
const size = 100;
<Rect
x={0}
y={0}
width={size}
height={size}
color="purple"
origin={{ x: size / 2, y: size / 2 }}
transform={[{ rotate: Math.PI / 4 }]}
/>
<Rect
x={0}
y={0}
width={100}
height={100}
color="orange"
transform={[
{ translateX: 150 },
{ translateY: 150 },
{ rotate: Math.PI / 6 },
{ scale: 1.5 },
{ skewX: 0.2 },
]}
/>
import { useSharedValue, withRepeat, withTiming } from "react-native-reanimated";
import { Canvas, Rect } from "@shopify/react-native-skia";
export default function AnimatedTransform() {
const rotation = useSharedValue(0);
useEffect(() => {
rotation.value = withRepeat(
withTiming(Math.PI * 2, { duration: 2000 }),
-1
);
}, []);
return (
<Canvas style={{ flex: 1 }}>
<Rect
x={0}
y={0}
width={100}
height={100}
color="cyan"
origin={{ x: 50, y: 50 }}
transform={[{ rotate: rotation }]}
/>
</Canvas>
);
}
Matrix Composition
const matrix = Skia.Matrix();
matrix.translate(100, 100);
matrix.rotate(Math.PI / 4);
matrix.scale(2);
const path = Skia.Path.Make();
path.addRect(rect(0, 0, 50, 50));
const transformed = path.transform(matrix);
Helper Functions
Degrees to Radians
const degreesToRadians = (degrees: number) => (degrees * Math.PI) / 180;
const rotation = degreesToRadians(45);
Radians to Degrees
import { toDegrees } from "@shopify/react-native-skia";
const degrees = toDegrees(Math.PI / 4); // 45
- Reuse matrix objects instead of creating new ones
- Use
useMemo for static transforms
- Combine multiple operations in a single transform array
- For animations, use Reanimated shared values
- Avoid unnecessary transformations