How to Pause a Matter.js Simulation

Pausing a Matter.js physics simulation is a standard requirement for web games and interactive canvas applications. This guide explains how to halt and resume the simulation using Matter.js's built-in Runner module as well as through a custom animation loop, providing clean and reusable code snippets for both approaches.

Method 1: Using Matter.Runner.stop and Matter.Runner.start

The standard way to run a Matter.js simulation is with the Matter.Runner module. To pause the simulation, pass the runner instance to Matter.Runner.stop(). To resume, call Matter.Runner.start() with both the runner and the engine.

// Setup
const engine = Matter.Engine.create();
const runner = Matter.Runner.create();

// Start the simulation
Matter.Runner.run(runner, engine);

let isPaused = false;

function togglePause() {
  if (isPaused) {
    // Resume simulation
    Matter.Runner.start(runner, engine);
    isPaused = false;
  } else {
    // Pause simulation
    Matter.Runner.stop(runner);
    isPaused = true;
  }
}

Method 2: Toggling the runner.enabled Property

If you prefer not to call start and stop explicitly, you can toggle the enabled boolean property on the runner instance. When set to false, the runner temporarily stops stepping the engine forward.

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

// Pause
runner.enabled = false;

// Resume
runner.enabled = true;

Method 3: Pausing a Custom requestAnimationFrame Loop

If your project does not use Matter.Runner and instead steps the engine manually using requestAnimationFrame, pause the physics by conditionally executing Matter.Engine.update().

const engine = Matter.Engine.create();
let isPaused = false;

function loop(time) {
  if (!isPaused) {
    // Step the simulation forward by 16.66ms (approx. 60fps)
    Matter.Engine.update(engine, 1000 / 60);
  }

  // Your custom rendering or game logic here

  requestAnimationFrame(loop);
}

requestAnimationFrame(loop);

// Control functions
function pause() {
  isPaused = true;
}

function resume() {
  isPaused = false;
}

Using this approach keeps the browser render loop active—allowing UI animations or menu transitions to continue—while freezing the physics bodies in place.