Prevent MouseConstraint from Grabbing Static Bodies
When building interactive simulations with Matter.js, you often want
users to drag dynamic objects while leaving scenery, boundaries, and
walls undisturbed. By default, mouse interactions can target or attempt
to interact with static bodies unless configured otherwise. This article
outlines the two most effective methods to prevent a
MouseConstraint from grabbing or targeting static bodies:
using collision filters and listening to the startdrag
event.
Method 1: Using Collision Filters (Recommended)
The most robust and performant way to restrict what a
MouseConstraint can touch is by using Matter.js collision
categories and masks. By assigning static bodies to a separate category,
you can explicitly tell the mouse constraint to ignore them.
const defaultCategory = 0x0001; // Dynamic objects
const staticCategory = 0x0002; // Walls, floors, and platforms
// 1. Assign the static category to your static body
const wall = Matter.Bodies.rectangle(400, 600, 800, 50, {
isStatic: true,
collisionFilter: {
category: staticCategory
}
});
// 2. Assign the default category to dynamic bodies
const box = Matter.Bodies.rectangle(400, 200, 80, 80, {
collisionFilter: {
category: defaultCategory
}
});
// 3. Configure the MouseConstraint mask to only interact with dynamic bodies
const mouse = Matter.Mouse.create(render.canvas);
const mouseConstraint = Matter.MouseConstraint.create(engine, {
mouse: mouse,
collisionFilter: {
mask: defaultCategory // Only interacts with bodies having defaultCategory
}
});
Matter.Composite.add(world, [wall, box, mouseConstraint]);By setting collisionFilter.mask to only match
defaultCategory, the MouseConstraint queries
will completely bypass any body assigned to
staticCategory.
Method 2:
Canceling Drag on the startdrag Event
If you prefer not to manage collision categories across your entire
simulation, you can intercept the drag event. Matter.js emits a
startdrag event whenever a body is clicked. You can check
if the targeted body is static and cancel the constraint
immediately.
const mouse = Matter.Mouse.create(render.canvas);
const mouseConstraint = Matter.MouseConstraint.create(engine, {
mouse: mouse
});
// Intercept drag initialization
Matter.Events.on(mouseConstraint, 'startdrag', function(event) {
if (event.body.isStatic) {
// Clear the body references to cancel the grab
mouseConstraint.body = null;
mouseConstraint.constraint.bodyB = null;
}
});
Matter.Composite.add(world, mouseConstraint);Setting mouseConstraint.body and
mouseConstraint.constraint.bodyB to null
prevents the mouse spring from attaching to the static object, leaving
it fully immobile.