Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using p5's functions without the setup/draw format

I'm relatively new to Javascript, and i was tinkering around with the p5 library. In Python i can import a single function from a library using the from x import y statement:

from subprocess import check_output

My question is, there is a way to do the same thing with p5 without using the setup/draw format? Say, for example, i want to use the noise function in one of my scripts; can i import and use that function only?

like image 513
g_rmz Avatar asked Aug 17 '16 07:08

g_rmz


1 Answers

With questions like this, it's best to put together a test to try things out:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Noise Test</title>
    <script src="p5.js" type="text/javascript"></script>
    <script>
        console.log(noise(100));    
    </script>

  </head>
  <body>
  Noise Test, check the console.
  </body>
</html>

Here we're loading the p5.js library, and then trying to call the noise() function. If we run that, we get an error:

Did you just try to use p5.js's noise() function? If so, you may want to move it into your sketch's setup() function.

For more details, see: https://github.com/processing/p5.js/wiki/Frequently-Asked-Questions#why-cant-i-assign-variables-using-p5-functions-and-variables-before-setup

index.html:9 Uncaught ReferenceError: noise is not defined

We can go to that url to read about what's going on:

In global mode, p5 variable and function names are not available outside setup(), draw(), mousePressed(), etc. (Except in the case where they are placed inside functions that are called by one of these methods.)

The explanation for this is a little complicated, but it has to do with the way the library is setup in order to support both global and instance mode. To understand what's happening, let's first look at the order things happen when a page with p5 is loaded (in global mode).

  1. Scripts in are loaded.

  2. of HTML page loads (when this is complete, the onload event fires, which then triggers step 3).

  3. p5 is started, all functions are added to the global namespace.

So the issue is that the scripts are loaded and evaluated before p5 is started, when it's not yet aware of the p5 variables. If we try to call them here, they will cause an error. However, when we use p5 function calls inside setup() and draw() this is ok, because the browser doesn't look inside functions when the scripts are first loaded. This is because the setup() and draw() functions are not called in the user code, they are only defined, so the stuff inside of them isn't run or evaluated yet.

It's not until p5 is started up that the setup() function is actually run (p5 calls it for you), and at this point, the p5 functions exist in the global namespace.

So, no, you can't use p5.js functions without the setup() and draw() functions.

That being said, you could define a callback function that you call from setup(), that way you know the p5.js functions are available:

<script src="p5.js" type="text/javascript"></script>
<script>
    function doYourStuff(){
        console.log(noise(100));        
    }

    function setup(){
        doYourStuff();
    }
</script>

Alternatively, you could use instance mode.

This involves manually creating an instance of p5 and using that to call functions directly instead of calling them globally:

<script src="p5.js" type="text/javascript"></script>
<script>
    var p5 = new p5();
    console.log(p5.noise(100));
</script>

You could also dig through the source.

There isn't a good way to import a single function, but you could do a ctrl+f search of the unminified source for p5.js and look for the noise() function. Then you could copy that into its own file (and any other helper functions it relies on). But that's probably going to be more work than using one of the above approaches, plus it might violate p5.js's copyrights.

like image 60
Kevin Workman Avatar answered Sep 17 '22 12:09

Kevin Workman