Create a Revolute Joint Hinge in Matter.js
This guide explains how to construct a revolute joint, commonly known
as a hinge or pin joint, using the Matter.js 2D physics engine. You will
learn the mechanics behind using the Matter.Constraint
module to lock two points together in space, how to anchor a dynamic
body to a fixed point in the world, and how to connect two moving bodies
at a shared pivot point.
Understanding Revolute Joints in Matter.js
Matter.js does not have a dedicated RevoluteJoint class.
Instead, revolute joints are built using Matter.Constraint.
A revolute joint is essentially a constraint configured with a
length of 0 and a high stiffness
(typically 1). This locks the anchor point of one object to
the anchor point of another while allowing full rotational freedom
around that shared pivot.
Method 1: Pinning a Body to a Fixed World Position
To create a hinge like a pendulum or a swinging trapdoor anchored to the world, connect a dynamic body to an absolute coordinate without a second body.
const { Engine, Render, Runner, Bodies, Composite, Constraint } = Matter;
// Create engine and world
const engine = Engine.create();
const world = engine.world;
// 1. Create a dynamic body to serve as the swinging arm
const arm = Bodies.rectangle(400, 300, 200, 20, {
collisionFilter: { group: -1 } // Optional: prevent self-collision
});
// 2. Create the revolute joint constraint
const hinge = Constraint.create({
pointA: { x: 400, y: 200 }, // Fixed point in world space
bodyB: arm, // The body attached to the hinge
pointB: { x: -90, y: 0 }, // Offset from arm's center (near the left edge)
length: 0, // Zero distance creates a direct pivot
stiffness: 1 // Fully rigid connection
});
// Add bodies to the world
Composite.add(world, [arm, hinge]);Method 2: Connecting Two Dynamic Bodies with a Shared Hinge
To connect two moving objects together—such as two links in a chain
or a ragdoll's elbow—you assign both bodyA and
bodyB. The hinge forms where their respective offset points
align.
// 1. Create two dynamic bodies
const upperArm = Bodies.rectangle(300, 200, 100, 20);
const forearm = Bodies.rectangle(380, 200, 100, 20);
// 2. Connect the right edge of upperArm to the left edge of forearm
const elbowJoint = Constraint.create({
bodyA: upperArm,
pointA: { x: 45, y: 0 }, // Near right edge of upperArm
bodyB: forearm,
pointB: { x: -45, y: 0 }, // Near left edge of forearm
length: 0,
stiffness: 1
});
Composite.add(world, [upperArm, forearm, elbowJoint]);Key Configuration Properties
pointAandpointB: WhenbodyAorbodyBis omitted, the point refers to absolute world coordinates. When a body is specified, the point acts as a relative offset from that body's center of mass.length: 0: Keeps the hinge points completely flush against each other.stiffness: 1: Ensures the hinge does not stretch under heavy loads or high velocities. Lower values will make the joint behave like an elastic tether instead of a solid hinge.damping: 0: By default, rotation around the hinge is frictionless. To simulate mechanical friction, adjust the body'sfrictionAiror apply manual rotational damping on update ticks.