How to Create Matter.js Bodies from SVG Paths

Generating a Matter.js physics body from an SVG path allows developers to build complex, custom rigid bodies beyond simple primitives like circles and rectangles. This article provides a concise, step-by-step guide explaining how to convert vector paths into physics vertices, decompose non-convex shapes using external helper libraries, and instantiate a functional rigid body inside the Matter.js physics simulation.

1. Install and Load Required Dependencies

Matter.js requires external libraries to parse complex SVG paths and handle concave polygons. Before generating bodies, you must include:

<script src="https://cdn.jsdelivr.net/npm/pathseg@1.2.1/pathseg.js"></script>
<script src="https://cdn.jsdelivr.net/npm/poly-decomp@0.3.0/build/decomp.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/matter-js@0.19.0/build/matter.min.js"></script>

2. Extract the SVG Path Element

Load or locate the SVG path inside the DOM. If your SVG is an external file, fetch it via fetch() and parse it using DOMParser. If it is already rendered in the HTML, target it directly using a standard selector.

const pathElement = document.querySelector('#my-svg-path');

Alternatively, you can dynamically create the element:

const pathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
pathElement.setAttribute('d', 'M 0 0 L 100 0 L 100 100 L 0 100 Z');

3. Convert the Path to Vertices

Matter.js provides a built-in utility named Matter.Svg.pathToVertices(). This method samples points along the vector path and converts them into an array of 2D vertex objects ({ x, y }).

// sampleLength determines the resolution/number of points (lower = higher fidelity, higher CPU cost)
const sampleLength = 15; 
const vertices = Matter.Svg.pathToVertices(pathElement, sampleLength);

4. Construct the Rigid Body

Pass the generated vertices to Matter.Bodies.fromVertices(). This function relies on poly-decomp to automatically split any concave shape into convex sub-bodies, combining them into a single compound body.

const x = 400; // X position in the world
const y = 300; // Y position in the world

const body = Matter.Bodies.fromVertices(x, y, [vertices], {
    isStatic: false,
    render: {
        fillStyle: '#2e86de',
        strokeStyle: '#ffffff',
        lineWidth: 1
    }
}, true); // The final boolean flag enables vertex optimization

5. Add the Body to the Simulation

Finally, add the instantiated body to your Matter.js engine's world composite.

Matter.Composite.add(engine.world, body);

Key Considerations