How to Offset Parts in Matter.js Compound Bodies

This guide explains how to properly position and offset individual parts within a compound body in Matter.js. You will learn how the physics engine calculates the center of mass, how to position components relative to one another during creation, how to shift the rotation origin using Body.setCentre, and how to avoid common positional synchronization errors.

How Matter.js Handles Compound Bodies

When you create a compound body using Body.create({ parts: [...] }), Matter.js automatically recalculates the overall body's center of mass based on the shapes, positions, and densities of all included parts. It then re-indexes the internal positions of each part as relative offsets from this calculated center of mass.

Because the center of mass is recomputed automatically, trying to manually adjust an individual child part's position.x or position.y properties after creation will cause desynchronization and physics glitching.


Step 1: Define Parts in Relative World Space

The most straightforward way to offset parts is to place them at their intended relative coordinates before assembling the compound body:

// 1. Create the primary body (e.g., the base)
const base = Bodies.rectangle(100, 100, 100, 20, {
  render: { fillStyle: 'blue' }
});

// 2. Create the second part with an offset relative to the base
// For example, 40px to the right and 30px above the base center
const attachment = Bodies.circle(140, 70, 15, {
  render: { fillStyle: 'red' }
});

// 3. Assemble into a compound body
const compoundBody = Body.create({
  parts: [base, attachment]
});

// 4. Move the assembled compound body to its actual world location
Body.setPosition(compoundBody, { x: 400, y: 300 });

// 5. Add the compound body to the world
Composite.add(engine.world, compoundBody);

When Body.create runs, Matter.js balances base and attachment, calculates their combined center of mass, and sets their relative offsets permanently. Calling Body.setPosition afterward moves the entire assembly while keeping the relative offset intact.


Step 2: Custom Pivots and Center Offsets with Body.setCentre

If you require the compound body to rotate around a specific point—such as the center of base rather than the calculated center of mass—you can shift the origin using Body.setCentre:

// Shift the rotation origin by an offset (x, y)
// The third argument (relative = true) shifts the origin relative to the current center of mass
Body.setCentre(compoundBody, { x: -20, y: 10 }, true);

Using Body.setCentre updates the physics origin without altering the visual positions of the underlying parts in world space.


Updating Offsets Dynamically After Creation

If you must change the offset of a part after the compound body has already been added to the world, use Body.setParts:

  1. Update the positions of the child bodies using Body.setPosition(part, newWorldCoordinate).
  2. Call Body.setParts(compoundBody, [compoundBody, newPart]) (or pass the full updated array of parts).
  3. Matter.js will recalculate the mass, inertia, and relative offsets of all parts to match the new configuration.