How to Drag Matter.js Bodies with Touch
Capturing user touch gestures to drag physics bodies in Matter.js
requires integrating the Matter.Mouse and
Matter.MouseConstraint modules with your rendering canvas.
While Matter.js includes built-in touch listeners within its mouse
module, mobile browsers often intercept these gestures for scrolling,
zooming, or panning. This guide covers how to set up touch-based
interaction, sync coordinates accurately, and prevent mobile browser
gesture conflicts.
1. Create the Mouse and MouseConstraint
Matter.js treats mouse and touch inputs through the same abstraction
layer (Matter.Mouse). When you bind a mouse instance to a
canvas element, it automatically attaches both pointer/mouse event
listeners (mousedown, mousemove,
mouseup) and touch event listeners
(touchstart, touchmove,
touchend).
// Setup engine and renderer
const engine = Matter.Engine.create();
const render = Matter.Render.create({
element: document.body,
engine: engine,
canvas: document.getElementById('world'),
options: {
width: window.innerWidth,
height: window.innerHeight,
wireframes: false
}
});
// 1. Create the Mouse instance linked to the canvas
const mouse = Matter.Mouse.create(render.canvas);
// 2. Create the MouseConstraint
const mouseConstraint = Matter.MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2,
render: {
visible: false
}
}
});
// 3. Add the constraint to the world
Matter.Composite.add(engine.world, mouseConstraint);
// 4. Keep the mouse in sync with rendering
render.mouse = mouse;2. Disable Default Touch Actions via CSS
The most common reason touch dragging fails on mobile screens is that the browser captures the gesture for viewport scrolling before Matter.js can process it. You must disable standard touch behaviors on the canvas element.
Apply the touch-action CSS property directly to your
canvas:
canvas {
touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}Setting touch-action: none informs the browser that all
touch interactions inside the canvas should be handled exclusively by
JavaScript, preventing default scroll and pinch-to-zoom behaviors.
3. Account for Device Pixel Ratio and Scaling
On high-density mobile screens (Retina displays), mismatching dimensions between the canvas style width and its internal drawing buffer will misalign touch coordinates relative to the physics bodies.
Ensure your mouse pixel ratio matches the renderer:
// Adjust for mobile device pixel ratios
const pixelRatio = window.devicePixelRatio || 1;
mouse.pixelRatio = pixelRatio;If you dynamically resize the canvas or scale the viewport, call
Matter.Mouse.setScale or update
mouse.pixelRatio so that touch points accurately map to
body boundaries.
4. Prevent Page Scroll via Event Listeners (Fallback)
If legacy mobile browsers continue to scroll during touch interactions, explicitly prevent default behavior on the canvas touch events:
const canvas = render.canvas;
canvas.addEventListener('touchstart', (e) => {
e.preventDefault();
}, { passive: false });
canvas.addEventListener('touchmove', (e) => {
e.preventDefault();
}, { passive: false });Setting { passive: false } is required in modern
browsers to allow e.preventDefault() to stop viewport
movement.