How to Resize a Rectangle in Matter.js
In Matter.js, rigid bodies do not have mutable width and
height properties that can be directly reassigned after
instantiation. This article provides a direct guide on how to resize an
existing rectangular body dynamically. You will learn how to adjust
dimensions using both relative scaling via
Matter.Body.scale and absolute dimension updates via
Matter.Body.setVertices.
Method 1: Using
Matter.Body.scale (Recommended)
The standard and most efficient way to resize an existing body in
Matter.js is by using the Body.scale method. This method
scales the body's vertices and automatically recalculates physical
properties such as area, inertia, and mass.
Because Matter.Body.scale requires scaling factors
(ratios) rather than absolute pixel values, you must calculate the ratio
of the target dimension relative to the current dimension.
const { Body } = Matter;
function resizeRectangle(body, newWidth, newHeight, currentWidth, currentHeight) {
const scaleX = newWidth / currentWidth;
const scaleY = newHeight / currentHeight;
// Apply scale to the body
Body.scale(body, scaleX, scaleY);
}Example Usage
Store the current dimensions alongside your body or in a custom wrapper object to accurately track size transitions over time:
// 1. Create a rectangle
const myRect = Matter.Bodies.rectangle(400, 200, 100, 50);
myRect.customWidth = 100;
myRect.customHeight = 50;
Matter.Composite.add(engine.world, myRect);
// 2. Resize to 200x80 later
const targetWidth = 200;
const targetHeight = 80;
Body.scale(myRect, targetWidth / myRect.customWidth, targetHeight / myRect.customHeight);
// Update tracked dimensions
myRect.customWidth = targetWidth;
myRect.customHeight = targetHeight;Method 2: Using
Matter.Body.setVertices
If your body has rotated, computing width and height via bounds can become inaccurate. Setting explicit vertices allows you to redefine the shape using absolute dimensions while preserving the body's current position and angle.
const { Body, Vertices } = Matter;
function setRectangleDimensions(body, width, height) {
// Define the new corners centered around (0, 0)
const halfWidth = width / 2;
const halfHeight = height / 2;
const newVertices = [
{ x: -halfWidth, y: -halfHeight },
{ x: halfWidth, y: -halfHeight },
{ x: halfWidth, y: halfHeight },
{ x: -halfWidth, y: halfHeight }
];
// Reapply vertices to the body
Body.setVertices(body, newVertices);
}Important Considerations When Resizing Bodies
- Collision Artifacts: Scaling a body while it is overlapping or touching other static or dynamic bodies can cause unexpected impulses or tunneling due to sudden overlap resolution.
- Mass and Inertia:
Body.scaleautomatically scales mass and inertia proportionally. If you useBody.setVertices, Matter.js recalculates mass and inertia based on the new geometry and original density. - Renderer Adjustments: If using
Matter.Render, the debug view will automatically reflect vertex changes. If using an external rendering engine (like PixiJS, Three.js, or HTML Canvas), ensure you update your visual asset's scale or transform origin to match the physics body.