Sprite image not appearing on matter.js

Viewed 2103

I am trying to replace the standard circle body with an image sprite but it isn't showing the image.

var Engine = Matter.Engine,
  Render = Matter.Render,
  World = Matter.World,
  Bodies = Matter.Bodies,
  Body = Matter.Body,
  Constraint = Matter.Constraint,
  Vector = Matter.Vector,
  Events = Matter.Events,
  Mouse = Matter.Mouse,
  MouseConstraint = Matter.MouseConstraint;

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

engine.world.gravity.y = 0; // gravity not needed in this app

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

var ball_0 = Bodies.circle(100, 100, 11, {
  density: 0.04,
  frictionAir: 0.06,
  restitution: 0.8,
  friction: 0.01,
  render: {
    sprite: {
      texture: 'images/white.png',
      xScale: 20,
      yScale: 20
    }
  }
});

// add all of the bodies to the world
World.add(engine.world, ball_0);

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

// run the renderer
Render.run(render);
<script src="https://github.com/liabru/matter-js/releases/download/0.10.0/matter.min.js"></script>

2 Answers

Setting wireframes: false is half the answer, you also need to first load the image before setting it as texture

You must load the Image before setting it as Texture otherwise you will get error

HTMLImageElement is in "broken" state

For me this issue end up printing 900+ error messages which crashed my sandbox.

Solution: I created a simple Image loader:

const loadImage = (url, onSuccess, onError) => {
  const img = new Image();
  img.onload = () => {
    onSuccess(img.src);
  };
  img.onerror = onError();
  img.src = url;
};

And later I used that loader to load the texture. Once texture is loaded you can set it as texture for your Body objects.

 loadImage(
      "./assets/blue.jpg",
      url => {
        console.log("Success");
        World.add(world, [
          Bodies.circle(340, 340, 100, {
            density: 0.0005,
            frictionAir: 0.06,
            restitution: 0.3,
            friction: 0.01,
            render: {
              sprite: {
                texture: url // set texture here
              }
            }
          })
        ]);
      },
      () => {
        console.log("Error  Loading ");
      }
    );

Important: before calling Renderer.run() you must disable wireframes

// create renderer
var render = Render.create({
  element: document.body,
  engine: engine,
  options: {
    width: 800,
    height: 600,
    wireframes: false, // disable Wireframe
  }
});

Render.run(render);
Related