Rodrigo
Rodrigo

Reputation: 5129

How to make minimal example of matter.js work?

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?

Upvotes: 8

Views: 7906

Answers (4)

Minimal single HTML file runnable example (0.19.0)

https://stackoverflow.com/a/39493132/895245 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

Upvotes: 2

Eralper
Eralper

Reputation: 6612

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>

Upvotes: 3

undefined
undefined

Reputation: 4135

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!

Upvotes: 3

Rodrigo
Rodrigo

Reputation: 5129

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);
}

Upvotes: 6

Related Questions