How to make minimal example of matter.js work?
Asked Answered
C

4

8

I'm trying to use the matter.js physics library. I'm using their "getting started" tutorial, but it can't find the canvas.

Here is my html:

<html>
<head>
<meta charset="UTF-8">
<title>Physics test</title>
</head>
<script type="text/javascript" src="./lib/matter-0.8.0.js"></script>
<script type="text/javascript">
// Matter.js module aliases
var Engine = Matter.Engine,
    World = Matter.World,
    Bodies = Matter.Bodies;

// create a Matter.js engine
var engine = Engine.create(document.body);

// create two boxes and a ground
var boxA = Bodies.rectangle(400, 200, 80, 80);
var boxB = Bodies.rectangle(450, 50, 80, 80);
var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });

// add all of the bodies to the world
World.add(engine.world, [boxA, boxB, ground]);

// run the engine
Engine.run(engine);
</script>
<body>
</body>
</html>

The console shows the following error:

" [Matter] warn: No "render.element" passed, "render.canvas" was not inserted into document."

I tried to create the render.element and render.canvas, but I'm acting blindly. A "minimal example to get you started" should be already working. What am I doing wrong?

Cripple answered 21/1, 2015 at 23:58 Comment(1)
Make sure the script is at the bottom of the page (or called on the window load event, or after DOM is ready).Aurochs
C
6

Taking off part by part of the demo, I found out that most of the code should be in a function, called in the page load, like:

<body onload='Start()'>

and

function Start() {
    // create a Matter.js engine
    var engine = Engine.create(document.getElementById('canvas-container'));

    // create two boxes and a ground
    var boxA = Bodies.rectangle(400, 200, 80, 80);
    var boxB = Bodies.rectangle(450, 50, 80, 80);
    var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });

    // add all of the bodies to the world
    World.add(engine.world, [boxA, boxB, ground]);

    // run the engine
    Engine.run(engine);
}
Cripple answered 22/1, 2015 at 2:1 Comment(0)
D
3

Well document.body exists in the browser console, but not in JavaScript.

You can use document.querySelector("body") instead.

The error probably comes because you passed undefined to Engine.create(), as document.body returns undefined.

Also, make sure you execute your code after the window.onload event, so that all the HTMLElements have been loaded. Like this:

window.addEventListener("load",init);
function init(){
    var body = document.querySelector("body");
    // Matter.js module aliases
    var Engine = Matter.Engine,
    World = Matter.World,
    Bodies = Matter.Bodies;

    // create a Matter.js engine
    var engine = Engine.create(body);

    // create two boxes and a ground
    var boxA = Bodies.rectangle(400, 200, 80, 80);
    var boxB = Bodies.rectangle(450, 50, 80, 80);
    var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });

    // add all of the bodies to the world
    World.add(engine.world, [boxA, boxB, ground]);

    // run the engine
    Engine.run(engine);
}

Hope this helps!

Dzerzhinsk answered 22/1, 2015 at 2:8 Comment(3)
Thanks, I have tried with document.getElementById before, and it didn't work either. The onload did the trick.Cripple
Be careful! document.getElementById(id) requires an id, and <body> doesn't normally have an id, use document.querySelector(selector) (more on selectors) instead, and also, window.onload will replace all previous load event's in window, I've updated my answer to use window.addEventListener() instead, which does not cause this behaviour. Lastly, if you feel your question has been answered, click the green tick next to the answer! Bye :)Dzerzhinsk
In my solution I used a <div id='canvas-container'></div>, like they do in the demo. But using Engine.create(document.body) also work. Thank you anyway.Cripple
P
3

It has been a long time for this question but I see that the library might be improved with new Render object so the new basic sample code is as follows

Include following in <head> tags

<script src="matter.js" type="text/javascript"></script>

The JS code can be placed at the bottom of the <body> tag

<script>

    // module aliases
    var Engine = Matter.Engine,
        Render = Matter.Render,
        World = Matter.World,
        Bodies = Matter.Bodies;

    // create an engine
    var engine = Engine.create();

    // create a renderer
    var render = Render.create({
        element: document.body,
        engine: engine
    });

    // create two boxes and a ground
    var ball = Bodies.circle(420, 15, 20);

    var boxA = Bodies.rectangle(400, 200, 80, 80);
    var boxB = Bodies.rectangle(450, 50, 80, 80);
    var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });

    // add all of the bodies to the world
    World.add(engine.world, [ball, boxA, boxB, ground]);

    // run the engine
    Engine.run(engine);

    // run the renderer
    Render.run(render);

</script>
Pork answered 14/9, 2016 at 14:33 Comment(0)
D
1

Minimal single HTML file runnable example (0.19.0)

https://mcmap.net/q/304096/-how-to-make-minimal-example-of-matter-js-work mentioned the key step which is to put the <script> tag at the bottom of the <body> element.

But for the sake of directness, here it is fully working on a single complete HTML file with the code from https://github.com/liabru/matter-js/wiki/Getting-started/1d138998f05766dc4de0e44ae2e35d03121bb7f2 and using the library hosted from CDNJS https://cdnjs.com/libraries/matter-js for the sake of the demo:

hello.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js" integrity="sha512-0z8URjGET6GWnS1xcgiLBZBzoaS8BNlKayfZyQNKz4IRp+s7CKXx0yz7Eco2+TcwoeMBa5KMwmTX7Kus7Fa5Uw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
<script>
// module aliases
var Engine = Matter.Engine,
    Render = Matter.Render,
    Runner = Matter.Runner,
    Bodies = Matter.Bodies,
    Composite = Matter.Composite;

// create an engine
var engine = Engine.create();

// create a renderer
var render = Render.create({
    element: document.body,
    engine: engine
});

// create two boxes and a ground
var boxA = Bodies.rectangle(400, 200, 80, 80);
var boxB = Bodies.rectangle(450, 50, 80, 80);
var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true });

// add all of the bodies to the world
Composite.add(engine.world, [boxA, boxB, ground]);

// run the renderer
Render.run(render);

// create runner
var runner = Runner.create();

// run the engine
Runner.run(runner, engine);
</script>
</body>
</html>

Alternatively, for local development, you would likely instead want to install locally with:

npm install [email protected]

and instead load the library with:

<script src="node_modules/matter-js/build/matter.min.js"></script>

as that will free you the need from being online to develop.

And real deployment will then likely want to use NPM and then webpack to bundle all Js into a single file instead as usual.

The example contains two squares falling, and no interactivity enabled:

enter image description here

enter image description here

Delaryd answered 8/5, 2023 at 17:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.