published: 2011/02/13. tags: processing.js, javascript, html5 canvas

Processing.js and Javascript

I have been working on a pet project to make my toddler son learn alphabet. When my son was 16 month old, when I call out the name of an animal, he was able to point it on his eating mat (which he doesn't use at the time of eating btw). Then I realized that even though he can't speak yet he was ready to remember words and also associate the words with objects and images. So, I started showing him alphabet and letters which he was also able to learn from his bouncing pony, an interactive game with the TV. At 19 months now, he can recognize a few letters. He also wants to write them on his magic (magnetic) slate and so he asks me to hold his hand and write the letters. And surprisingly he has the patience to write from A to Z! He is also able to differentiate letters from numbers.

Anyway, why am I saying all this? Well, that's where my pet project comes into picture. My goal is to be able to use the computer to teach kids (at least my son where possible and appropriate). As my son is learning, it's also a learning experience for me to see how his skills are progressing and what is needed to fulfill his requirements. As I spend a lot of time on the computers, he naturally wants to use them as well. And if there is a competition on who can bang the keyboard fast and hard, I wouldn't be surprised if he comes first. As the keyboards don't have the letters in order, it's difficult to make a small kid to learn the alphabet and make words using the keyboard. So, I started off creating a simple HTML app that would display all the English alphabet in order and he can simply click or drag and drop them and create words and follow the link to learn pronunciation of the word and know the meaning (he can't do all these at his current age, but would come handy one day). But before even forming words, his desire to write these letters is where we had a pause. Unless me or my wife holds his hand and write the letters, he has no way of learning and practicing how to write the alphabet himself.

So, my subsequent idea to the online keyboard is to actually provide animations of how to write the letters. I was debating between using Java Swing which I am familiar with vs using HTML 5 Canvas element. While thinking about this and researching, I came to know of Processing.js. Then it was a no brainer for me to go with it. Partly because it allows me to learn something new, but there are other benefits like rapid prototyping, making it easily available online so that others can make use of it (yes, I can create an applet, but I prefer using the regular browsers without plugins).

While good software development process is to gather requirements, come up with a good design, decide on your classes and objects and write test cases even before you start coding and what not, for the kind of stuff I do in my spare time, it doesn't work like that. As the focus is in creating and refining the idea, prototyping and reiterating is what works best. Of course, once I have the end product and if I had all the knowledge that I gathered in the process at the beginning, then I can understand doing the traditional software development approach works well. Anyway, I just started off with simple demo example on Prototype.js and went on building on it.

One of the road blocks I had was to create interaction between the canvas wrapped by Processing.js and the HTML UI controls such as buttons. Usually, the expectation is to make calls to the wrapper when there is a HTML UI event. However, how to make these event handlers available on the Processing object? A naive approach (which I am not ashamed to state I did :)), would be to create an instance of Processing object and try to use it. But remember that the new object that you create from JavaScript is not the same as the one that gets automatically created via the data-processing-sources pde.

That's when I had to dig a bit deeper into the processing.js code and finally came up with the following strategy.

  1. First, it's possible to write javascript code inside the pde file, even though it's Processing code. I am not sure if this is by design or not but it worked for me.
  2. However, it's not straightforward and that's where it get's difficult.
  3. But all hope is not lost. First thing to do is, in the setup method, have the following line
    
    println(externals.sketch);
    
    
    What the above code does is, it prints the compiled Processing code and so you can see your javascript code that got generated. So, finding out the problem by looking at the compiled code is a lot easier. You can comment the statement once you got your code working.
  4. You can setup all your event handler code within the setup() call itself.
    
    void setup() {
      this.doSomething = function() {
      }
    }
    
    
    However, if you need to call the Processing object member functions you don't need to use "this" as you would do in a typical javascript code. You can directly use the methods and the compilation process automatically converts these calls into method invocations against the variable $p which is bound to the current object of Processing (on which the setup method is called).

    By putting the event handlers into the setup code, by the time you need these event handlers they will already be available on the object (thanks to the power of javascript to augment objects with additional methods).

    Another advantage of having the event handler code in the setup function is, these functions have access to the rest of the state that's not stored as member variables. All the variables that you define at the beginning of the pde file before the setup method are accessible in your event handlers. This is something that won't be possible if one were to setup the event handlers directly from outside the pde file on the Processing object (assuming you know how to get hold of the one that's associated with your canvas, which is the next point).

  5. However, you need to make sure to use the right object. This can be done as follows
    
      var p;
      function initPage() {
        p = Processing.getInstanceById("canvas");
      }
    
    
    Processing has an API getInstanceById which returns the exact Processing object that was created as a wrapper for your canvas element with a given id. If you don't do this and instead try to create a new Processing object with your existing canvas, it would not have the setup method that was obtained from the pde (or pjs) file. The initPage is an onLoad event handler for the document body.
  6. Finally, if you have a button, say, "Animate", then you can write
    
    <button onclick="p.doAnimate(event);">Animate</button>
    
    
All this reminds of my class project while doing my Masters where we had to integrate between VRML and Java and also between TCL/TK and C++. Integrations between languages typically tend to be bit complex, but once you know what exactly is going on, it's not that difficult.

© 2011 Dirisala.Net/articles