Set an Image as a Sprite Texture in Matter.js

This guide explains how to apply an image as a visual sprite texture to a rigid body using the built-in Matter.js renderer. By configuring the render.sprite property on a body, you can replace default wireframe or solid color shapes with custom PNG, JPEG, or SVG graphics. Below are the steps, code examples, and scaling formulas required to ensure your visual texture aligns accurately with the underlying physical collider.

Configuring the Sprite Property

When creating a body with Matter.Bodies, supply a render.sprite object inside the options parameter. The essential property is texture, which accepts a relative path or absolute URL pointing to your image file.

const box = Matter.Bodies.rectangle(400, 200, 100, 100, {
  render: {
    sprite: {
      texture: './assets/crate.png'
    }
  }
});

Matter.Composite.add(engine.world, box);

Complete Implementation Example

To see the sprite rendered, ensure wireframes is set to false in your Matter.Render configuration, as wireframe mode hides all custom textures.

const { Engine, Render, Runner, Bodies, Composite } = Matter;

// 1. Initialize engine and world
const engine = Engine.create();

// 2. Initialize renderer
const render = Render.create({
  element: document.body,
  engine: engine,
  options: {
    width: 800,
    height: 600,
    wireframes: false, // Required for sprites to display
    background: '#fafafa'
  }
});

Render.run(render);
Runner.run(Runner.create(), engine);

// 3. Create a body with an image texture
const crate = Bodies.rectangle(400, 100, 80, 80, {
  render: {
    sprite: {
      texture: 'https://example.com/crate.png',
      xScale: 1,
      yScale: 1
    }
  }
});

const ground = Bodies.rectangle(400, 590, 810, 60, { isStatic: true });

Composite.add(engine.world, [crate, ground]);

Scaling the Sprite to Match the Body

Matter.js renders textures at their native pixel dimensions by default. If the source image dimensions do not match the physics body's width and height, the visual graphic will not align with the collision boundaries.

Use xScale and yScale within the sprite object to scale the image:

const targetWidth = 100;
const targetHeight = 100;
const imageNativeWidth = 512;
const imageNativeHeight = 512;

const scaledBody = Bodies.rectangle(200, 200, targetWidth, targetHeight, {
  render: {
    sprite: {
      texture: 'https://example.com/large-icon.png',
      xScale: targetWidth / imageNativeWidth,
      yScale: targetHeight / imageNativeHeight
    }
  }
});

Offsetting the Sprite

If the collision boundary needs to be centered differently from the image center, apply xOffset and yOffset. The default offset value is 0.5 for both axes, which aligns the center of the image with the center of mass of the physics body. Adjusting these values shifts the anchor point relative to the image's total dimensions.