Processing.js Quick Start - JavaScript Developer Edition
Introduction
This quick start guide is written from the standpoint of a JavaScript developer. The document assumes you know JavaScript and web programming, but only very basic Processing knowledge is assumed.
Index
- For the Impatient
- Why Processing.js?
- Ways to use Processing.js
- Things to Know as a JavaScript Developer using Processing.js
- Processing.js provides access to various DOM/JavaScript objects via the externals property
- Division which is expected to produce an integer might need explicit casting
- Processing.js has to cheat to simulate Processing's synchronous I/O
- Processing.js requires more care with variable naming than Processing
- It is possible to put Processing code directly in your web page
For the Impatient
If you're in a rush, here's what you need to know:
- Processing.js converts Processing code to JavaScript and runs it in the browser, using <canvas> for a drawing surface.
- To use it, download Processing.js here: downloads
- Make your Processing *.pde files as you normally would, for example hello-web.pde
- Create a web page that includes Processing.js as well as a <canvas> with info about where to get your sketch file (you can specify multiple *.pde files, separating them with spaces):
<script src="processing-1.0.0.min.js"></script> <canvas data-processing-sources="hello-web.pde"></canvas>
Load your web page, and it will parse, translate, and run your sketch in the browser.
Why Processing.js?
What is Processing?
The Processing language was originally created at MIT as part of the Media lab and Aesthetics and Computation group. They needed a way to bridge the gap between software developers, artists, data visualizers, etc., and to do so in a way that allowed new programmers (or non-programmers) to do complex visual work easily. Processing was built using Java, and can be thought of as a simplified Java, with a simplified Java API for drawing and graphics.
What does Processing bring to the web?
Processing has a large and vibrant community, who are good at creating 2D and 3D graphics, visualizing data sets, audio, video, etc. With HTML5 the web gained canvas, audio, and video--things which had previously only been available via plugins like Flash or Java. At the same time, advances in JavaScript engines have made it possible to do things in script that were previously too slow.
By porting the Processing language to the web, both the Processing and web communities benefit. For Processing, this means that code which used to only work on the desktop now "just works" in the browser. For the web, this means that a new but mature and full-featured approach to graphics programming becomes available. The <canvas> element is too low-level for most developers to use directly--JavaScript libraries are necessary. Processing.js can be thought of as just such a library, simplifying the use of the 2D and 3D canvas operations.
How much work is it to learn Processing?
The Processing language was designed to be small but complete, and easy to learn. This document does not attempt to teach you Processing, and you are encouraged to seek out Processing specific tutorials, books, and examples. Any Processing code or concepts should map to Processing.js (the exceptions are listed below). You can also use pure JavaScript to work with the Processing drawing API, skipping the Java syntax of Processing in favour of JavaScript.
Ways to Use Processing.js
Processing.js was originally created in order to allow existing Processing developers and existing Processing code (often referred to as sketches) to work unmodified on the web. As a result, the recommend way to use Processing.js is to write Processing code, and have Processing.js convert it to JavaScript before running it.
Over time, many web developers have begun using Processing.js, and asked that we design a way for the API to be used separate from the Processing language itself. Therefore, we have provided a way for JavaScript developers to write pure JavaScript code and still use the Processing.js functions and objects. NOTE: Processing.js is first and foremost a port of Processing to the open web, with design decisions favouring compatibility with Processing. It was not designed as a general purpose HTML drawing library. Having said that, it can be used as a high-level drawing API for canvas.
Below we discuss the various methods for using Processing.js in your web pages.
Writing Pure Processing Code
This is the preferred method for using Processing.js, and has been dealt with at length in the Processing.js for Processing Devs quick start guide. To summarize:
- Download Processing.js from here
- Create a separate Processing file or files, naming them whatever you want, as long as they have a *.pde extension.
- Create a web page that includes Processing.js as well as a <canvas> with info about where to get your sketch file(s), and include Processing filenames as a space-separated list in a data-processing-sources attribute on the canvas:
Hello Web - Processing.js Test
Processing.js Test
This is my first Processing.js web-based sketch:
<canvas data-processing-sources="hello-web.pde"></canvas>
Processing.js will automatically scan the document on page load for <canvas> elements with data-processing-sources attributes, download the files using XMLHTTPRequest, and feed them to the Processing-to-JavaScript translator. The resulting JavaScript is run using eval.
Pre-compiling Processing code to JavaScript
Processing.js automatically downloads and converts any Processing code to JavaScript. It does this using the Processing.compile() method, and those interested in building tools or utilities for Processing.js can do the same.
In order to obtain "compiled" code (i.e., JavaScript suitable for use by the Processing.js runtime) from Processing code, do the following:
// hard-coded Processing code, text from an HTML widget, downloaded text, etc. var processingCode = "..."; var jsCode = Processing.compile(processingCode).sourceCode;
For example, converting the following Processing code produces the "compiled" JavaScript underneath:
// Processing code
void setup() {
size(200, 200);
background(100);
stroke(255);
ellipse(50, 50, 25, 25);
println("hello web!");
}
// "Comiled" JavaScript code
// this code was autogenerated from PJS
(function(processing, $constants) {
function setup() {
processing.size(200, 200);
processing.background(100);
processing.stroke(255);
processing.ellipse(50, 50, 25, 25);
processing.println("hello web!");
}
processing.setup = setup;
})
Writing JavaScript-only Processing.js code
The previous method produced JavaScript code from Processing, but you can also write JavaScript on its own. The Processing.js parser turns Processing code into a JavaScript function, then runs it. As a result, it's possible to skip the Processing code altogether, and simply write a JavaScript function, passing this to your Processing instance. Here's an example:
function sketchProc(processing) {
// Override draw function, by default it will be called 60 times per second
processing.draw = function() {
// determine center and max clock arm length
var centerX = processing.width / 2, centerY = processing.height / 2;
var maxArmLength = Math.min(centerX, centerY);
function drawArm(position, lengthScale, weight) {
processing.strokeWeight(weight);
processing.line(centerX, centerY,
centerX + Math.sin(position * 2 * Math.PI) * lengthScale * maxArmLength,
centerY - Math.cos(position * 2 * Math.PI) * lengthScale * maxArmLength);
}
// erase background
processing.background(224);
var now = new Date();
// Moving hours arm by small increments
var hoursPosition = (now.getHours() % 12 + now.getMinutes() / 60) / 12;
drawArm(hoursPosition, 0.5, 5);
// Moving minutes arm by small increments
var minutesPosition = (now.getMinutes() + now.getSeconds() / 60) / 60;
drawArm(minutesPosition, 0.80, 3);
// Moving hour arm by second increments
var secondsPosition = now.getSeconds() / 60;
drawArm(secondsPosition, 0.90, 1);
};
}
var canvas = document.getElementById("canvas1");
// attaching the sketchProc function to the canvas
var processingInstance = new Processing(canvas, sketchProc);
Here a sketch function is created, similar to what the parser would produce. This function should take 1 argument, a reference to a processing object (i.e., the Processing runtime), which will be created by the Processing constructor. Any Processing functions or objects are accessible as properties of this object.
Once that function is complete, pass it, along with a reference to a canvas, to the Processing constructor (remember to use new).
Writing Documents that Combine Processing and JavaScript Code
One of the first questions people ask with Processing.js is whether they can read values from the document in which the Processing sketch is running, or vice versa. The answer is yes.
Processing.js converts Processing code into JavaScript contained in a function closure. The variables and functions you create are not attached to the global object (i.e., window). However, you can still get access to them.
Accessing JavaScript Objects from Processing
Since Processing code gets converted to JavaScript and run like any other function, all Processing code has access to the global object. This means that if you create a variable or function in a global script block, they are automatically accessible to Processing. Consider this example:
First the Processing file, mixing.pde:
String processingString = "Hello from Processing!";
void setup() {
printMessage(jsString + " " + processingString);
}
Next the web page:
Hello Web - Accessing JavaScript from Processing
<canvas data-processing-sources="mixing.pde"></canvas>
Here Processing.js allows the use of a variable and function declared outside the Processing code.
Mixing JavaScript and Processing
The previous example kept a clean separation between the JavaScript and Processing code, while loosening the boundary between the two. Because Processing.js converts Processing code to JavaScript, it's also possible to mix them directly. The Processing.js parser will leave JavaScript it finds within the Processing code unaltered, allowing developers to write a hybrid of Processing and JavaScript (NOTE: this is why we don't use a pure Processing parser approach in processing.js). Here is the previous example rewritten using this method:
var jsString = "Hello from JavaScript!";
var printMessage = function(msg) {
document.getElementById('msg').innerHTML = "Message: " + msg;
};
String processingString = "Hello from Processing!";
void setup() {
printMessage(jsString + " " + processingString);
}
There is some JavaScript syntax that can't be easily mixed this way (e.g., regex literals). In those cases you can simply move your pure JavaScript to a <script> block and access it using the method described above.
Accessing Processing from JavaScript
Reaching out from the Processing code to JavaScript is easier than going the other way, since the JavaScript created by the Processing.js parser is not exposed directly on the global object. Instead, you gain access using the Processing.instances property.
The Processing constructor keeps track of instances it creates, and makes them available using the getInstanceById() method. By default, when a <canvas> has a data-processing-sources attribute, its id is used as a unique identifier for the Processing instance. If no id attribute is provided, you can use Processing.instances[0].
After you have a reference to the appropriate Processing instance, you can call into it like so:
<!DOCTYPE html>
<html>
<head>
<title>Hello Web - Controlling Processing from JavaScript</title>
<script src="processing-1.0.0.min.js"></script>
<canvas id="sketch" data-processing-sources="controlling.pde"></canvas>