# How to access p5js functions when using ES6 modules

**URL:** <https://discourse.processing.org/t/how-to-access-p5js-functions-when-using-es6-modules/21359>\
**Category:** Coding Questions\
**Created:** [May 28, 2020, 7:51am UTC](https://discourse.processing.org/t/how-to-access-p5js-functions-when-using-es6-modules/21359 "2020-05-28T07:51:44Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![dansumption](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/dansumption/32/9365_2.png) [@dansumption](https://discourse.processing.org/u/dansumption)\
**Post date:** [May 28, 2020, 7:51am UTC](https://discourse.processing.org/t/how-to-access-p5js-functions-when-using-es6-modules/21359/1 "2020-05-28T07:51:44Z")

</div>

I am trying to write an app using ES6 modules and the voronoi library, and in this environment all of the processing instance functions (`background`, `stroke`, `random`, etc) are not in the module’s namespace.

I have got around this for the modules I’m writing by passing the processing object into each one and storing it in the module, i.e.

```auto
class SomeModule {
  constructor(processing) {
    this.processing = processing;
  }

  draw() {
    this.processing.background(0);
    ...

```

However, this does not work when I import files which assume that the processing functions will be in their namespace. Specifically in my case, I am loading `p5.voronoi.js` from my HTML, but when I try to use it I get an error:

```auto
p5.voronoi.js:280 Uncaught ReferenceError: round is not defined
    at setRandoms (p5.voronoi.js:280)
    at p5.voronoi (p5.voronoi.js:227)
   ...

```

How can I get processing’s `round` function, and all the other functions I rely on, into a namespace accessible from `p5.voronoi.js`?

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 28, 2020, 9:46am UTC](https://discourse.processing.org/t/how-to-access-p5js-functions-when-using-es6-modules/21359/2 "2020-05-28T09:46:41Z")

</div>

> [@dansumption](#):
>
> , into a namespace accessible from “p5.voronoi.js”?

That “p5.voronoi” library is meant for sketches using the “global mode” approach only:

> <https://github.com/Dozed12/p5.voronoi/blob/master/library/p5.voronoi.js>

It means at the very least your main “sketch.js” file gotta use the “global mode” approach as well.

> [@dansumption](#):
>
> I am trying to write an app using ES6 modules and the voronoi library, and in this environment all of the processing instance functions ( `background` , `stroke` , `random` , etc) are not in the module’s namespace.

If p5.js is loaded via `<script>`, it dumps itself on the global namespace & thus it can be accessed even by ES6 module files, as long as it finds **setup()** and/or **draw()** on the global namespace as well, like this: `window.setup = function () {}`

Here’s a p5.js global mode sketch example using ES6 module files:

> <https://gist.github.com/GoSubRoutine/da4939559d8b786df13f5694ea2edd30>
>
> There are more than three files. show original

---

<div class="post-metadata">

**Author:** ![dansumption](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/dansumption/32/9365_2.png) [@dansumption](https://discourse.processing.org/u/dansumption)\
**Post date:** [May 28, 2020, 12:32pm UTC](https://discourse.processing.org/t/how-to-access-p5js-functions-when-using-es6-modules/21359/3 "2020-05-28T12:32:36Z")

</div>

> Here’s a p5.js global mode sketch example using ES6 module files:

Brilliant! That looks to the solution. I hadn’t realised you could use the processing globals inside a module (the examples I found didn’t do it that way, but rather fetched the processing instance via a constructor, as above).

That’s an awful lot of `this.processing.` refernces that I’ve just had to remove from my code! Much neater codebase as a result.

Only problem now is that it doesn’t work, because every time I call `loadPixels` or `image` it complains that the canvas element has 0 width or height. I presume this is because creating the canvas is done asynchronously, and the way I did things before left time for them to complete before they were needed, but now things are happening quicker.

Going to go off an see how I can run those creation methods asynchronously (but if you can point me in the right direction, it might save me some digging 🙂)

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 28, 2020, 1:41pm UTC](https://discourse.processing.org/t/how-to-access-p5js-functions-when-using-es6-modules/21359/4 "2020-05-28T13:41:56Z")

</div>

> [@dansumption](#):
>
> … fetched the processing instance via a constructor, as above).

Classes in other files should still require a p5 instance, so they can be used regardless the main sketch is in global or instance mode.

> [@dansumption](#):
>
> I presume this is because creating the canvas is done asynchronously,

AFAIK, `<canvas>` are created synchronously.  
Loading assets, on the other hand, is indeed asynchronously.

> [@dansumption](#):
>
> (but if you can point me in the right direction, it might save me some digging 🙂)

Most I can do is pointing you to a more complex sketch I have, which also uses ES6 modules, classes, a 3rd-party library (Matter.js), and is available in both global & instance modes:

https://glitch.com/embed/#!/embed/matter-js-bouncing-colorful-balls?path=sketches/global.mjs&previewSize=0&sidebarCollapsed=true

---

<div class="post-metadata">

**Author:** ![dansumption](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/dansumption/32/9365_2.png) [@dansumption](https://discourse.processing.org/u/dansumption)\
**Post date:** [July 2, 2020, 6:33pm UTC](https://discourse.processing.org/t/how-to-access-p5js-functions-when-using-es6-modules/21359/5 "2020-07-02T18:33:12Z")

</div>

Thanks for your replies @GoToLoop and sorry for taking so long to get back on this… life intervened!

Your tips sent me in the correct direction, which put very simply was to set a `setup` and `draw` method on the global `window` object. I’m not sure quite where I got my previous approach from, but I copied it from somewhere, where instead the `setup` and `draw` methods were instantiated in something like the following way:

```auto
const sketch = processing => {
  processing.setup = () => {
    ...
  }

  processing.draw = () => {
    ...
  }
}

const myP5 = new p5(sketch);

```

I then had to iron out a few race conditions which I had been experiencing mainly as a result of my initial approach, but once I’d done that then it worked even better than before, plus I managed to clean the code of hundreds of ugly instances of (for example) `this.processing.circle(...` and replace them with a far more straightforward `circle(...`

Coincidentally, changing my approach to the one you recommended also solved the other mystery problem I’d been seeing, detailed in this post: [Setup method runs twice - #3 by dansumption](https://discourse.processing.org/t/setup-method-runs-twice/21275/3)

BTW if you’re interested to see what I ended up making with all this new knowledge (and I’m very proud of it), here’s the music video I made entirely using p5js: [https://youtu.be/rdbgckSmlAo](https://youtu.be/rdbgckSmlAo)

Thanks again!

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [July 3, 2020, 3:14pm UTC](https://discourse.processing.org/t/how-to-access-p5js-functions-when-using-es6-modules/21359/6 "2020-07-03T15:14:54Z")

</div>

> [@dansumption](#):
>
> I’m not sure quite where I got my previous approach from, but I copied it from somewhere,

Some place like this 1? 😉

> **[examples | p5.js](https://p5js.org/examples/instance-mode-instantiation.html)**
>
> p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.

> [@dansumption](#):
>
> , where instead the `setup` and `draw` methods were instantiated in something like the following way:

p5.js sketches can use 2 approach coding styles: “Global” & “Instance” modes.

On “global mode” the whole p5 instance is dumped in the _window_ global context.

While on “instance mode” we create a function containing our sketch code and pass it as the 1st argument for the p5 constructor.

“Global mode” is the easiest to code with. However, we can’t have more than 1 “Global mode” sketch running on the same frame context!

If we need to have more than 1 sketch, we’re gonna have to code the others on “instance mode” style.

Unless we place the extra “global mode” sketches on their own separate `<iframe>` tag:  
[Developer.Mozilla.org/en-US/docs/Web/HTML/Element/iframe](http://Developer.Mozilla.org/en-US/docs/Web/HTML/Element/iframe)

On the link below we’ve got 4 sketch instances on the same page:  
[Matter-JS-Bouncing-Colorful-Balls.Glitch.me/all.html](http://Matter-JS-Bouncing-Colorful-Balls.Glitch.me/all.html)

The top 2 are coded w/ “global mode” style, while the 2 on the bottom are using “instance mode”:  
[Matter-JS-Bouncing-Colorful-Balls.Glitch.me/sketches/global.mjs](http://Matter-JS-Bouncing-Colorful-Balls.Glitch.me/sketches/global.mjs)  
[Matter-JS-Bouncing-Colorful-Balls.Glitch.me/sketches/instance.mjs](http://Matter-JS-Bouncing-Colorful-Balls.Glitch.me/sketches/instance.mjs)

If you hit CTRL+U on the 4 running sketches’ page you’re gonna come up w/ the following “all.html” file:

```auto
<script defer src=https://cdn.JsDelivr.net/npm/p5></script>
<script defer src=https://cdn.JsDelivr.net/npm/matter-js></script>

<iframe src=global.html></iframe>

<script type=module src=sketches/global.mjs></script>

<script type=module>
  import sketch from '/sketches/instance.mjs';
  for (let i = 0; i++ < 2; new p5(sketch));
</script>

```

Notice I had to place the extra “global mode” sketch in an `<iframe>`, b/c we can’t have more than 1 “global mode” sharing the same page frame:  
`<iframe src=global.html></iframe>`

It loads another HTML file, which in turn loads & runs “global.mjs” along w/ p5.js & matter-js libraries, separated from its parent HTML’s context:  
[Matter-JS-Bouncing-Colorful-Balls.Glitch.me/global.html](http://Matter-JS-Bouncing-Colorful-Balls.Glitch.me/global.html)

```auto
<script defer src=https://cdn.JsDelivr.net/npm/p5></script>
<script defer src=https://cdn.JsDelivr.net/npm/matter-js></script>

<script type=module src=sketches/global.mjs></script>

```

In short we can stick w/ the easier “global mode” style as long as we take care to place them in separate `<iframe>` tags if we’re using more than 1 global sketch on the same page. 🕶

---

<div class="post-metadata">

**Author:** ![dansumption](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/dansumption/32/9365_2.png) [@dansumption](https://discourse.processing.org/u/dansumption)\
**Post date:** [July 3, 2020, 3:36pm UTC](https://discourse.processing.org/t/how-to-access-p5js-functions-when-using-es6-modules/21359/7 "2020-07-03T15:36:39Z")

</div>

> [@GoToLoop](#):
>
> > [@dansumption](#):
> >
> > I’m not sure quite where I got my previous approach from, but I copied it from somewhere,
> 
> Some place like this 1? 😉  
> [p5js.org/examples/instance-mode-instantiation.html](http://p5js.org/examples/instance-mode-instantiation.html)

Ahhhhh, that (and the rest of your post) makes sense! Thanks for going to the trouble of explaining.

I only anticipate using p5js to generate a single sketch (which anyway I am mainly just using as something I can capture in OBS so as to turn into an MP4 file), so don’t think I will ever need _instance_ mode. Annoying that it was the only way I discovered initially of allowing modules access to the `processing` object. Still, it’s all learning…
