June 11th, 2008
The always-excellent Aza Raskin had a little bit of fun recently - inspired by my recent Processing.js work - to port the popular Context Free Art language to JavaScript, using Canvas.
Renamed Algorithm Ink the result is a complete way to programmatically generate elegant pieces of artwork. Aza took the result a step further and built an in-browser IDE, gallery, and real-time result viewing. It appears to work best in Firefox 3, from my initial testing.
The result of one piece might look like this:
But that's the beauty since you'll likely never get the same piece of art twice. All works are seeded with a bit of randomness in order to create unique works. For example here is the CFA code that generated the above image:
startshape scale
rule scale{
SPIKES{ s .03 }
}
rule SPIKES {
SPIKE {}
SPIKE { r 90 }
SPIKE { r 180 }
SPIKE { r 270 }
}
rule SPIKE {
LSPIKE {}
}
rule SPIKE {
LSPIKE { flip 90 }
}
rule LSPIKE {
SQUARE {}
LSPIKE { y 0.98 s 0.99 r 1}
}
rule LSPIKE 0.005 {
SPIKE { r 90 }
SPIKE { r -90 }
LSPIKE { y 0.98 s 0.99 r 1}
}
rule MOUSECLICK{
SPIKES{ s .025 }
}
The code is quite simple - just a set of rules that are initiated and seeded based upon a few parameters. More information can be found in the Context Free Art documentation.
Of course the entire Context Free port is open source: contextfree.js. Looking through the source you'll note that the result is much more math-heavy than Processing performing frequent matrix-based transformations to the display. The result, however, is that pieces written in CFA (as shown above) involve much less, obvious, mathematical calls and is a much-purer result.
I think this particular port shows a ton of promise: It shows that it's possible to create elegant works using JavaScript while doing it in a completely standards-based way. I'm excited to see people start to play around with this - I think it shows a lot of promise.
Tags: visualization, javascript
8 Comments on 'Algorithmic Ink in JavaScript'
May 14th, 2008
It's been fascinating to watch the outpouring of interest and creativity that's surrounded the recent release of Processing.js.
First things first, the project has been moved over to Github. This will help with the collaboration/patching process going forward.
A number of patches have already been provided by active users and have been merged into the main code base (which can be found in the project history).
Some of the changes that were made:
- Virtually all of the demos now work in Webkit (save for the text rendering ones) in addition to Firefox 3.
- Chris Davenport provided support for QUADS, QUAD_STRIP, TRIANGLE_FAN, and TRIANGLE_STRIP implementations in beginShape/vertex. Also endShape(CLOSE) support was added.
- Renato Formato provided a patch for handling curveVertex and curveTightness correctly.
- A patch from Felipe Gomes includes the addition of the LEFT/CENTER/RIGHT and mouseButton globals. The contextmenu is now prevented, as well, from right clicks. Additionally, a new init.js file was created (which is more robust than what was initially provided).
I've pulled together a quick round-up of the different, interesting, posts, demos, and projects that I've found, relating to Processing.js.
Getting Started
Will Larson has written a series of articles that detail how to best get started playing with Processing.js:
Additionally, the basic demos have been broken down and included in an interactive wiki.
Demos
A number of new demos have been created, at this point. Here's a couple that I thought were pretty interesting.
IDEs
There's been some significant effort towards creating an interactive development environment for Processing.js.
Press / Blogs
There was a bunch of feedback concerning the project release - overwhelmingly positive, as well. Some of my favorite responses thus far:
Wired: "We cover a lot of language and software developments here at Compiler, but this might be the most impressive thing we've ever seen."
Chris Blizzard: "Easy to drop in graphical interactive elements into other sites with the same transparency and zero-barrier to learning we’ve seen from the rest of the web. Think about how fast that stuff might spread on the web, how we might end up with people sharing and learning together and how much better the experience on the web might be in the end. That iterative process is one that needs starting points and what John has done is give us a great starting point. "
Andy Baio: "one of the most amazing hacks I've ever seen... could Processing.js be the beginning of the end for the closed-source culture of rich media tech?"
Also: Scott Hanselman, Kottke, Simon Willison, Peter Kirn, and Ajaxian.
It also made a bunch of social sites (with some interesting discussion taking place): Slashdot, Digg, Y Combinator News, Del.icio.us (2), and Reddit.
Tags: processing, visualization, javascript
10 Comments on 'Processing.js Aftermath'
April 7th, 2008
This weekend I gave two talks at BarCamp Rochester (which was very well put together and quite enjoyable) - one on jQuery and a very quick one on the Processing language. I've deconstructed my slides into some bullet points here. If you're not familiar with the language, or what it's capable of, this should give you a good overview.
Processing is a data visualization programming language.
It has three components:
- The Processing language
- The Processing drawing API
- The implementation (in Java - can optionally pass the drawing API through to OpenGL).
The Processing Language and API
- Strictly typed
- Has classes, inheritance
- Includes a bunch of globally-accessible functions (the drawing API - very flat and PHP-like).
Basic Program Structure
Two core methods: setup() and draw()
- Very OpenGL-like
- draw() is called continually at a specific framerate (if none is specified then it goes as fast as possible)
Simple example: Drawing a continuous line with the mouse.
void setup
() {
size
(200,
200);
background
(102);
}
void draw() {
stroke(255);
if(mousePressed) {
line(mouseX, mouseY, pmouseX, pmouseY);
}
}
Initialization
- setup() is called initially
- size(...) - set the width/height of the drawing area
- Can include calls to any other number of methods, such as: background(...) - (which draws and fills a background with a specified color).
- Note: All colors are done in RGBA. background(102) is equivalent to background(102,102,102,255) (opaque gray color)
The draw() loop
- draw() gets called as fast as possible, unless a frameRate is specified (with framerate(20), for example). You can disable any looping by calling noLoop().
- stroke() sets color of drawing outline (the color of lines, points, and the outsides of polygons)
- fill() sets inside color of drawing (inside of polygons)
- mousePressed is true if mouse is down
- Very different from typical asynchronous events - since program keeps looping we get state updates automatically. (Unless you specify mousePressed as a global function - then it'll be called as a callback.)
- mouseX, mouseY - mouse position, pmouseX, pmouseY - previous mouse position in last draw() call
Drawing
Different drawing methods: line(), rect(), arc(), ellipse(), point(), quad(), triangle(), bezier(), etc.
All use stroke(), strokeWeight(), and fill().
Can also draw complex polygons using beginShape, endShapre, and vertex - like in this example.
fill(127);
beginShape();
for (int i=0; i<segments; i++){
vertex(ground[i].x1, ground[i].y1);
vertex(ground[i].x2, ground[i].y2);
}
vertex(ground[segments-1].x2, height);
vertex(ground[0].x1, height);
endShape(CLOSE);
The Canvas
Very OpenGL-like. You can mutate the canvas rendering using: translate(), scale(), and rotate().
You can also save and restore the state of the canvas using: pushMatrix() and popMatrix().
A basic example using pushMatrix/popMatrix: A movable arm.
Classes
Can hold data, do inheritance.
Example: Bouncing an object off of rocky terrain
class Ground {
float x1, y1, x2, y2, x, y, len, rot;
Ground(){ }
Ground(float x1, float y1, float x2, float y2) {
this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2;
x = (x1+x2)/2;
y = (y1+y2)/2;
len = dist(x1, y1, x2, y2);
rot = atan2((y2-y1), (x2-x1));
}
}
Math
A whole mess of math functions are provided, as well: dist(), map(), constrain(), abs(), floor(), ceil(), random(), noise(), atan2(), cos(), sin(), pow(), sqrt(), radians().
Images
Can be used to load in external images. Example: Animation of guy dancing.
int numFrames = 12; // The number of frames in the animation
int frame = 0;
PImage[] images = new PImage[numFrames];
void setup(){
size(200, 200);
frameRate(30);
for(int i=0; i<numFrames; i++) {
String imageName = "PT_anim" + nf(i, 4) + ".gif";
images[i] = loadImage(imageName);
}
}
void draw() {
frame = (frame+1)%numFrames;
image(images[frame], 0, 0);
}
Demos
Some fun demos that I really like:
- Zipdecode - rendering all zipcodes in the country and searching them in real time.
- Substrate - rendering a piece of art.
- Genetic Trees - selectively breed and mutate trees.
- World is not round - live VJing a song using Processing and a set of physical input controls.
Books
Tags: graphics, processing, data, visualization, barcamp
9 Comments on 'Overview of Processing'
April 13th, 2005
I wrote a new visualization for IM user data today. The following image shows a two-week composite view of a user and its buddies. To acheive this, I essentially took a 24 hour view from a user, added an opacity, and layered each day on top of each other. The result is this interesting composite view that's really informative. (The darker the area, the more active the user is during that time period) I later added in the ability to drag-and-drop users, to make it easier to compare one user to another. We will probably be launching this service very soon - I'll be sure to let everyone know when that is.
Tags: visualization, imscan, images, projects, im
1 Comment on 'New IM Status Visualization'