The Matter.js Physics Engine can bring great possibilities to your JavaScript projects. It is useful for building games and simulations, creating user interactivity, and even adding dynamics to a static site.
“Matter.js supports all major browsers including IE8+. Additionally, it is suitable for use on mobile devices as it can detect touch and has responsiveness.”
If you are new to the library, there is a fun set of demos to try. This is a good starting point to gain inspiration for how you wish to incorporate Matter.js into your projects.
At any stage in your familiarity with Matter.js, the documentation will always be a reliable resource.
To give credit where credit is due, there is an example on CodeSandbox that demonstrates the solution well.
This guide will explain the solution to make the code reusable, and also provide some additional insight for how the built-in methods of the Matter.js library can be used in React.
All the necessary code is in the Scene.js
component:
import React from "react";
import ReactDOM from "react-dom";
import Matter from "matter-js";
class Scene extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
var Engine = Matter.Engine,
Render = Matter.Render,
World = Matter.World,
Bodies = Matter.Bodies,
Mouse = Matter.Mouse,
MouseConstraint = Matter.MouseConstraint;
var engine = Engine.create({
// positionIterations: 20
});
var render = Render.create({
element: this.refs.scene,
engine: engine,
options: {
width: 600,
height: 600,
wireframes: false
}
});
var ballA = Bodies.circle(210, 100, 30, { restitution: 0.5 });
var ballB = Bodies.circle(110, 50, 30, { restitution: 0.5 });
World.add(engine.world, [
// walls
Bodies.rectangle(200, 0, 600, 50, { isStatic: true }),
Bodies.rectangle(200, 600, 600, 50, { isStatic: true }),
Bodies.rectangle(260, 300, 50, 600, { isStatic: true }),
Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
]);
World.add(engine.world, [ballA, ballB]);
// add mouse control
var mouse = Mouse.create(render.canvas),
mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2,
render: {
visible: false
}
}
});
World.add(engine.world, mouseConstraint);
Matter.Events.on(mouseConstraint, "mousedown", function(event) {
World.add(engine.world, Bodies.circle(150, 50, 30, { restitution: 0.7 }));
});
Engine.run(engine);
Render.run(render);
}
render() {
return <div ref="scene" />;
}
}
export default Scene;
The componentDidMount()
method contains the methods for initializing and rendering the Matter.js content. The source code files for all of the demos display the rendering process well.
This entire method can also be extracted as a helper method if desired. The essential piece to React integration is providing a ref
on a JSX element in the return statement of the class component:
This ref
is then specified as the element
property of the Matter.Render()
method within the componentDidMount()
:
It is important to create this association when using React, because otherwise, the scene will automatically create an element, which may be difficult to use in a React JSX return statement. (It certainly could be possible, though.)
element
property in the Matter.Render()
method
That covers the essentials for getting a minimally viable Matter.js product up and running with React!
Matter.js has lots of built-in methods for manipulating properties within the various modules. The methods require the developer to be able to make a reference to a specific module or body within the Matter.js engine.
One method to achieve this is by using React’s state
to store objects or variables that have been declared in the initializing process, called in the componentDidMount()
method.
For example, at the end of the the componentDidMount()
, we can call a setState()
. It might look like:
this.setState({
render: render
})
By setting the render object in state, it can be used to reference the various modules. We can inspect the component using React Developer Tools and learn where the various parts are located:
Working our way down to the bodies
key, we have access to the bodies within the render
. So, if we wanted to remove a body from the scene, we can write something like:
const world = this.state.render.engine.world
const body = world.bodies[0]
Matter.World.remove(world, body)
We have now called a built-in method, Matter.World.remove
by passing in two state-referenced objects as the arguments.
Matter.World.remove method
The Matter.js Physics Engine can be implemented into React with only a little bit of React knowledge. You don’t even have to be a physicist to use it!
An advantage of using React Developer Tools is the visualization aspect of learning the Matter.js library. It sort of serves as a condensed form of the codebase.
By spending some time investigating this object, you’ll be sure to learn lots about Matter.js.
The end. Thank you for reading !
#React #JavaScript #Programming #Front End Development #Webdev