Skip to main content
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, y
const matrix = Skia.Matrix();
matrix.translate(50, 100);

Rotation

rotate
(radians: number) => SkMatrix
Rotates by angle in radians
const 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 radians
const matrix = Skia.Matrix();
matrix.skew(0.5, 0); // Skew horizontally

Concatenation

concat
(matrix: InputMatrix) => SkMatrix
Multiplies this matrix with another
const 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

identity
() => SkMatrix
Resets to identity matrix
matrix.identity();

Get Values

get
() => number[]
Returns the 9 matrix values as an array
const values = matrix.get();
console.log(values); // [1, 0, 0, 0, 1, 0, 0, 0, 1]

Using with Transforms

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>

Transform Types

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] }

Transform Origin

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>

3D Transforms (Matrix4)

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>

3D Transform Types

{ 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 }]}
/>

Combined Transformations

<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 },
  ]}
/>

Animated Transform

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

Performance Tips

  • 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

Build docs developers (and LLMs) love