How to Offset a Sprite Texture in Matter.js

This article explains how to correctly align and offset sprite textures on rigid bodies in Matter.js. By default, Matter.js centers an attached sprite image directly over the body's center of mass, which can cause visual misalignment if your graphic has uneven padding or an off-center focal point. Below, you will learn which built-in properties control texture positioning, how the offset values function, and how to apply them directly in your code.

Understanding Sprite Offsets in Matter.js

When using the built-in Matter.js renderer (Matter.Render), textures are assigned using the render.sprite configuration object. Positioning of the image relative to the body is handled by two properties:

These offsets are defined as normalized ratios of the image's original dimensions, not absolute pixel values. The default value for both properties is 0.5, which places the geometric center of the image directly at the position of the physics body.

Applying Offsets During Body Creation

To define offsets when instantiating a physics body, include xOffset and yOffset inside the render.sprite definition within the body options:

const { Bodies } = Matter;

const boxWithSprite = Bodies.rectangle(400, 200, 80, 80, {
  render: {
    sprite: {
      texture: './assets/character.png',
      xScale: 1,
      yScale: 1,
      xOffset: 0.6, // Shifts the texture horizontally
      yOffset: 0.4  // Shifts the texture vertically
    }
  }
});

Updating Offsets Dynamically

If you need to change the sprite alignment at runtime—such as during animation state changes or directional flips—you can modify the properties directly on the body instance:

// Shift the texture further to the right
boxWithSprite.render.sprite.xOffset = 0.35;

// Shift the texture downward
boxWithSprite.render.sprite.yOffset = 0.25;

Calculating Pixel-Exact Offsets

Because Matter.js uses proportional multipliers instead of pixel offsets, calculate the offset value using the source image's dimensions:

xOffset = desiredPixelAnchorX / imageSourceWidth;
yOffset = desiredPixelAnchorY / imageSourceHeight;

For instance, if you have an image that is 200 pixels wide and the collision point needs to be anchored at pixel 120, set xOffset to 120 / 200, which equals 0.6.