JS1k: Original source
Unfortunately I haven't been able to put together another JS1k demo as I've had lots of 'real' work going on at the moment (boo!); so I thought I'd post a fully commented version of the JavaScript code for anyone who is interested to look over.
Some of the entries have been breathtaking, making my poor little demo look a little simple! Never mind. I look forward to looking over the uncompressed source of the other entries. There are just so many things to learn from them!
/**
* This uncompressed source is close to my entry submitted to JS1k.
* The number of particles and colours are different, but the rest is
* near enough the same. The code is structured in a much neater way.
*/
var animate = function(){
//Grab our canvas object and context
var canvas = document.getElementById('c');
var c = canvas.getContext('2d');
//Set the canvas width to the same as the browser
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//Make the body background black and hide the scroll bars
document.body.style.background = "black";
document.body.style.overflow = "hidden";
//Grab the width / height of the canvas for later use
var width = canvas.width,
height = canvas.height;
//Arrays used to store the position / speed / direction and radius of the particles
var posY = [],
posX = [],
speedX = [],
speedY = [],
directionX = [],
directionY = [],
radius = [];
return {
//Our initialise function
init: function(){
//Look at the width and generate a number of particles
for(i = 10; i < width; i += 30) {
//For each ballplace it in a random location
var generatedX = Math.floor(Math.random()*width);
var generatedY = Math.floor(Math.random()*height);
//Set the initial particle start positions
posX[i] = generatedX;
posY[i] = generatedY;
//Each particle has a random x and y speed
var generatedSpeedX = 1 + Math.ceil(Math.random()*8);
var generatedSpeedY = 1 + Math.ceil(Math.random()*8);
//Set the initial speeds
speedX[i] = generatedSpeedX;
speedY[i] = generatedSpeedY;
//Set the x and y directions of each particle
(Math.ceil(Math.random()*2) === 1) ? directionX[i] = 1 : directionX[i] = -1;
(Math.ceil(Math.random()*2) === 1) ? directionY[i] = 1 : directionY[i] = -1;
//Each particle has a different radius
radius[i] = 10 + Math.ceil(Math.random()*5);
}
//Fire our draw function every 10ms
setInterval(this.draw, 20);
},
//Fun this function to draw a frame
draw: function(){
//Clear the last frame by filling it black (clearRect caused issues in chrome)
c.fillStyle = "black";
c.fillRect(0,0,width,height);
//Loop through each particle
for(i=10;i<width;i+=30){
//Change its x direction if it gets to the boundry
if(posX[i] > width || posX[i] < 0){
directionX[i] *= -1;
}
//Change its y direction if it gets to the boundry
if(posY[i] > height || posY[i] < 0){
directionY[i] *= -1;
}
//Save the canvas settings before we modify anything (clip)
c.save();//Before path
//For each particle begin a path around its position
c.beginPath();
c.arc(posX[i],posY[i],radius[i],0,Math.PI * 2,false);
//Clip the path ready to be filled later
c.clip();
//Set the red radial gradient alpha to 1
c.globalAlpha = 1;
//Create our red radial gradient up the top left corner
var radGradRed = c.createRadialGradient(width/4,height/4,100,width/4,height/4,width/4);
radGradRed.addColorStop(0, 'red');
radGradRed.addColorStop(1, 'black');
c.fillStyle = radGradRed;
//Create a rectangle filled using the red radial
c.fillRect(0,0,width,height);
//Set the global alpha to 0.6 for the next box (so the red shines through)
c.globalAlpha = 0.6;
//Create our green radial gradient up the top right corner
var radGradGreen = c.createRadialGradient(3*width/4,height/4,100,3*width/4,height/4,width/4);
radGradGreen.addColorStop(0, 'green');
radGradGreen.addColorStop(1, 'black');
c.fillStyle = radGradGreen;
//Create a rectangle filled using the green radial
c.fillRect(0,0, width, height);
//Set the global alpha to 0.4 for the next box (red / green shines through)
c.globalAlpha = 0.4;
//Create our blue radial gradient at the bottom middle
var radGradBlue = c.createRadialGradient(width/2,3*height/4,100,width/2,3*height/4,width/4);
radGradBlue.addColorStop(0, 'blue');
radGradBlue.addColorStop(1, 'black');
c.fillStyle = radGradBlue;
//Create a rectangle filled using the green radial
c.fillRect(0,0,width,height);
//Restore the canvas to how it was before the clipping path
c.restore();
//Set the new x and y position of the selected particle
posX[i] += directionX[i]*speedX[i];
posY[i] += directionY[i]*speedY[i];
}
//Set the new global alpha to 0.9 for the static particles
c.globalAlpha = 0.9;
//Create a red particle top left
c.fillStyle = "red";
c.beginPath();
c.arc(width/4,height/4, 20, 0, Math.PI * 2, false);
c.fill();
//Create a green particle top right
c.fillStyle = "green";
c.beginPath();
c.arc(3*width/4, height/4, 20, 0, Math.PI * 2, false);
c.fill();
//Create a blue particle middle bottom
c.fillStyle = "blue";
c.beginPath();
c.arc(width/2, 3*height/4, 20, 0, Math.PI * 2, false);
c.fill();
}
};
}();
//Call the init function and get the particles moving
animate.init();Or for those of you who are a fans of jsFiddle I've pasted it here for you look at.