Matter.js Detect Mouse Movement Without Dragging
This article explains how to capture continuous mouse movement across
a Matter.js canvas without requiring a click or drag action. By default,
Matter.js tracks pointer coordinates internally, but developers often
mistake the MouseConstraint module as strictly a
drag-and-drop tool. By accessing the underlying Mouse
instance and listening to Matter.js events, you can passively detect the
cursor's exact coordinates across the simulation space at any time.
Step 1: Initialize the Mouse and MouseConstraint
To capture mouse data in Matter.js, you must create a
Mouse instance linked to your renderer's canvas and attach
it to a MouseConstraint.
const { Engine, Render, Runner, Bodies, Composite, Mouse, MouseConstraint, Events } = Matter;
const engine = Engine.create();
const render = Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false
}
});
// Create mouse controller linked to the canvas
const mouse = Mouse.create(render.canvas);
const mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2,
render: { visible: false }
}
});
Composite.add(engine.world, mouseConstraint);
render.mouse = mouse;Step 2: Listen for the
mousemove Event
The MouseConstraint emits a mousemove event
whenever the cursor moves over the canvas element, regardless of whether
a mouse button is pressed.
Events.on(mouseConstraint, 'mousemove', function(event) {
const mousePosition = event.mouse.position;
console.log(`Mouse X: ${mousePosition.x}, Mouse Y: ${mousePosition.y}`);
});The coordinates in event.mouse.position automatically
account for canvas scaling and pixel ratios handled by Matter.js.
Step 3: Track Movement Passively Without Body Interaction
If you want to track mouse movement but prevent the mouse from
grabbing or dragging any physical bodies in the world, disable the
collision filter on the MouseConstraint:
const passiveMouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
collisionFilter: {
mask: 0x0000 // Disables interaction with all collision categories
}
});
Composite.add(engine.world, passiveMouseConstraint);
Events.on(passiveMouseConstraint, 'mousemove', function(event) {
const { x, y } = event.mouse.position;
// Perform actions based on coordinates without dragging bodies
});Alternative: Polling Coordinates Inside the Update Loop
If an event-driven approach is not required, you can directly query
mouse.position inside Matter.js's beforeUpdate
or afterUpdate engine lifecycle events:
Events.on(engine, 'afterUpdate', function() {
const currentX = mouse.position.x;
const currentY = mouse.position.y;
// Use current coordinates in real-time updates
});This method reads the latest cursor position on every tick of the physics engine without relying on separate input event listeners.