Create a Newton's Cradle with Matter.js
This guide explains how to quickly build a realistic Newton's cradle
simulation using Matter.js and its specialized composite helper,
Matter.Composites.newtonCradle. You will learn how to
configure the engine, initialize the cradle with custom physical
dimensions, add interactive controls, and tune collision properties to
achieve an accurate kinetic motion effect.
Understanding
Matter.Composites.newtonCradle
Matter.js provides a built-in composite function specifically designed to generate a Newton's cradle assembly. The function signature is:
Matter.Composites.newtonCradle(xx, yy, number, size, length)xx: The X-coordinate for the center point of the top suspension beam.yy: The Y-coordinate for the top suspension beam.number: The total count of suspended balls (typically 5).size: The radius of each ball in pixels.length: The length of the suspension strings in pixels.
Internally, this method automatically creates the circular bodies and
attaches them to static anchor points using
Matter.Constraint instances.
Step-by-Step Implementation
1. Initialize the Matter.js Modules
First, alias the core Matter.js modules for convenience:
const {
Engine,
Render,
Runner,
Composites,
Composite,
Mouse,
MouseConstraint,
Body
} = Matter;2. Create the Engine and Renderer
Create an engine to manage the physics updates and a renderer to draw the simulation to an HTML canvas:
const engine = Engine.create();
const world = engine.world;
const render = Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false,
background: '#1a1a1a'
}
});
Render.run(render);
const runner = Runner.create();
Runner.run(runner, engine);3. Instantiate the Newton's Cradle
Generate the cradle composite and add it to the physics world:
const cradle = Composites.newtonCradle(280, 100, 5, 30, 300);
Composite.add(world, cradle);4. Trigger the Initial Motion
In a real Newton's cradle, the motion begins when one ball is pulled back and released. To replicate this automatically on startup, displace the first ball:
// Displace the leftmost ball along the X and Y axes
Body.translate(cradle.bodies[0], { x: -180, y: -100 });5. Add Mouse Interaction (Optional)
Allow users to grab and pull any ball manually using a mouse constraint:
const mouse = Mouse.create(render.canvas);
const mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2,
render: {
visible: false
}
}
});
Composite.add(world, mouseConstraint);
render.mouse = mouse;Tuning Physics for Maximum Realism
By default, Matter.js bodies lose kinetic energy due to air resistance and inelastic collisions. To make your Newton's cradle swing back and forth for longer periods:
- Restitution (Bounciness): The default balls
generated by
Composites.newtonCradlehave a restitution value of1(perfectly elastic). Avoid reducing this value. - Air Resistance: Set
frictionAirto zero across all bodies in the cradle to eliminate drag:
cradle.bodies.forEach((ball) => {
ball.frictionAir = 0;
ball.friction = 0;
ball.restitution = 1;
});- Collision Precision: Increase the engine solver iterations if you observe balls clipping through one another during high-velocity impacts:
engine.positionIterations = 10;
engine.velocityIterations = 10;