How to Configure a Revolute Joint in Planck.js?
A Revolute Joint in planck.js (the
JavaScript rewrite of the Box2D physics engine) constrains two rigid
bodies to share a common anchor point, allowing them to rotate relative
to each other like a hinge. To configure it properly, you need to define
the two connecting bodies, establish a shared local or world anchor
point, and optionally enforce rotation limits or motor settings to
simulate realistic mechanical constraints. This guide covers the
essential initialization steps, code implementation, and advanced
parameters required to turn a basic joint into a fully functional
hinge.
Step 1: Initialize the Bodies and Joint Definition
Before creating the joint, you must have a world
instance and two Body objects already defined—typically a
static body (like a wall or post) and a dynamic body (like a door or
pendulum). The easiest way to configure a revolute joint is by using the
RevoluteJoint definition helper, which automatically
calculates the local anchor points based on a shared world
coordinate.
import { World, Vec2, RevoluteJoint } from 'planck';
const world = new World(new Vec2(0, -10));
// Body 1: The anchor/base (Static)
const ground = world.createBody({
position: new Vec2(0, 5)
});
// Body 2: The moving hinge piece (Dynamic)
const door = world.createBody({
type: 'dynamic',
position: new Vec2(2, 5)
});
// Define the common anchor point in world coordinates
const anchorPoint = new Vec2(0, 5);
// Create the joint definition
const jointDef = RevoluteJoint({}, ground, door, anchorPoint);
const hingeJoint = world.createJoint(jointDef);Step 2: Enforce Angle Limits
A standard hinge rarely rotates a full 360 degrees. To prevent your dynamic body from swinging infinitely, you can enable angle limits on the joint definition. These limits are measured in radians relative to the initial angle between the bodies when the joint was created.
enableLimit: A boolean flag to activate the constraints.lowerAngle: The minimum allowed rotation (in radians).upperAngle: The maximum allowed rotation (in radians).
const constrainedJointDef = RevoluteJoint({
enableLimit: true,
lowerAngle: -Math.PI / 4, // -45 degrees
upperAngle: Math.PI / 4, // +45 degrees
}, ground, door, anchorPoint);
const limitedHinge = world.createJoint(constrainedJointDef);Step 3: Add Motor Power (Optional)
If your hinge needs to be self-powered—like an automatic closing door or a robotic arm segment—you can enable the joint’s motor. This requires setting a target speed and a maximum torque so the motor doesn’t apply infinite force to reach its goal.
enableMotor: Activates the joint motor.motorSpeed: The desired angular velocity in radians per second (positive for counter-clockwise, negative for clockwise).maxMotorTorque: The maximum torque limit the motor can exert to achieve the target speed.
const motorizedJointDef = RevoluteJoint({
enableMotor: true,
motorSpeed: 2.0, // Fast rotational speed
maxMotorTorque: 100.0 // Resistance threshold
}, ground, door, anchorPoint);
const motorizedHinge = world.createJoint(motorizedJointDef);Step 4: Modifying the Hinge at Runtime
Once the joint is created, you can dynamically turn features on or off or adjust their values during the physics simulation loop using the joint instance methods.
// Change motor direction on the fly
hingeJoint.setMotorSpeed(-2.0);
// Disable the limits dynamically
hingeJoint.enableLimit(false);