Sketch with classes implementation in a Reactjs project

I manaje to implement a basic p5 sketch into my react app successfuly but I’m struggling when I have multiple classes and say a third party library like Matterjs.

Here is my current Reactjs setup:
Sketch.js is a functional component, in it I have the usual setup and draw p5js methods with an import to a class and an import for the p5js and matterjs libraries, the problem I have is that whe I start to use classes from the matterjs lib in my class object things start to get messy very quickly as I have to pass a reference to the say Bodies object down to my class plus a reference to the p5js and so on.

Is there a guideline on how to best approach this type of projects? Is there a specific way to import the libraries and classes?

Any help will be much appreciated.

// END OF LINE

1 Like

Given p5js isn’t a JS module, but instead it is distributed as a normal JS file, I don’t think we can use the JS keyword import for it. :confused:

If you make a class that needs to request a specific object reference many times, it’s much simpler to request that from its constructor and store it as 1 of its properties. :bulb:

In the sketch link below, the class Ball asks for a p5 object as its constructor’s parameter; then stores it as property p: :nerd_face:

1 Like

Hi @GoToLoop thank you for your reply :+1:

I feel I didn’t explain my problem very well. I’m not an expert in Javascript so some of its quirks are still a mistery to me hence my post. p5js can be imported, here is an example of a bare-bones component.

import p5 from 'p5';

export default function P5Component() {
	const sketch = (p) => {
		p.setup = () => {
			p.createCanvas(window.innerWidth, window.innerHeight);
			p.background('#fcfcfc');
		};

		p.draw = () => {
			p.background('#fcfcfc');
			p.fill(20, 20);
			p.ellipse(p.mouseX, p.mouseY, 50, 50);
		};
	};
	new p5(sketch, window.document.getElementById('canvasContainer'));
	return null;
}

You must install the package on to your React project.

My struggle comes when I need to use other third party libraries and clases in my project, so I wondered if there is an easier way to work with such combination.

So on my project I import the Matterjs library and a Class, passing a p5 reference to the class is not a problem, as you suggested :+1:

But when the class needs to use some of the Matterjs objects and methods things start to get complicated. I already try to pass a reference of Matterjs, but I happen to import all sort of objects Bodies, Constrains, World and so on and still cant get it to work. I think I’ll have to keep all my code in the same Component and not border with a class since my skectch is very small.

Say your bouncing ball instance mode code, is a good example of my situation. If you make the ball a class in a separate file that uses Matterjs to bounce around will mirror my situation exaclty.

Again if there is a way to workaround this kind of situations I’ll love to know about it.

1 Like

The statement import p5 from 'p5'; won’t work in a browser environment, b/c it lacks the extension name for the imported file.

That is, it needs to be ‘p5.js’ instead of just ‘p5’.

In the future, browsers may be able to accept extension-less filenames.

Also, even using the full filename, we’d still need to add its path to its name.

That is, special folders like ‘node_modules/’ are meaningless to a browser.

So instead of just ‘p5.js’, we’re gonna need something like:
import p5 from '/node_modules/p5/lib/p5.js';.

And lastly, both ‘p5.js’ & ‘matter-js.js’ are plain JS library files, not actual ES6 modules; b/c they lack the keyword statements export or import inside them.

Therefore we can’t use the keyword import on neither of them b/c they don’t expose anything using actual ES6 syntax!

Just assume both p5 & Matter are already available in the global context once they’re loaded like this:

<script defer src=https://Unpkg.com/p5></script>
<script defer src=https://Unpkg.com/matter-js></script>

My guess your project got bundled utilities which are able to convert your bare-bones component into an actual browser-runnable code; which makes them a challenge for me to debug.

1 Like

Well, it took a couple of days for me to learn enough Matter.js in order to change my “Bouncing Colorful Balls” sketch to rely on it instead for all movement & bouncing.

The file “sketch.mjs” can pass around both the World & p5 instance references to the files “ball.mjs” & “addCanvasWalls.mjs”!

Maybe you can find out a way to adapt the “technique” to your own React.js components.

Here’s the complete browser-runnable code:

And some extras which run 2 & 4 instances of it in the same page:

Notice that I use the extension “.mjs” instead of “.js” just to make it clear they’re true ES6 module files rather than plain vanilla script 1s.

1 Like

@GoToLoop LEGEND!

Since my project is a Reactjs “app” it does bundles the p5js and matterjs libraries in deed.

I had a look at your code (thank you for the time and effor to work on the examples friking legend you are), I noticed something on the Ball class: constructor(world, p = p5.instance) I’ve never seeing that before, do you mind elaborate?

My take on passing the p5js reference to the Ball class was:

constructor(world, p) {
    this.world = world;
    this.p = p;
}

and then this.p.[method] every time I need a p5js function like: this.p.ellipse(this.p.mouseX, this.p.mouseY);

But your implementation is cleaner with p5.instance. I take is a feature of p5js only right?

1 Like

Those are parameters w/ a default value, which takes place when the parameter is undefined.

That is, if we pass an argument to the parameter world only, the parameter p is gonna be initialized w/ the value p5.instance instead.

Actually p5.instance is irrelevant for this sketch b/c it holds the p5 reference of a global mode sketch.

Since this Matter.js sketch version is coded in instance mode only, p5.instance is always undefined.

Therefore we’ve always gotta pass the sketch’s p5 reference as the 2nd argument.

The original non-Matter.js had both global & instance mode versions.

So the global mode sketch could opt out to pass the 2nd argument if it chooses so.

BtW, p5js got a 3rd-party library called p5-matter which bundles Matter.js:
PalmerPaul.com/p5-matter

1 Like