I don’t know about you, but I’m getting tired of wires. Let’s build something else. For starters, a simple particle system.
First the HTML:
[php lang=”HTML”]
[/php]
In the script file, we’ll use the jQuery document ready function to kick things off:
[php lang=”JavaScript”]$(function() {
// …
});[/php]
As for vars, we’ll of course need a reference to the canvas and context, its width and height. Then an array to hold the particles, something for the number of particles, a loop counter, and we’ll throw in a bounce variable to reverse the particles’ directions when they hit the walls. After that we can go ahead and grab our canvas reference with jQuery and then the context.
[php lang=”JavaScript”]$(function() {
var points = [], numPoints = 50, i, canvas, context, width, height, bounce = -1;
canvas = $(“#canvas”)[0];
width = canvas.width;
height = canvas.height;
context = canvas.getContext(“2d”);
// …
});[/php]
Now we can create the particles themselves. These are just going to be generic objects with x, y, vx, and vy properties. We’ll randomized both their positions and velocities.
[php lang=”JavaScript”]for(i = 0; i < numPoints; i += 1) {
points.push({x:Math.random() * width,
y:Math.random() * height,
vx:Math.random() * 10 - 5,
vy:Math.random() * 10 - 5});
}[/php]
We'll run everything in a loop with setInterval. We'll split it into two functions, update and draw. The update function will run the physics simulation - moving the particles, checking to see if they hit a boundary and bouncing them if so.
[php lang="JavaScript"]function update() {
var i, point;
for(i = 0; i < numPoints; i += 1) {
point = points[i];
point.x += point.vx;
point.y += point.vy;
if(point.x > width) {
point.x = width;
point.vx *= bounce;
}
else if(point.x < 0) {
point.x = 0;
point.vx *= bounce;
}
if(point.y > height) {
point.y = height;
point.vy *= bounce;
}
else if(point.y < 0) {
point.y = 0;
point.vy *= bounce;
}
}
}[/php]
The draw function will run through all the particles and draw a small circle on the canvas to represent that particle's position.
[php lang="JavaScript"]function draw() {
context.clearRect(0, 0, width, height);
var i, point;
for(i = 0; i < numPoints; i += 1) {
point = points[i];
context.beginPath();
context.arc(point.x, point.y, 2, 0, Math.PI * 2, false);
context.stroke();
}
}[/php]
And finally, we just need the setInterval call to run these two on a loop:
[php lang="JavaScript"]setInterval(function() {
update();
draw();
}, 1000/24);[/php]
You can see the whole JS function here: http://www.bit-101.com/jscanvas/mar15.js
And see the simulation in action here:
http://www.bit-101.com/jscanvas/mar15.html
Over the next few days, we’ll mess with this some more and see what we can come up with.
Nice, it’s interesting that the circles are draw every frame rather than drawn once and then moved. Is this method the best way for js or is it just the method you chose to implement this time? It does make sense though, and kind of elegant to just have the points store the info and recalculate positions and then draw it fresh each “frame”.
Here you draw explicitly, which is really powerful. You’ll see so when Keith hits the canvas.translate functionality in one of his next chapters.
Another way of looking at it, is to consider the drawing functionality being abstracted away by the DisplayObject in Flash.
Yeah, as crookedspoon says, the display list is actually a very high level abstraction. It’s much more common to see low level stuff where you draw things on every frame. OpenGL, DirectX, Processing, etc. all work this way. At some level, that’s what Flash is doing as well, just hidden away from you.
WOW! this runs fluid on my N270 netbook (FF4b), beatiful, can’t wait to see a more advanced demo, to see where it touches the limits of this CPU 😉