Skip to main content

Adding Sizzle With HTML5 Canvas

[lead]Many in the United States don’t know that there’s an American Football league in India. The Elite Football League of India (EFLI) recently expanded and the Navi Mumbai Sabres were a part of that expansion. We were commissioned with pulling together a teaser site for the new team.[/lead]
We wanted to create something remarkable for the team. Even though it’s a simple teaser site, the design was amazingly done, but we wanted to take it a step further. We used the HTML 5 canvas tag and some javascript to take it up a notch by adding some floating embers to give life to the page.

Navi Mumbai Sabres Teaser

Check out NaviMumbaiSabres.com to view the full effect.

Creating The Floating Embers

First place an HTM5 canvas tag within the HTML body.


<canvas id="embers"></canvas>

Give the element a width and height.


#embers {
	width: 500px;
	height: 500px;
}

We’ll be using javascript to create the interaction. First we declare some variables that we’ll use later on.


var canvas;
var stage;
var width;
var height;
var particles = [];
var mouseX = 0;
var mouseY = 0;
var speed = 1; // speed of particles
var max = 1000; // max lifespan
var amount = 50; // amount of particles
var size = 60; // size of particles

We then create an object to store our ember particles. This will include the position, speed, size, transparency level and how long each particle will be “alive”.


function Particle(x,y,xs,ys) {
	this.x = x; //x coordinate
	this.y = y; //y coordinate
	this.xs = xs; //x speed
	this.ys = ys; //y speed
	this.size = Math.floor(Math.random() * 12) + 6; //size
	this.alpha = Math.random()*1.2-0.3; //transparency
	this.life = 0; //age
}

Great. Now let’s initialize the canvas and set the stage for adding our content.


function init() {
	canvas = document.getElementById("embers"); // reference to the HTML element
	if(canvas.getContext) { //see if the browser supports canvas
		stage = canvas.getContext("2d"); //get canvas context to draw onto
	} else {
		//Or you can simply abort and not do anything at all.
		alert("Canvas not supported.");
	}
}

Now we need to set the rules for when, where and how the particles are to be creating and move around the new stage.


function update() {
	if (particles.length < amount) { // limits the amount of particles on the page based on the size of the canvas
		mouseX = Math.floor(((Math.random() * width) + (Math.random() * width)) / 2);
		mouseY = Math.floor(((Math.random() * height) + (Math.random() * height)) / 2);  // random x and y position within canvas
		speedZ = (Math.random()*2*speed)/100, 0-Math.random()*2*speed // random horizontal and vertical speeds within range
		var p = new Particle(mouseX,mouseY,speedZ,speedZ); // adds a new particle
		particles.push(p); // push new particle to the particles stack to be added to stage later
	}
  
	stage.clearRect(0, 0, width, height); //clear the stage before we draw new frame
	for (i=0; i<particles.length; i++) { //cycle through each particle and draw them	  
		//add some gradient to each particle, so it has a soft edge
		var gradient = stage.createRadialGradient(particles[i].x,particles[i].y,0,particles[i].x,particles[i].y, particles[i].size);
		gradient.addColorStop(0.2,"rgba(245,223,118," + particles[i].alpha + ")");
		gradient.addColorStop(1,"rgba(0,0,0,0)");
		stage.fillStyle = gradient;
	
		// raw the particle as a circle
		stage.beginPath();
		stage.arc(particles[i].x,particles[i].y,(max-particles[i].life)/max*(size/2)+(size/2),0,2*Math.PI); //circle gets smaller the longer it has been alive
	
		stage.fill(); //add to stage
	
		//move the particle based on the horizontal and vertical speeds
		particles[i].x+=(particles[i].xs + (Math.random() * 2))
		particles[i].y+=particles[i].ys;
	
		particles[i].life++; //increase the particle age
	
		if (particles[i].life >= max) { // remove particle is it is too old
			particles.splice(i, 1);
			i--;
		}
	}
}

Finally let’s add a timer in the init function so we can update our canvas each frame and run on page load.


$(window).on('load',function() {
	init();
});

function init() {
	canvas=document.getElementById("embers"); //reference to the HTML element
	if (canvas.getContext) { //see if the browser supports canvas
		stage = canvas.getContext("2d"); //get canvas context to draw onto
		var timer = setInterval(update,50); //update the particles every frame
	} else {
		//Or you can abort and do nothing.
		alert("Canvas not supported.");
	}
}

View the final result here or on CodePen.

See the Pen OPoKro by Matthan Heiselt (@matthan) on CodePen.

Notes

Because an animation loop can be intensive, it is recommended for use without a whole lot of other things going on. It may be wise to create a fallback for mobile to increase performance.

The canvas tag is not compatible with older versions of Internet Explorer, but we can add a javascript shiv to allow IE9 to use the element while IE8 and below will need a fallback image.


<!--[if lt IE 9]>
	<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
Share this article on
Walk West

Walk West

Our forward-thinking team stays up to date on industry trends and evolutions. Stay tuned as we continue to examine and share unique perspectives on these ideas. Check back for our thoughts on what’s new and upcoming.

Related Reading