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.

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.

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);