Monday, December 20, 2010
Let it Spoke.
Editor’s Note: Spoke wingman and resident minstrel Jeremy Crapsey mushes his huskies across the frozen white north in order to bring us an early yuletide gift. Nothing says “Nadolig Llawen” quite like a warm fire and some random math.
Just in time for the holidays, a winter wonderland has descended on Spoke. Instead of making you wait until Christmas, we thought we’d let you open up your present early and see just how we went about making this wintry snow globe animation.
Read instruction manual before use:
Use HTML and JavaScript (Flash is too bulky and obtrusive) for this project. Canvas and CSS3 are not good alternatives. Why? Because, we want to support as many browsers as possible with the least amount of work.
This animation will be viewable in all JavaScript-enabled browsers. Building in only HTML and JavaScript allows all smart phones, tablet devices, and any other product that works with Internet browsers to view this animation.
Assemble this project with small and simplistic code. Then, when the holidays are over, you can remove the code easily without damaging your site.
Assembling the project
Now the fun begins. Follow this basic outline for when you create your very own winter wonderland. Note that we used tween.js
-
Set up the scene: This is where you build your container box in HTML, setup scripts, and CSS styles for the background.
-
Build your snowflake: Construct your snowflake object which will be reused. We realize that no two snowflakes are alike, but to keep this simple, we used an ordinary circle. To give the illusion that they are not the same, simply change the size of the circle. Each image is 15 x 15 pixels rendered as a PNG.
var snowFlake = function(target){ /* Lets create a snowflake by using a div element with a background image. */ var div = document.createElement("div") ,random = Math.random() ,even = Math.floor(random*(2)); //default styles div.style.position = "absolute"; div.style.background = "no-repeat center"; div.style.backgroundImage="url('snow_flake01.png')"; div.style.width = "15px"; div.style.height = "15px"; div.style.top = "-15px"; //default settings div.random = random; div.x = 0; //lets have the snowflake start above the scene div.y = -15; //Main function used to update the //snow flakes position div.update = function(){ div.style.left = div.x+"px"; div.style.top = div.y+"px"; } //Used to update the image of the //snowflake div.setImage = function(image){ div.style.backgroundImage = "url('"+image+"')"; } //Used to reset the posistion of the snowflake div.reset = function(){ //moves the snowflake above the scene div.y = -15; } //Inserts the Div into the targeted Element target.appendChild(div); return div } -
The Population, randomization, and animation script: provides the three secret ingredients to create the illusion of a gentle snowfall. Let’s assign animation rules for each individual snowflake and populate it into our target element. Keep in mind that you must render the snowflakes with an aesthetically pleasing and smooth animation.
var renderSnow = function(opt,target){ /* Our “render snow” function here will populate the target element with snowflakes */ for(var i = 0;i<= opt.count;i++){ var flake = new snowFlake(target) ,xPos = flake.x = Math.random()*(400) ,random = flake.random ,fallSpeed = opt.fallSpeed+random*(1000) ,driftSpeed = opt.driftSpeed+random*(1000); //Set the current snowflake's image flake.setImage(opt.image); /* We use tween.js to propagate the snowflake position values. */ floatDown = new TWEEN.Tween(flake) .to({y:196},fallSpeed) //This runs the flake update command //on every refresh .onUpdate(flake.update); floatLeft = new TWEEN.Tween(flake) .to({x:xPos-30},driftSpeed); floatRight = new TWEEN.Tween(flake) .to({x:xPos+30},driftSpeed); floatDown .delay(i*opt.delay) .onComplete(flake.reset); //animation chians floatLeft.chain(floatRight); floatRight.chain(floatLeft); floatDown.chain(floatDown); floatDown.start(); //Lets mix it up a bit and //randomize the start animation. if(Math.floor(i%2)==0){ floatLeft.start(); }else{ floatRight.start(); } } } -
Animation loop script: To produce the illusion of animation, loop thirty times every second.
//Lets target our containment elements var frontLayer = document.getElementById("front_layer"); var backLayer = document.getElementById("back_layer"); /* Here we run our “render snow” methods. This allows us to create two separate layers of snowfall in our scene. Here you can add more snowflake layers to give a more "blizzard" effect. Adjust the speed and density of each layer by modifying the values (the larger the number the slower the speed). */ renderSnow({ image:"snow_flake01.png" ,driftSpeed:7000 ,fallSpeed:4000 ,count:10 ,delay:300 },frontLayer); renderSnow({ image:"snow_flake03.png" ,driftSpeed:7000 ,fallSpeed:10000 ,count:20 ,delay:500 },backLayer); /* This is where the magic happens. Our frame rate is set at 30fps: */ (function tick(){ /* Every time TWEEN.update(); is run, the values of the snow flakes we assigned tweens (TWEEN.Tween()) to. It will produce the next values in our tween animation, and update the CSS positions on our snowFlake objects. */ TWEEN.update(); setTimeout(tick,1000/30); }());
Once your project is successfully assembled and thoroughly tested, all that’s left to do is sit back and enjoy it.
We are.
Merry Christmas and a very Happy New Year.
Join the conversation