How to Detect Off-Screen Bodies in Matter.js
This article explains how to detect and trigger events when physics bodies leave the visible canvas bounds in Matter.js. Since the physics engine does not include a native "out-of-bounds" event listener, you must track body coordinates using the engine's update cycle and fire a custom callback when an object exceeds your defined boundaries.
The Standard Detection Approach
Matter.js operates on an update loop. To check whether a body has
left the screen, you attach an event listener to the engine's
afterUpdate event. During each tick, you iterate over the
active bodies in the world and compare their positions against the
canvas dimensions.
const { Engine, Events, Composite } = Matter;
// Define your visible screen boundaries
const viewWidth = 800;
const viewHeight = 600;
// Listen for the engine's afterUpdate event
Events.on(engine, 'afterUpdate', () => {
const bodies = Composite.allBodies(engine.world);
for (let i = 0; i < bodies.length; i++) {
const body = bodies[i];
// Ignore static bodies like terrain or boundaries
if (body.isStatic) continue;
// Check if the body's center point has left the view
if (
body.position.x < 0 ||
body.position.x > viewWidth ||
body.position.y < 0 ||
body.position.y > viewHeight
) {
triggerOutOfBoundsEvent(body);
}
}
});
function triggerOutOfBoundsEvent(body) {
// Dispatch a standard DOM event or run custom logic
window.dispatchEvent(new CustomEvent('bodyOutOfBounds', { detail: { body } }));
// Frequently, you will want to remove the body to prevent memory leaks
Composite.remove(engine.world, body);
}Checking Precise
Boundaries Using body.bounds
Using body.position checks only the central origin point
of the body. If you need to ensure the entire shape is completely
outside the visible screen before triggering the event, use the
body.bounds property (which contains min and
max vectors representing the body's axis-aligned bounding
box).
const isFullyOffScreen =
body.bounds.max.x < 0 ||
body.bounds.min.x > viewWidth ||
body.bounds.max.y < 0 ||
body.bounds.min.y > viewHeight;
if (isFullyOffScreen) {
triggerOutOfBoundsEvent(body);
}Best Practices
- Clean Up Removed Bodies: If bodies falling
off-screen are no longer needed, always remove them from the physics
world using
Composite.remove(engine.world, body). Leaving untracked bodies falling infinitely into the void will continually consume CPU resources. - Filter Unnecessary Bodies: Skip checking static
bodies (
body.isStatic) or sensors to minimize performance overhead during each physics step. - Buffer Margins: If you spawn bodies just off-screen
to enter the viewport, add a padding margin to the coordinate checks
(e.g.,
body.position.y > viewHeight + 100) so you do not prematurely trigger removal events on incoming bodies.