Restrict Body Rotation on Matter.js Constraints
In Matter.js, rigid bodies attached to constraints naturally rotate around their attachment points under gravity and applied forces. This guide explains how to restrict or completely eliminate this rotation using three primary techniques: setting the body's inertia to infinity, utilizing dual constraints to lock the orientation, and clamping the rotation angle using engine update events.
Method 1: Set Body Inertia to Infinity
The most direct way to prevent a body from rotating while still allowing it to translate along a constraint is to set its rotational inertia to infinity. This makes the body immune to torque and rotational forces.
You can apply this property during the creation of the body:
const body = Matter.Bodies.rectangle(x, y, width, height, {
inertia: Infinity,
inverseInertia: 0
});If the body already exists in your simulation, use the
Body.setInertia utility function:
Matter.Body.setInertia(body, Infinity);While this permanently locks the body's angle to its initial value, the constraint will still permit linear movement (such as swinging or sliding) based on how the constraint is anchored.
Method 2: Use Dual Constraints
If you want to restrict rotation relative to another body or fixed anchor without freezing the body's absolute inertia, attach two constraints with an offset distance. A single constraint acts as a pivot, whereas two parallel constraints form a rigid link that cancels out rotational freedom.
const constraintA = Matter.Constraint.create({
bodyA: bodyA,
pointA: { x: -20, y: 0 },
bodyB: bodyB,
pointB: { x: -20, y: 0 },
stiffness: 1
});
const constraintB = Matter.Constraint.create({
bodyA: bodyA,
pointA: { x: 20, y: 0 },
bodyB: bodyB,
pointB: { x: 20, y: 0 },
stiffness: 1
});
Matter.Composite.add(world, [constraintA, constraintB]);By separating the anchor points horizontally or vertically, the body is forced to maintain the orientation defined by the two parallel connections.
Method 3: Clamp the Angle via Engine Events
When you need to limit rotation within a specific degree range rather
than locking it completely, modify the body's angle in the
beforeUpdate event.
Matter.Events.on(engine, 'beforeUpdate', () => {
const minAngle = -Math.PI / 4; // -45 degrees
const maxAngle = Math.PI / 4; // 45 degrees
if (body.angle < minAngle) {
Matter.Body.setAngle(body, minAngle);
Matter.Body.setAngularVelocity(body, 0);
} else if (body.angle > maxAngle) {
Matter.Body.setAngle(body, maxAngle);
Matter.Body.setAngularVelocity(body, 0);
}
});Resetting the angular velocity to zero when hitting a boundary prevents the body from accumulating rotational energy against the restricted limit.