HAIL JS

Hey Guys,

I wish Happy New Year to all and Hope your Christmas and New year was amazing. Now During the Christmas week and New Year, wordpress introduced a new feature to make your website christmas-sy. You could see snow falling from the sky or to the top of the website to be precise.

So in this tutorial, We will learn how that system is build and how does it work.

First of all, a brief introduction to what we are building.

We want small snow flakes falling from the top of the window to the bottom and it should feel natural. Since It’s just an addon to the original website. We want minimal coding required to activate this feature. So the process to activating this feature should be including a JS file in the DOM and one line calling the funcionality (optional). Now we can also make the JS file call itself automatically but this way, users cannot configure the feature. So if you don’t want the user to change anything in your code then you can call the funcionality inside the JS file. Also the spped and direction of the flakes can be changed as according to the mouse position to create a more realistic hail effect.

We will call Hail.js the file that needs to be included inside the DOM. This time we will using jQuery library to ease up our coding experience so include jquery inside the project. This is optional as you can also build it without jQuery.

HAIL JS

We will start with setting some of the configurations we will be needing later in project.


	var CONF = {};

	/* INFINITY TIME FLAG */
	CONF.REPEAT_INFINITE = -1;

	/* Speeds Constants */
	CONF.SLOW_SPEED = 20;
	CONF.DEFAULT_SPEED = 50;
	CONF.FAST_SPEED = 80;

	/* Step Constants */
	CONF.SMALL_STEP = 10;
	CONF.DEFAULT_STEP = 15;
	CONF.LARGE_STEP = 20;

	/* Size Constants */
	CONF.SMALL_SIZE = 2;
	CONF.DEFAULT_SIZE = 3;
	CONF.LARGE_SIZE = 5;

	/* Delay Constants */
	CONF.SMALL_FREQUENCY = 5;
	CONF.DEFAULT_FREQUENCY = 10;
	CONF.LARGE_FREQUENCY = 15;

We will be using Objects. Now the parameters are self explanatory. We will provide user these parameters to configure the application.

The REPEAT_INFINITY Flag is used to denote that applications needs to be running at all times.
The SPEED Flags denote the frames per second associated with each Snow Flake. We will provide random speeds to each flake withing these constraints.
The STEP Flags denote the distance in pixels travelled by the flake in one frame.
The SIZE Flags denotes the size of the flake.
The FREQUENCY Flags denote the number or frequency of new flakes produced in one second.

With this out of the way, Now We will create Hail Method. It will take an object to configure the application.


var Hail = function(vars) {
	...

Setting up some local flags


	...

	/* STOP Flag */
	this.stop = false;

	/* Mouse Coordinates */
	this.currentMousePos = { x: $('body').width() / 2, y: $('body').height() / 2 };

	/* Offsets */
	this.leftOffset = 0;

	/* Step */
	this.step = CONF.DEFAULT_STEP;

	...

Updating user preferences according to the arguments


	...

	/* Parameters */
	this.time = vars.time ? vars.time : CONF.REPEAT_INFINITE;
	this.color = vars.color ? vars.color : 'white';
	this.speed = vars.speed ? vars.speed : CONF.DEFAULT_SPEED;
	this.frequency = vars.delay ? vars.frequency : CONF.DEFAULT_FREQUENCY;
	this.size = vars.size ? vars.size : CONF.DEFAULT_SIZE;

	...

Now call the make() method that we will define later. We will also keep track of the mouse position.


	...

	/* Let it snow..let it snow.. */
	var self = this;
	setTimeout(function () {
	   	requestAnimationFrame(function() {
	   		self.make();
	   		self.mousePosition();
	   	});
	}, 0);

	...

If the user wants the application to stop after “time” milliseconds, we will add a stopping mechanism. The stopping mechanism is not ran if the flag REPEAT_INFINITY is set.


		...

		/* Stop it */
		if(self.time != CONF.REPEAT_INFINITE) {
			setTimeout(function () {
			   	requestAnimationFrame(function() {
			   		self.destroy();
			  	});
			}, self.time);
		}

	}

The destroy method is very simple. Remember the stop flag we set up earlier? The destroy method just set the stop flag.


	Hail.prototype.destroy = function() {
		this.stop = true;
	}

We will also use random method. So let’s introduce another method to ease up that process. it returns an integer between the range [min, max].


	Hail.prototype.getRandom = function(min, max) {
		return Math.floor(Math.random() * (max-min) + min);
	}

Now let’s make the … well make method. First thing we will check that if the stop flag is unset or not. This allow us to stop the application by setting the flag.


	Hail.prototype.make = function() {
		if(this.stop) return;
		...

We will use span tags to denote flakes. You can use any tag as we will be overriding it properties.


	...

	var self = this;
	var span = $('<span />', {
		class: 'hail'
	});

	...

Get the step associated with flakes with random method we defined earlier. The step must be between MIN_STEP and MX_STEP as defined in CONF object.

	...
	
	var spanStep = self.getRandom(CONF.SMALL_STEP, CONF.LARGE_STEP);

	...

Now align the hail on the top of the document as random left property so the flakes are positioned randomly on the top of the screen.


	...

	span.css({'background': this.color});
	span.css({'left': self.getRandom(0, $('body').width())});
	span.css({'top': '-10px'});
	span.css({'height': this.size + 'px', 'width': this.size + 'px'});

	...

Append the span to the DOM. and make a call to HandleInterval method responsible for moving the flakes accross the screen.


	...

	setTimeout(function() {
		self.HandleInterval(self, span, spanStep);
	}, (1000 / self.speed));

	$('body').append(span);

	...	

Finally, Make a recursive call to make method to create more flakes.


		...

		setTimeout(function () {
		  	requestAnimationFrame(function() {
		  		self.make();
		   	});
		}, 1000/this.frequency);
	}

Before moving to HandleInterval method, we wil define the mouse position handler. This method sets the value of the leftOffset property of Hail object. In short this tells us the distance the hail has to move horizontally according to the change in mouse positions.


	Hail.prototype.mousePosition = function() {
		var self = this;
	    $(document).mousemove(function(event) {

	    	if(event.pageX > self.currentMousePos.x) {
	    		// on to the right
	    		self.leftOffset = (event.pageX - self.currentMousePos.x) % ($('body').width() / 2);
	    	} else {
	    		// on to the left
	    		self.leftOffset = (event.pageX - self.currentMousePos.x) % ($('body').width() / 2);
	    	}

	        self.currentMousePos.x = event.pageX;
	        self.currentMousePos.y = event.pageY;
	    });
	}

Now we can tackle HandleInterval method head on.


	Hail.prototype.HandleInterval = function(self, span, spanStep) {
		requestAnimationFrame(function() {
			var topPosition = parseFloat(span.css('top'));
			var leftPosition = parseFloat(span.css('left'));
			...

Getting the top and left values associated with the flake.The top value is incremented by STEP property and left value is incremented by the leftOffset property. If the flake crosses the bottom, left or right part of the screen, we want the flake to be destroyed.


		...

		if(topPosition >= $('body').height() || leftPosition < 0 || leftPosition > $('body').width()) {
			span.remove();
			return;
		} else {
			span.css({'top': topPosition + spanStep + 'px', 'left': leftPosition + self.leftOffset + 'px'});
		}

		...

Finally Call itself recursively as per the SPEED property.


		...

		setTimeout(function() {
				self.HandleInterval(self, span, spanStep);
			}, (1000 / self.speed));
		});
	}

That’s it. Now The styles associated with the flakes can be integrated inside the JS file itself but it is borderline the defination of messy code. So we will define the styles inside hail.css file

CSS

	
	span.hail {
		display: block;
		width: 5px;
		height: 5px;

		border-radius: 50%;
		box-shadow: 0px -1px 2px 1px #EEE;

		position: absolute;
		top: -10px;

		-webkit-transition: all 100ms linear;
		transition: all 100ms linear;

		background: #ffffff; /* Old browsers */
		background: -moz-linear-gradient(top,  #ffffff 0%, #e5e5e5 100%); /* FF3.6-15 */
		background: -webkit-linear-gradient(top,  #ffffff 0%,#e5e5e5 100%); /* Chrome10-25,Safari5.1-6 */
		background: linear-gradient(to bottom,  #ffffff 0%,#e5e5e5 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
		filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#e5e5e5',GradientType=0 ); /* IE6-9 */

	}

Finally we arrive at HTML part where the user configure the application for themselves.

HTML


	<script type="text/javascript" src='script/jQuery.js></script>
	<script type="text/javascript" src='script/hail.js'></script>

The jQuery and hail.js file included inside the body of the DOM so that it doesnt conflict with the loading of the page.


	<script type="text/javascript">
		new Hail({
			frequency: 2
		});
	</script>

And we are at the end of the tutorial.

The source code is available at github and live preview here.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s