How to Scale a Body Dynamically in Matter.js

Matter.js fully supports dynamically scaling rigid bodies at runtime using its built-in physics methods. This article explains how to dynamically resize bodies using the Matter.Body.scale function, provides a direct code example for real-time scaling, and highlights essential considerations regarding mass recalculation, physics stability, and visual rendering.

Using the Body.scale Method

To scale a body dynamically, use the static method Matter.Body.scale(body, scaleX, scaleY, [point]). Rather than setting an absolute size, this function applies a relative multiplier to the body's current dimensions, vertices, and physical properties.

Code Example: Dynamic Scaling

The following example demonstrates scaling an existing body over time within the engine's update cycle:

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

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

// Create a renderer
const render = Render.create({
  element: document.body,
  engine: engine,
  options: { width: 800, height: 600, wireframes: false }
});

Render.run(render);
const runner = Runner.create();
Runner.run(runner, engine);

// Add a dynamic body
const box = Bodies.rectangle(400, 200, 80, 80);
Composite.add(world, box);

// Scale dynamically on every tick
let growing = true;
Events.on(engine, 'beforeUpdate', () => {
  const scaleFactor = growing ? 1.01 : 0.99;
  
  // Apply the scale to the body
  Body.scale(box, scaleFactor, scaleFactor);

  // Toggle growth bounds based on mass or area
  if (box.area > 20000) growing = false;
  if (box.area < 3000) growing = true;
});

Critical Considerations

1. Automatic Mass and Inertia Updates

When Body.scale() is invoked, Matter.js automatically recalculates the body's vertices, area, mass, and moment of inertia based on its existing density. If you require the body's mass to remain constant despite changing volume, manually reassign box.mass or adjust box.density immediately after scaling:

Body.scale(body, scaleX, scaleY);
Body.setMass(body, originalMass);

2. Collision and Tunneling Issues

Scaling a body too rapidly can cause its boundaries to expand directly into neighboring bodies. Because physics engines resolve penetrations with explosive separation impulses, sudden large scale changes can launch overlapping objects across the screen. To prevent physics glitches, scale objects gradually across multiple frames.

3. Compound Bodies

If you scale a compound body (a body formed by multiple parts), Body.scale() handles all child parts automatically, adjusting their relative positions and shapes relative to the primary center.

4. Custom Visual Synchronization

If you use a custom rendering pipeline (such as HTML5 Canvas, PixiJS, or Three.js) instead of the default Matter.js Render module, note that Body.scale modifies the body's vertex positions directly. You must update your visual sprite dimensions or scale matrices to match the updated physics bounds.