Heard about this "js1k" competition from reddit and was excited seeing all the great demos that people have submitted, so I gave it a shot myself. I wanted to make something similar to the background I created for PriceCheck and I really learned a lot doing it.

Got the idea for this from Context Free Art where you can create artwork using only primitive objects.

The artwork
Tree & Grass
The Tree & Grass are simple recursive box generator. It uses the translate/scale/rotate function in canvas to move around where the boxes should be drawn.Got the idea for this from Context Free Art where you can create artwork using only primitive objects.
var scale = 1;
function execute(y, size, rotate) {
canvas_context.save();
canvas_context.rotate(rotate);
canvas_context.translate(0, -y);
canvas_context.scale(size, size);
scale *= size;
tree();
canvas_context.restore();
scale /= size;
}
function tree() {
// If the size of the current rendering state is too small, stop rendering
if (scale > 0.04) {
// Once in a while split the branches in 2
if (rnd(1) < 0.04) {
execute(0, 0.7, -0.15);
execute(0, 0.7, 0.15);
}
else {
// Draw our tree using a box
canvas_context.fillRect(0, 0, 9, 9);
// Keep moving the tree further infront
execute(4, 1, (rnd(1) < 0.5) ? 0.08 : -0.08);
}
}
}
The moon
Its just one big radial gradient with 3 points. This adds the most to the scene.Shooting stars
To achieve shootings stars we need 3 canvases.- Stars: Draw the tip of the stars here randomly
- Stars_Tmp: Storage position to help move canvas 1 pixels diagonally and save back to canvas 1 every frame.
- Display: Draw the "Stars" canvas every frame & applies a very transparent black fill over the whole thing, this makes the previous positions of the stars fade out and gives it a trailing effect
// Give the display a black background
display.fillStyle = "#000";
display.fillRect(0,0,screen_width, screen_height);
setInterval(function () {
// Copy Stars to the tmp
stars_tmp.clearRect(0,0,screen_width,screen_height);
stars_tmp.drawImage(stars.canvas, 0, 0);
// Copy stars_tmp back to Stars, but with a difference in position of the stars
stars.clearRect(0,0,screen_width,screen_height);
stars.drawImage(stars_tmp.canvas, -1, 1);
// Draw a slight transparent black screen to fade, and then draw the stars
display.fillStyle = "rgba(0,0,0,0.1)"
display.fillRect(0,0,screen_width, screen_height);
display.drawImage(stars.canvas, 0, 0);
// Add new stars
if (Math.random() < 0.1) {
stars.fillStyle = "#FFF";
stars.fillRect(Math.random()*screen_width, 0, 3, 3);
}
}, 10);
Parallax effect
The moon, stars, trees & shooting stars are all on their own canvas objects, so every frame those canvases are just stitched together. To give the parallax effect I had to make each canvas object with a different width, this allows for moving one faster then the other using their own width as the speed property.Tricks for minification
- Google Closure Compiler & jscrush: Use it.
- After using Google Closure Compiler, go through the code and minify yourself, no software is as creative as you, you can do better.
- Property Shortening: Iterate through a objects property and give each property a new shortened name.
for (property in cavas_context) { canvas_context[(property[7] || property[0]) + (property[11] || property[2])] = canvas_context[property]; }I had to go through many iterations till I found an algorithm with least amount of collisions. This code had these property names:- createLinearGradient == al
- canvas == cn
- drawImage == ga
- clearRect == ce
- translate == ta
- If you don't use jscrush, doing a search and replace for "function" and ");" and replacing it with a letter helps.
- Decimal numbers doesn't need a 0 in front of them. So 0.1 can be changed to .1
- 'var' keyword, you can go without it. Just assign a value to a variable name before you look it up and it will be created in the global scope.
- Really need a local variable? Use the function parameters to define it.
- Most importantly, reuse your code, make every character count.