Exploiting Processing.js by mixing Processing and javascript legally

Using Processing.js inevitably leads to the desire to mix in plain javascript with the Processing code, to make things happen in a webpage because of linked .js libraries, or custom js. The problem is that once javascript is added directly, Processing will no longer accept the sketch. This is inconvenient. However, there is a way to make this headache go away: write an interface!

The trick is to keep javascript and Processing code separate. In order for Processing to not complain, we need to call Processing methods, not javascript functions. How do we do this? Well, here's an example

in your javascript

	function myfunction(text, somenumber)
	{
		// do something with text and somenumber
	}
	

in your Processing sketch

	// if you're thinking "C style header file", or "java interface", you are thinking exactly the right thing
	interface JavaScript
	{
		// we promise Processing that a function with this signature will exist in objects that we say are of this type
		void myfunction(String text, float somenumber);
	}

	// sketch-global object that will point to the on-page javascript
	JavaScript javascript = null;

	// a method for binding the page's javascript environment to the in-sketch jsinterface object
	void setJavaScript(JavaScript js) { javascript = js; }

	// regular setup
	void setup() { ... }
	
	// regular draw, with a call to a function of which *we* know it's javascript, but
	// of which Processing thinks it's normal Processing code because of the interface "promise".
	void draw()
	{
		...
		if(javascript!=null) { javascript.myfuction("moo",45.657); }
	}
	

when you load your sketch, catch it!

	// create a Processing instance, and keep the reference so we can call public methods
	var pjs = new Processing(canvasid, "source code");

	// call the "set interface" method, in which we lie by saying "the argument we're passing
	// is actually a JSInterface object". In fact, it's the javascript "window" instance.
	pjs.setJavaScript(this);
	

Processing will now happily run your sketch, because even though you're calling a javascript function, you've told Processing that this function also exists, even though it does nothing natively, because of the JavaScript interface. Because there is no type validation when calling sketch methods directly from javascript, we can pass a reference to javascript's "window" object to the sketch as if it counts as a JavaScript object, so javascript won't complain either.

And to show that it actually works, an example. Have a look at the sketch code here, the javascript functions it will call here, and the bit of loader javascript here (do try to run this sketch from Processing too!). In Processing, all you see is a circle going round on a plain background. However, there are "javascript" calls in the code that also write a log entry whenever the circle has gone round a full iteration, and a constant changing of the <canvas> border width as the draw() method is being called. These will do absolutely nothing in Processing, but embedded on a webpage these will trigger the corresponding javascript functions.


[one entry per full iteration]