Wednesday, December 7, 2011

animation nation part 1: processing.js


At work we thought it might be cool if we could jazz up the following bit of pseudo DNA (using Alleyoop's colors as the crossbars) that we are using during our signup process.

I wondered if we could get a nice little 3D-ish effect by treating the helix strands as sin curves and then animating them by increasing the angle (Hey remember the into to Superman II ?  Around 9 seconds in, the awesome spinning prison rings are actually 2 rings permanently welded together and then rotated as single unit... an awesome economical visual effect.)

My goto language for this kind of thing is Processing. Processing is a little Java IDE and API that makes making applets really easy, and lets me leverage my 10-odd years of Java experience in a way that works on most any browsers to make gamejam games and my own toys. (With applet supporting waning over the years, I'm happy to see stuff like Minecraft exercising Java as a viable game platform.)

An applet would be overkill for the task (not to mention raising the spectre of Content-y and plugin warnings) so I turned to Processing's little brother Processing.js. It's an HTML5, javascript/canvas based version of Processing. It has 2 modes: one where it can (try to) run the exact same ".pde" files as the Java version, and another where it acts as a highpowered API to the canvas object for more traditional javascript code. I knew Processing.js might not be acceptable for use on our actual site, since it depends on the canvas object that is only now getting support by IE, but I decided to give it a whirl anyway.

The pde "run the java code" mode is in preferred, but for my money it's not ready for prime time. It is essentially using a preprocessor to translate Java code into javascript, and the results aren't always pretty, especially for stuff involving classes and collections of mixed object types. The error messages are often extremely opaque or absent altogether.

Despite the problems, Processing.js is still a lot of fun, especially with one of the inbrowser IDEs like sketchpad.cc. You can type code and almost instantly see results, part of the charm of both versions of Processing.

Nearly every Processing program has two main parts: setup(), where one time activities are performed, and draw() which is called every frame. Most Processing programs (at least the ones I've written) clear the background every frame and draw the entire frame from scratch, but some just keep drawing on the same canvas.

Here's what I came up with. Apologies for the code that follows -- it's mostly hacking around proof-of-concept stuff, and there are a lot of "magic numbers" there I tweaked to make it look good... not exactly like the model, but enough to see that a spinning 3D effect could emerge from a sine wave fragment place against the flipped version of itself and constantly having its starting angle increased. Essentially the variable x1 runs through the horizontal values, x2 is the next value (for drawing line segments) and we get the two y values by running the sin() function. And then at certain x1 values, we draw the cross pieces.


void setup() {
    size(200, 200); 
    smooth();
    frameRate(30);
    strokeWeight(10);
} 
float off = 0;
void draw() {  
background(255);
pushMatrix();
translate(120,0);
rotate(3.14 / 4);

off += .1;
for(float x1 = 0; x1 < 120; x1++){
    float x2 = x1 + 1;
    float a1 = off + x1 / 40;
    float a2 = off + x2 / 40;
    float y1 = 20 * sin(a1);    
    float y2 = 20 * sin(a2);    
 
    if((x1 +1) % 31 == 0){
       stroke(255,0,0);
       line(x1,100,x2,y2+100);
       line(x1,100,x2,-y2+100);
    }
    stroke(128);
    line(x1,y1+100,x2,y2+100);
    line(x1,-y1+100,x2,-y2+100);
}
popMatrix();
 
}


Here's the result (IE users are out of luck, in this way and in so many others...)


Not half bad if I do say so myself! The effect was very sensitive to little tweaks.

Next up: the same idea in Raphael.js... a very different tool that works on all the major browsers.

No comments:

Post a Comment