How to Implement Drag and Drop in Matter.js
Implementing drag-and-drop functionality in Matter.js allows users to
interact directly with physics bodies inside an HTML5 canvas. This guide
covers the essential steps to enable object dragging using Matter.js's
built-in Mouse and MouseConstraint modules,
providing a straightforward code implementation from initializing the
physics engine to capturing user input.
1. Include the Matter.js Library
Before writing JavaScript, load the Matter.js library into your HTML file via a CDN or bundle it using a package manager like npm:
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js"></script>2. Set Up the Engine, Renderer, and Runner
Initialize the core Matter.js modules: Engine,
Render, Runner, and
Composite.
const { Engine, Render, Runner, Bodies, Composite, Mouse, MouseConstraint } = Matter;
// Create an engine
const engine = Engine.create();
const world = engine.world;
// Create a renderer
const render = Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false
}
});
Render.run(render);
// Create runner
const runner = Runner.create();
Runner.run(runner, engine);3. Add Physics Bodies
Create dynamic bodies that can be dragged, along with static bodies to serve as boundaries (such as a floor and walls).
// Add boundaries (static bodies)
const ground = Bodies.rectangle(400, 590, 810, 30, { isStatic: true });
const leftWall = Bodies.rectangle(5, 300, 30, 600, { isStatic: true });
const rightWall = Bodies.rectangle(795, 300, 30, 600, { isStatic: true });
// Add draggable objects
const boxA = Bodies.rectangle(400, 200, 80, 80, { render: { fillStyle: '#e74c3c' } });
const boxB = Bodies.rectangle(450, 50, 80, 80, { render: { fillStyle: '#3498db' } });
const circle = Bodies.circle(380, 100, 40, { render: { fillStyle: '#2ecc71' } });
// Add all bodies to the world
Composite.add(world, [ground, leftWall, rightWall, boxA, boxB, circle]);4. Implement Mouse and MouseConstraint
The MouseConstraint module binds user mouse inputs
(click, drag, release) or touch inputs to bodies within the
simulation.
// Create a mouse input linked to the canvas
const mouse = Mouse.create(render.canvas);
// Create the mouse constraint
const mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2,
render: {
visible: true // Shows the drag line constraint
}
}
});
// Add the mouse constraint to the world
Composite.add(world, mouseConstraint);
// Keep the mouse in sync with rendering
render.mouse = mouse;5. Handling Events (Optional)
You can listen for interaction events emitted by
MouseConstraint to trigger custom behaviors, such as
logging when an item is grabbed or dropped:
Matter.Events.on(mouseConstraint, 'startdrag', (event) => {
console.log('Dragging body:', event.body);
});
Matter.Events.on(mouseConstraint, 'enddrag', (event) => {
console.log('Released body:', event.body);
});By linking Mouse.create() to the renderer canvas and
applying a MouseConstraint to the engine world, any
non-static Matter.js body automatically becomes interactive and
responsive to mouse clicks and touch dragging.