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:
category: A 32-bit integer defining the group the object belongs to. Each unique category is typically a power of two (e.g.,0x0001,0x0002,0x0004).mask: A 32-bit bitmask defining which categories the object can interact with.group: A signed integer that overrides category/mask rules when non-zero. If two bodies share a positive group value, they always collide; if negative, they never collide.
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 draggedApplying 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.