SEARCH
Get Our Free Ebook
Beginners Guide to HTML

Web Programming JavaScript Add Falling Snow using Java Script

# Add Falling Snow using Java Script

\$erjik JavaScript Dec 30, 2005

Have you ever seen the real snow, the enchanting dance of falling snowflakes? However, if you haven't been so lucky as to set your eyes upon this natural wonder, don't sulk, because this tutorial will show you how to create your very own Java Script snow on your own web page. It might look a bit less natural, but it will still preserve its winter magic. So, let us start!

For starters, let's initialize the variables that we'll need for the purpose. Here they are:

• Sn - The number of snowflakes. Don't get carried away with it, because a high number of snowflakes will require a lot RAM and therefore slow down your computer. The optimal number depends on the size of the snowflakes that you'll use: the smaller the flakes, the more of them you can create. I set their number to 12.
• x, y - the current position of a snowflake. You can move the flakes by changing these coordinates.
• wind, fall, rad - the variables, the value of which will be used to change the flakes' coordinates. Wind is the value for the x . Fall is the velocity of a falling snowflake and therefore the value for the y. We'll use the built-in mathematical function Math.cos() to estimate the path of a falling snowflake and as this function returns the cosine in radians, we'll need the variable rad .
• i - the variable for execution statements in loop.
• width, height - the variables to measure the height and the width of the browser window's content area.

Each snowflake will have its own values for all the variables responsible for its movement on the screen. We'll need the following bodies for these values.

 x = new Array(); y = new Array(); fall = new Array(); wind = new Array(); rad = new Array();

As real snowflakes differ in shape, we'll make several different snowflakes. I took some time beforehand to prepare a few flakes of different sizes and shapes. You should understand that it's no big deal to draw the snowflakes. It's much harder to save them afterward in .gif or .png format preserving the same transparency and the minute pattern details.

 function snowflakesload() { var args = snowflakesload.arguments; document.snowflakes = new Array(args.length); for (var i=0; i < args.length; i++) { document.snowflakes[i] = new Image; document.snowflakes[i].src = args[i]; } }

This function creates the necessary number of images depending on the parameters transmitted to it. I call this function the following way:

To make the script workable with different browsers, we need to use the function of determining the browser that the document loads in. We'll use the following code for Internet Explorer:

 var ie = (document.all)?1:0;

this one is used for Netscape 6 and Mozilla:

 var ns = (document.getElementById & & !document.all)?1:0;

The next step will give us the width and the height of the browser window that will show your page:

 if (ie) { width = document.body.clientWidth; height = document.body.clientHeight; } else if (ns) { width = self.innerWidth; height = self.innerHeight; }

Now let's move on to direct creation of snowflakes on a page. We'll need the following code to do this:

 for (i = 0; i < sn; i++) { x[i] = Math.random()*(width-50); y[i] = Math.random()*(height-50); fall[i] = 1+Math.random()*2; wind[i] = Math.random()*Math.PI-Math.PI; rad[i] = 0; document.write(" + document.snowflakes[Math.floor(Math.random() * document.snowflakes.length)].src + "" style="position: absolute; z-index: "+ i + "; visibility: hidden; top: 15px; left: 15px; filter:alpha(opacity=100); -moz-opacity: 1;" border="0">"); }

In each step of the cycle we'll need to set random values for variables that are responsible for the position and the velocity of a given snowflake on the screen. This shows the flake on a page.

The values width -50 and height -50 determine the area of the window where the snowflake will be placed. In this case we set the values of coordinates x and y to fit the height and width of the whole screen. If these values are changed to width/2 and height/2 , for instance, the snowflakes will be found only in the top left corner fitting into a quarter of the screen.

This code lets us choose in a random fashion one of the images from the document . snowflakes body:

 document.snowflakes[Math.floor(Math.random() * document.snowflakes.length)].src

To hide the snowflakes until the function of their movement is called, we'll use the following attribute:

 visibility : hidden ;

Now let's lay our hands on the most important function snow(), which will be moving our snowflakes:

 function snow() { for (i = 0; i < sn; i++) { y[i] += fall[i]; rad[i] += (wind[i]/180)*Math.PI; document.getElementById("snowflake"+i).style.left = x[i] + Math.cos(rad[i])*20; document.getElementById("snowflake"+i).style.top = y[i]; } }

Using the cycle for ( i = 0; i < sn ; i ++) , this function changes the position of each snowflake in the snowflake body for the values of x (vertically) and y (horizontally). To make the path of falling snowflake more realistic, the value of the x coordinate changes according to this formula: Math . cos ( rad [ i ])*20 where the argument of Math.cos() function can be changed with the help of this formula: rad [ i ] += ( wind [ i ]/180)* Math . PI ;

For interval running of this function, let's add a button to our page:

 Action:

It will call the following function:

 function onoff() { document.getElementById("fall").value=='Start' ? document.getElementById("fall").value='Stop' : document.getElementById("fall").value='Start'; if (document.getElementById("fall").value=='Stop') { snow_on=setInterval("snow()", 20); } else { clearInterval(snow_on); } for (i = 0; i < sn; i++) { document.getElementById("snowflake"+i).style.visibility = "visible"; } }

When clicking on the button, we'll change the text on it to "Stop" and will be constantly calling the snow() function with the 20 millisecond interval until we click on this button again, i.e. until the value of "Stop" doesn't change to the value of "Start."

As all our snowflakes are hidden, after launching we need to change their visibility property to "visible."

Also, the snow can be launched right during the loading of the page. To do this, you'll just need to slightly change the body tag on your page:

And now you'll probably exclaim - "Hey, Dude! Your snowflakes fly away from the screen and its makes scrollbars appear! That's sucks !" And I can ' t help agreeing with you . But this can be easily mended. We'll just need to use the following properties of the elements on your page offsetLeft and offsetTop that keep the distance (in pixels) between the left and the top edges of the parent element (in our case it's document ). offsetWidth and offsetHeight fix the height and width (in pixels) of the element itself, i.e. of the snow.

Now we need to determine the condition for checking the position of a snowflake. If the flake falls beyond the limits of the width and height values, we should generate a new snowflake instead with 0 for the y coordinate, so that this new flake appears right at the top of the document.

We'll need one more variable for the condition, let's say var out = 0; and the condition itself will look like this:

 if (document.getElementById("snowflake"+i).offsetLeft + document.getElementById("snowflake"+i).offsetWidth >= width-3 || document.getElementById("snowflake"+i).offsetTop + document.getElementById("snowflake"+i).offsetHeight >= height-3) {out = 1} else {out = 0};

Let's add these changes to our snow() function, and here's what we'll get:

 function snow() { var out = 0; for (i = 0; i < sn; i++) { y[i] += fall[i]; if (document.getElementById("snowflake"+i).offsetLeft + document.getElementById("snowflake"+i).offsetWidth >= width-3 || document.getElementById("snowflake"+i).offsetTop + document.getElementById("snowflake"+i).offsetHeight >= height-3) {out = 1} else {out = 0}; if (out) { x[i] = Math.random()*(width-50); y[i] = 0; fall[i] = 1+Math.random()*2; wind[i] = Math.random()*Math.PI-Math.PI; rad[i] = 0; width = ns ? window.innerWidth : document.body.clientWidth; height = ns ? window.innerHeight : document.body.clientHeight; document.getElementById("snowflake"+i).src = document.snowflakes[Math.floor(Math.random()* document.snowflakes.length)].src; } rad[i] += (wind[i]/180)*Math.PI; document.getElementById("snowflake"+i).style.left = x[i] + Math.cos(rad[i])*20; document.getElementById("snowflake"+i).style.top = y[i]; } }

There is a filter in the IE browser that allows setting the degree of opacity for a given page element: filter:alpha(opacity=70); Mozilla Firefox carries a similar filter -moz-opacity: 0.7; Let's try to add it to our script:

 Opacity:

This button will call the following function:

 function setopasity() { document.getElementById("opacity").value=='On' ? document.getElementById("opacity").value='Off' : document.getElementById("opacity").value='On'; for (i = 0; i < sn; i++) { if (document.getElementById("opacity").value=='On') { // sets random opasity values in IE and NS if (ie){ document.getElementById("snowflake"+i).filters.alpha.opacity = Math.floor(20+Math.random()*80); } else if (ns){ document.getElementById("snowflake"+i).style.MozOpacity = 0.2+Math.random()*0.8; } } else { if (ie){ document.getElementById("snowflake"+i).filters.alpha.opacity = 100; } else if (ns){ document.getElementById("snowflake"+i).style.MozOpacity = 1; } } } }

For IE we can change the property of each flake he following way:

 filters.alpha.opacity = Math.floor(20+Math.random()*80);

And this way for Mozilla Firefox:

 style.MozOpacity = 0.2+Math.random()*0.8;

Note : Opacity filter requires more system memory, so the script may run with lags.

Now let's throw some interactivity into our effect by creating a slight shift of the snowflakes' movement toward the cursor of the mouse. The further the cursor from the center of the document, the more actively the flakes will be following it.

To achieve this mouseover effect, we'll need to create one more button:

 Mouse catching:

 function mouseon() { document.getElementById("mouse").value=='On' ? document.getElementById("mouse").value='Off' : document.getElementById("mouse").value='On'; mX = 0; mY = 0; mXo = width/2; mYo = height/2; document.onmousemove = getMouse; function getMouse(e) { if(ns) { mX = e.pageX; mY = e.pageY; } else { mX = event.x + document.body.scrollLeft; mY = event.y + document.body.scrollTop; } mX = (mX - mXo)/(200); mY = (mY - mYo)/(600); return true; } }

mX, mY are the variables indicating the current position of the mouse pointer.

mX0, mY0 are the coordinates of the document center with the respective values width / 2 and height / 2.

To get the coordinate for the current position of the mouse cursor in our document, well need to call the function getMouse each time the document.onmousemove takes place;

Note that the event fires repeatedly, although the frequency of firing depends on the speed of the mouse motion and system resources.

Having received the mX and mY coordinates, we need to change them relative to the center and reduce these values dividing x values by 200 and y values by 600. Now we have to add these small values to the current values of the coordinates of our flakes. To do this, we'll need to add a code into the function snow() before we change the position of the flakes:

 if (document.getElementById("mouse").value == 'On') { x[i]+=mX; y[i]+=mY; }

The further the mouse is from the center, the more actively the flakes will be following it.. Also, the force of attraction will depend upon the figure, which you divide the coordinate by - the smaller the value, the more the snowflakes gravitate toward the cursor. You can feel the difference between their vertical and horizontal gravitation.

Well, the only thing left to do is add the ability to hide the snowflakes, so that your page is not completely buried in snow:

Again, we are adding a button:

 Visibility:

And we're finishing the last function of our "snowy" script:

 function hidesnow() { document.getElementById("showhide").value=='Show' ? document.getElementById("showhide").value='Hide' : document.getElementById("showhide").value='Show'; for (i = 0; i < sn; i++) { document.getElementById("showhide").value=='Hide' ? document.getElementById("snowflake"+i).style.visibility = "visible" : document.getElementById("snowflake"+i).style.visibility = "hidden"; } }

Well, That's all!

If you are lost in something, you can see everything in the full script below with detailed commentaries:

You can see the result of this script with these buttons:

 Action:     Opacity:     Mouse catching:     Visibility:

Happy New Year..!