Matter.js MouseConstraint Collision Filtering

This guide explains how to use collision filters with a MouseConstraint in Matter.js to control which physics bodies the user can interact with. By assigning bitmask categories and masks to both your rigid bodies and the mouse constraint, you can restrict dragging behavior to specific elements while ignoring static boundaries, background items, or UI layers.

Understanding Collision Categories and Masks

Matter.js uses 32-bit integer bitmasks to define collision rules via the collisionFilter object:

For interaction filtering, defining distinct category and mask bitmasks is the most reliable approach.

Defining Interaction Groups

Start by defining your collision categories as bit flags:

const CATEGORY_DEFAULT = 0x0001; // Static boundaries, ground, UI
const CATEGORY_INTERACTIVE = 0x0002; // Objects the user can drag
const CATEGORY_PASSIVE = 0x0004; // Physics objects that should not be dragged

Applying Filters to Rigid Bodies

Assign the appropriate categories to the bodies in your world. For example, give movable bodies the CATEGORY_INTERACTIVE flag:

const draggableBox = Matter.Bodies.rectangle(400, 200, 80, 80, {
  collisionFilter: {
    category: CATEGORY_INTERACTIVE,
    mask: CATEGORY_DEFAULT | CATEGORY_INTERACTIVE | CATEGORY_PASSIVE,
  },
});

const ground = Matter.Bodies.rectangle(400, 600, 810, 60, {
  isStatic: true,
  collisionFilter: {
    category: CATEGORY_DEFAULT,
    mask: CATEGORY_INTERACTIVE | CATEGORY_PASSIVE,
  },
});

Configuring the MouseConstraint

When creating the MouseConstraint, provide a collisionFilter inside its options object. Set its mask to match only the categories you want the mouse to grab:

const mouse = Matter.Mouse.create(render.canvas);

const mouseConstraint = Matter.MouseConstraint.create(engine, {
  mouse: mouse,
  constraint: {
    stiffness: 0.2,
    render: {
      visible: false,
    },
  },
  collisionFilter: {
    category: CATEGORY_DEFAULT,
    mask: CATEGORY_INTERACTIVE, // Only bodies with CATEGORY_INTERACTIVE will be picked up
  },
});

Matter.Composite.add(engine.world, mouseConstraint);

Dynamic Updating

You can change the MouseConstraint collision filter at runtime if your game or application state changes:

// Temporarily disable all dragging
mouseConstraint.collisionFilter.mask = 0x0000;

// Re-enable dragging for interactive bodies
mouseConstraint.collisionFilter.mask = CATEGORY_INTERACTIVE;

By ensuring the MouseConstraint.collisionFilter.mask matches only the category bits of intended bodies, you prevent the cursor from grabbing background walls, static floors, or restricted simulation elements.