How to Set a Custom Gravity Vector in Matter.js
In Matter.js, controlling the direction and strength of gravity allows you to create unique physics environments such as zero-gravity space simulations, inverted worlds, or sideways pulling forces. This guide explains how to define a global custom gravity vector directly on the engine instance and how to apply directional or radial gravity forces to individual bodies using update loops.
Defining Global Gravity on the Engine
Matter.js provides a built-in gravity object on the
Engine instance. The gravity vector consists of three
primary properties: x, y, and
scale.
By default, Matter.js sets gravity downwards along the Y-axis:
x:0y:1scale:0.001
1. Setting Gravity During Initialization
You can define the custom vector when instantiating the engine by
passing a gravity configuration in the
Engine.create() options:
const engine = Matter.Engine.create({
gravity: {
x: 0.5, // Pulls bodies to the right
y: -0.5, // Pulls bodies upward
scale: 0.001 // Strength multiplier
}
});2. Modifying Gravity at Runtime
If your engine is already running, you can modify the vector dynamically by updating the properties directly:
// Reverse gravity upside down
engine.gravity.y = -1;
// Create horizontal wind or sideways gravity
engine.gravity.x = 1;
engine.gravity.y = 0;
// Disable world gravity completely
engine.gravity.scale = 0;Creating Custom Per-Body Gravity
When you need non-uniform gravity—such as a planetary attraction point or individual gravity directions for specific objects—you should disable the global gravity and apply forces manually before each engine step.
Implementation Example:
const { Engine, Events, Body, Vector } = Matter;
const engine = Engine.create();
// Disable global gravity
engine.gravity.scale = 0;
// Define a custom force to apply continuously
Events.on(engine, 'beforeUpdate', () => {
const customGravity = { x: 0, y: -0.002 }; // Upward vector
// Apply to a specific body
Body.applyForce(myBody, myBody.position, customGravity);
});For radial or planetary gravity toward an attractor point:
Events.on(engine, 'beforeUpdate', () => {
const attractorPosition = { x: 400, y: 300 };
const G = 0.001; // Gravitational constant
bodies.forEach((body) => {
const force = Vector.sub(attractorPosition, body.position);
const distance = Vector.magnitude(force);
if (distance > 0) {
const normal = Vector.normalise(force);
const magnitude = (G * body.mass) / (distance * 0.05);
Body.applyForce(body, body.position, Vector.mult(normal, magnitude));
}
});
});