HowTo: Processing.js in iOS

February 5th, 2011 § 5 comments

Processing.js is a great Javascript-port of the processing language that has reached the version 1.0 milestone a few months ago and allows the easy creation of visually-appealing interfaces. Plus, being based on Javascript and HTML5 it promises the mythical ‘Write once, run anywhere’, even on mobile devices that don’t support Java.

For a recent multi-platform visualization project I wanted to use processing.js so I wouldn’t have to write everything twice. Unfortunately, however, getting processing.js to run on the iDevices doesn’t seem to be that easy. Projects like iProcessing run processing code on the iPhone, but only there (the regular desktop webbrowser version needs additional work). There also exist dedicated rewrites of processing.js that bring with them the disadvantage of every fork: For every update of processing.js, the wrapper also needs one.

Fortunately, it is pretty easy to use any version of processing.js on iOS simply by using a suitable HTML skeleton. Necessary steps are:

  1. Transform touch events to mouse events
  2. Keep MobileSafari from scrolling/zooming

First, we have to let the processing-canvas catch all touch events, so we can call the corresponding processing-functions. We do that simply by adding the corresponding event handlers to it:

id="sketch" data-processing-sources="sketch/sketch.pde" width="320" height="480" autofocus></canvas>

Then, we have to write some javascript that converts the touch coordinates to processing’s internal mouse coordinates. We also want to call here the corresponding mouse-function (mousePressed for touchStart and so on). Finally, we also have to keep MobileSafari from using the touch events for scrolling, which is done by calling event.preventDefault() for each event:

<script type="text/javascript">

var processingInstance;

function setProcessingMouse(event){
if (!processingInstance) {
processingInstance = Processing.getInstanceById('sketch');

var x = event.touches[0].pageX;
var y = event.touches[0].pageY;

processingInstance.mouseX = x;
processingInstance.mouseY = y;

function touchStart(event) {

function touchMove(event) {

function touchEnd(event) {

function touchCancel(event) {


Here is the complete HTML-skeleton. Make sure that you have processing-1.0.0.min.js in the same directory (you can download it from and a processing-sketch in ‘sketch/sketch.pde’.

Some caveats: Multi-touch is not supported (all touches beyond the first are ignored) and advanced processing features such as video or 3D probably don’t work. But you can use this barebone-HTML to get your processing-sketches on the web – on all devices.

Tagged , , , , , ,

§ 5 Responses to HowTo: Processing.js in iOS"

  • Nice post. We’re adding proper touch event support for iOS in Processing.js 1.1, and have a patch written now. Let us know if you find other issues, and file bugs. We’d love to have it work well on these devices.

  • […] Howto: ProcessingJS in iOS […]

  • selvam says:

    TouchEnd event are not working in Android mobile applications

  • Leeroy says:

    Was getting Cannot read property ‘pageX’ of undefined
    Switched to

    var x = event.changedTouches[0].pageX;
    var y = event.changedTouches[0].pageY;

    in function setProcessingMouse(event)

  • Hi! I found this post and used your code on my website because the sketches weren’t working on my safari iOS. Still It doesn’t work quite right. When I run it on desktop the mouseX and mouseY coordinates work just fine, but on mobile the sketch takes the coordinates of the touch event relative to the coordinate 0,0 of the whole page instead of the 0,0 of the canvas. The finger doesn’t match the ellipse on mobile!

    Here’s the live code

    Do you have any idea how I can fix it so that the coordinates match?

Leave a Reply

Your email address will not be published. Required fields are marked *

What's this?

You are currently reading HowTo: Processing.js in iOS at Augenmusik.


  • noise

    Error: Twitter did not respond. Please wait a few minutes and refresh this page.