Search code examples
javascriptcanvasprocessing.js

pjs sketches and html canvas


I'm trying to understand what I'm doing when I stick a pjs sketch to an html canvas in the following way.

<body>
<canvas id="mycanvas" style="border: 1px solid black;"></canvas> 
</body>
<script src="https://cdn.jsdelivr.net/processing.js/1.4.8/processing.min.js">
</script>

<script>
var sketchProc = function(processingInstance) {
with (processingInstance) {     
size(800, 400);      
frameRate(30);

draw = function() {
  background(235, 245, 255);
};

}};
var canvas = document.getElementById("mycanvas");     
var processingInstance = new Processing(canvas, sketchProc);
</script>

When I began learning this stuff, I was eager to add my animations to an html doc. I learned the above way pretty much how I imagine a hamster can learn to push a button and receive a pellet; that is, I don't understand the mechanism well, but the result is positive.

Here is the above example in action: https://jsfiddle.net/h1Lb91ux/

Here is my attempt at making sense of this.

The following code is defining a function called sketchProc.

var sketchProc = function(processingInstance) {
with (processingInstance) {     
size(800, 400);      
frameRate(30);

draw = function() {
  background(235, 245, 255);
};

}};

This doesn't return anything because we're just defining sketchProc, not calling it. It's argument is processingInstance, which is being defined as a local variable just like if I did:

var functionX = function(x) {
  return x;
};

But I do not understand the with statement. I know of with statements from excel-vba, which can be used to attach multiple methods to an object without having to repeatedly type out the object name. Is this the same?

The following statement makes perfect sense.

var canvas = document.getElementById("mycanvas"); 

But this next one is a source of confusion:

var processingInstance = new Processing(canvas, sketchProc);

To me, this looks like we're making a single instance or object from an object constructor function (in javascript) or a class (in processing), which takes 2 arguments: canvas and sketchproc. We're calling this specific instance processingInstance, which confusingly is the same name as the local variable used in the function sketchProc.

I hope this is not too rambling.


Solution

  • The following code is defining a function called sketchProc.

    var sketchProc = function(processingInstance) {
    with (processingInstance) {     
    size(800, 400);      
    frameRate(30);
    
    draw = function() {
      background(235, 245, 255);
    };
    
    }};
    

    It's defining a function object that itself contains functions like draw(). You can read more about function objects here, but basically this is just an instance that contains functions that Processing can call.

    But I do not understand the with statement.

    Try googling something like "javascript with" for a ton of results, including this one. But my understanding is that it's a shortcut to avoid having to call processingInstance. before everything. You can try removing the with statement and putting processingInstance. before any Processing function to see the alternative. The with is optional, but makes you code slightly shorter. I personally don't like the use of with here, but that's just me.

    But this next one is a source of confusion:

    var processingInstance = new Processing(canvas, sketchProc);
    

    To me, this looks like we're making a single instance or object from an object constructor function (in javascript) or a class (in processing), which takes 2 arguments: canvas and sketchproc. We're calling this specific instance processingInstance, which confusingly is the same name as the local variable used in the function sketchProc.

    Your understanding sounds about right. Creating an instance of Processing is what kicks off all of the Processing magic, calling the setup() function and the draw() function for you automatically. You can also rename the variable if it confuses you.

    Taking a step back, this code uses Processing.js's instance mode, which is why you have all this extra code that you don't really understand. I would recommend you start with the more basic global mode, which would allow your code to look like this:

    <script type="application/processing">
    function setup(){
      size(800, 400);      
      frameRate(30);
    }
    
    function draw() {
      background(235, 245, 255);
    };
    </script>
    <canvas> </canvas>
    

    I'm also curious why you're using Processing.js. If you're coming from a JavaScript background, you might have more luck with P5.js instead.