How Matter.js Render Draws Objects to Canvas
The built-in Matter.js render module (Matter.Render) is
an HTML5 Canvas-based visualization tool designed to display the state
of a physics simulation. This article breaks down the rendering pipeline
of Matter.js, explaining how the engine manages the render loop, reads
vertex and positional data from physical bodies, applies visual styling
and sprite textures, and executes standard 2D canvas drawing commands on
each frame.
The Render Loop
The drawing process begins with
Matter.Render.run(render), which sets up an animation loop
powered by the browser's native requestAnimationFrame API.
On every frame, the renderer calls Render.world(render),
which synchronizes the visual display with the underlying
Matter.Composite containing all simulated entities.
Before drawing begins, the renderer clears the entire canvas area
using context.clearRect(). If a custom viewport or camera
bounds are defined, the renderer computes the necessary scaling and
translation offsets and applies them to the canvas 2D rendering context
using context.setTransform().
Traversing the World Hierarchy
Once the canvas is cleared and transformed, Render.world
traverses the bodies, constraints, and composite structures present in
the physics engine. It processes these elements in a specific visual
order:
- Background clearing and background image rendering (if defined).
- Physical bodies (
Matter.Body). - Constraints and joints (
Matter.Constraint). - Optional debug overlays (such as collision points, broadphase bounds, axes, and velocity vectors).
Drawing Bodies and Geometry
For each body in the world, the renderer verifies whether
body.render.visible is set to true. If
visible, it evaluates whether to draw a vector shape or an image
sprite.
1. Vector and Polygon Rendering
If no sprite is assigned (or if
render.options.wireframes is set to true), the
renderer draws the body's geometric paths directly:
- Vertex Path Construction: Every body in Matter.js
contains an array of calculated vertices (
body.vertices) that represent its current position and rotation in world space. The renderer opens a new path withcontext.beginPath()and moves to the first vertex usingcontext.moveTo(vertices[0].x, vertices[0].y). - Connecting Vertices: It loops through all remaining
vertices, adding lines via
context.lineTo(vertex.x, vertex.y), and seals the shape withcontext.closePath(). - Styling and Fill: The renderer applies color styles
defined in
body.render.fillStyle,body.render.strokeStyle, andbody.render.lineWidth. If wireframe mode is enabled, it ignores body-specific colors and renders thin stroke outlines using predefined debug colors. - Primitive Optimization: For purely circular bodies
(
body.circleRadius), the renderer can bypass the vertex loop and usecontext.arc()directly at the body'sposition.xandposition.y.
2. Sprite Rendering
When a texture is specified in
body.render.sprite.texture, the module draws an image
instead of raw vector outlines:
- Image Retrieval: The renderer retrieves the
pre-loaded HTML
Imageelement from its internal texture cache. - Canvas Transformation: To align the sprite with the
body's physics state, the renderer saves the context state
(
context.save()), shifts the origin to the body's current coordinates usingcontext.translate(body.position.x, body.position.y), and rotates the context to matchbody.angleusingcontext.rotate(body.angle). - Drawing the Image: The sprite is drawn using
context.drawImage(), offset by its defined anchor points (xOffset,yOffset) and scaled according toxScaleandyScale. - Restoration: The context is restored to its default
orientation via
context.restore().
Drawing Constraints and Debug Information
After bodies are drawn, the module renders constraints. For simple
spring or rigid connections, the renderer reads
constraint.pointA and constraint.pointB
(resolving them to world coordinates if attached to bodies) and draws a
line between the two anchors using context.moveTo() and
context.lineTo().
If diagnostic options are enabled in render.options—such
as showVelocity, showCollisions, or
showAxes—the module iterates over active engine data
structures to draw supplementary visual aids:
- Axes: Lines drawn from body centers along their orientation vectors to indicate rotation.
- Velocities: Vectors projected from body centroids
proportional to
body.velocity. - Collisions: Markers drawn at
collision.supportswhere contact points exist between intersecting shapes.
Through this cycle of clearing, transforming coordinates, iterating over geometry, and applying native 2D canvas strokes and textures, the Matter.js render module transforms mathematical simulation data into an interactive visual output.