How to Simulate a Spring in Matter.js
This article explains how to simulate a physical spring in the Matter.js 2D physics engine using constraints. By modifying key constraint properties such as stiffness, damping, and length, you can transform rigid joints into elastic, oscillating connections. The following guide covers the essential parameters, provides a direct code implementation, and offers tips for tuning spring behavior.
Understanding Constraints as Springs
In Matter.js, a constraint connects two physics bodies, or one body
to a fixed point in the world. By default, constraints act as rigid rods
with a stiffness value of 1. To create a
spring, you must lower the stiffness so the constraint can stretch and
compress, and configure damping to control how quickly the oscillation
settles.
Key Properties for Spring Behavior
bodyAandbodyB: The two physics bodies linked by the constraint. If connecting to a fixed coordinate, setbodyAto the body andpointBto a static vector{ x, y }.length: The rest length (equilibrium position) of the spring. When displaced, the constraint exerts force to return to this length.stiffness: A value typically between0and1. A value of1represents a completely rigid link, while lower values (e.g.,0.01to0.1) allow elasticity, mimicking a spring.damping: A value that introduces resistance to motion, preventing the spring from oscillating indefinitely. Higher values cause the spring to settle faster.
Implementation Example
Below is a complete implementation demonstrating a dynamic body suspended from a fixed anchor point using a spring constraint:
const { Engine, Render, Runner, Bodies, Composite, Constraint } = Matter;
// Create engine and world
const engine = Engine.create();
const world = engine.world;
// Create renderer
const render = Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false
}
});
// 1. Create the moving body (the weight on the spring)
const bob = Bodies.circle(400, 300, 30, {
density: 0.005,
render: { fillStyle: '#e74c3c' }
});
// 2. Create the spring constraint
const spring = Constraint.create({
pointA: { x: 400, y: 100 }, // Fixed anchor point in the world
bodyB: bob, // Attached dynamic body
pointB: { x: 0, y: 0 }, // Attachment offset on the body
length: 150, // Target resting length
stiffness: 0.05, // Low stiffness enables stretching
damping: 0.02, // Controls oscillation decay
render: {
strokeStyle: '#2ecc71',
lineWidth: 3
}
});
// Add items to the world and run
Composite.add(world, [bob, spring]);
Render.run(render);
Runner.run(Runner.create(), engine);Connecting Two Moving Bodies
To connect two independent moving bodies with a spring, define both
bodyA and bodyB:
const bodyA = Bodies.rectangle(350, 200, 40, 40);
const bodyB = Bodies.rectangle(450, 200, 40, 40);
const springBetweenBodies = Constraint.create({
bodyA: bodyA,
bodyB: bodyB,
length: 100,
stiffness: 0.03,
damping: 0.01
});
Composite.add(world, [bodyA, bodyB, springBetweenBodies]);Tuning Spring Dynamics
- For high bounce (undamped oscillation): Keep
dampingnear0(e.g.,0.001) and use a moderatestiffness(e.g.,0.05). - For a stiff suspension (e.g., a vehicle axle): Use
a higher
stiffness(e.g.,0.3to0.6) with a moderatedamping(e.g.,0.1) to avoid abrupt snapping. - Preventing instability: Very low stiffness paired
with high body velocities or large masses can cause numerical
instability in the solver. Adjust
engine.positionIterationsandengine.velocityIterationsto higher values if the simulation behaves erratically.