Processing.js for Processing Devs: Difference between revisions

No edit summary
Line 106: Line 106:
While Processing.js is compatible with Processing, Java is not JavaScript, and canvas has some differences from Java's graphics classes.  Here are some tricks and tips as you start working on more complex sketches in Processing.js.
While Processing.js is compatible with Processing, Java is not JavaScript, and canvas has some differences from Java's graphics classes.  Here are some tricks and tips as you start working on more complex sketches in Processing.js.


* Processing uses the concept of a '''data''' directory, where images and other resources are located.  Processing.js does not include this.  As a result, you should always provide file pages (e.g., images) that are relative to your web page, which is the norm on the web.
===Processing.js has no data directory===


* Processing.js is compatible with Processing, but is not, and will never be, fully compatible with Java.  If your sketch uses functions or classes not defined as part of Processing, they are unlikely to work with Processing.js.  Similarly, libraries that are written for Processing, which are written in Java instead of Processing, will most likely not work.
Processing uses the concept of a '''data''' directory, where images and other resources are located.  Processing.js does not include this.  As a result, you should always provide file pages (e.g., images) that are relative to your web page, which is the norm on the web.
 
===Processing.js implements Processing, but not all of Java===
 
Processing.js is compatible with Processing, but is not, and will never be, fully compatible with Java.  If your sketch uses functions or classes not defined as part of Processing, they are unlikely to work with Processing.js.  Similarly, libraries that are written for Processing, which are written in Java instead of Processing, will most likely not work.
 
===Processing.js has to cheat to simulate Processing's synchronous I/O===
 
Processing uses a synchronous I/O model, which means that functions like '''loadImage()''' take time to execute, and while they are running, nothing else happens: the program waits until '''loadImage()''' is done before moving on to the next statement.  This means that you can count on the value returned by a function like '''loadImage()''' being usable in the next line of code.
 
Web browsers don't work like this.  The web uses an asynchronous I/O model, which means that functions which load external resources can't make the program wait until they finish.  In order to replicate Processing's load* functions, you have to use a special Processing.js Directive.
 
The Processing.js Directives are hints to the browser that are written in comments rather than in the Processing code itself.  Here's a typical Processing sketch that loads an image synchronously and then draws it:
 
<pre>
PImage img;
 
void setup() {
  img = loadImage("picture.jpg");
  image(img, 0, 0);
}
</pre>
 
This code will not work in the browser with Processing.js, because the call to '''image()''' will happen before the file '''picture.jpg''' has been downloaded.  The fix is to ask Processing.js to download the image before the sketch starts, and cache it--a technique known as preloading.  Here is the modified code:
 
<pre>
/* @pjs preload="picture.jpg"; */
PImage img;
 
void setup() {
  img = loadImage("picture.jpg");
  image(img, 0, 0);
}
</pre>
 
Notice the extra comment line at the top of the code.  The '''@pjs''' directive is for Processing.js, and not the developer.  Think of it as an extra in of code that will be executed before the program begins.
 
If you have multiple images to load, use a list like so:
 
<pre>
/* @pjs preload="picture.jpg,picture2.jpg,picture3.png"; */
</pre>
 
===Processing.js requires more care with variable naming than Processing===
 
One of the powerful features of JavaScript is its dynamic, typeless nature.  Where typed languages like Java, and therefore Processing, can reuse names without fear of ambiguity (e.g., method overloading), Processing.js cannot.  Without getting into the inner-workings of JavaScript, the best advice for  Processing developers is to not use function/class/etc. names from Processing as variable names.  For example, a variable named '''line''' might seem reasonable, but it will cause issues with the similarly named '''line()''' function built-into Processing and Processing.js.
Confirmed users
656

edits