Handling Touch Events in Matter.js with Matter.Mouse

This article explains how to capture and process mobile touch inputs in Matter.js using the built-in Matter.Mouse and Matter.MouseConstraint modules. You will learn how to configure touch interactions for HTML5 canvas elements, prevent default mobile browser gestures from interfering with physics simulations, and properly scale touch coordinates for high-density mobile screens.

1. How Matter.Mouse Handles Touch

The Matter.Mouse module natively listens for both standard mouse events (mousedown, mousemove, mouseup) and touch events (touchstart, touchmove, touchend). When you bind a mouse instance to a canvas, Matter.js automatically maps single-finger touches to the primary pointer coordinates.

To enable user interaction with physical bodies, you pair Matter.Mouse with Matter.MouseConstraint.

2. Basic Setup Implementation

To initialize mobile touch support, create your engine, renderer, mouse, and mouse constraint in sequence:

// 1. Create engine and renderer
const engine = Matter.Engine.create();
const render = Matter.Render.create({
    element: document.body,
    engine: engine,
    options: {
        width: window.innerWidth,
        height: window.innerHeight,
        wireframes: false
    }
});

Matter.Render.run(render);
Matter.Runner.run(Matter.Runner.create(), engine);

// 2. Attach Matter.Mouse to the render canvas
const mouse = Matter.Mouse.create(render.canvas);

// 3. Create the MouseConstraint
const mouseConstraint = Matter.MouseConstraint.create(engine, {
    mouse: mouse,
    constraint: {
        stiffness: 0.2,
        render: {
            visible: false
        }
    }
});

// 4. Add the constraint to the world
Matter.Composite.add(engine.world, mouseConstraint);

// 5. Keep the mouse in sync with rendering
render.mouse = mouse;

3. Prevent Default Mobile Scrolling

By default, dragging a finger on a mobile screen triggers page scrolling or pull-to-refresh gestures, which cancels or interrupts the physics interaction. Prevent this behavior by applying CSS to the canvas element:

canvas {
    touch-action: none;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}

Setting touch-action: none ensures the browser delegates all touch handling directly to the canvas without interpreting gestures as navigation.

4. Handling High-DPI and Retina Displays

Mobile devices typically use high device pixel ratios (DPR). If you adjust the canvas dimensions to match window.devicePixelRatio, you must scale the Matter.Mouse coordinates accordingly to maintain alignment:

const pixelRatio = window.devicePixelRatio || 1;

// If scaling your renderer for retina screens:
render.options.pixelRatio = pixelRatio;

// Scale mouse input coordinates to match the render canvas
Matter.Mouse.setScale(mouse, {
    x: 1 / pixelRatio,
    y: 1 / pixelRatio
});

5. Listening to Touch Events Directly

If you need to trigger custom actions during touch interactions, listen directly to the mouseConstraint events:

Matter.Events.on(mouseConstraint, 'startdrag', function(event) {
    console.log('Body touched:', event.body);
});

Matter.Events.on(mouseConstraint, 'enddrag', function(event) {
    console.log('Touch released');
});