HTML5 is new technology that is developed as a replacement for current HTML standard. HTML5 brings so many improvement that not exists in current standard HTML. Canvas is one of the most important element of HTML5. This new element allows us to draw directly and manipulate any pixels on canvas. The canvas has a context that provides us cool high level API to help us when drawing onto canvas.
In this tutorial we’ll try to create a simple animation effect using HTML5 canvas. Although the animation we’ll create is just a simple animation, but it’s pretty cool to see. Here is a screenshot of the final animation. If you want to see it lives, you can see the final animation by clicking Live Preview button above.
Basic Idea
When you see the animation, may be you think it’s difficult to create such animation. As I stated before, this is simple and easy to create the animation like that. The idea is creating invisible particles with random location on the canvas then move every particles randomly. As the particles moved, we check the distance between particles, if the distances is less than, say 230 pixels, we create random color line. Then the logic is repeated.
Define Canvas Object
We’ll work on HTML5 canvas, so we must define it first.
<div style="width:800px;padding-top:20px; margin:0 auto;"> <canvas id="canvas" width="800" height="500"></canvas> </div>The context of the canvas can be gotten by invoking [cci]getContext(‘2d’)[/cci] on canvas object. This will give us the 2d context.
// get canvas element var canvas = document.getElementById('canvas'); if(!canvas.getContext) { alert("Your browser doesn't support html5"); return; } // get drawing context ctx = canvas.getContext("2d");Define Particle Object
For simplicity and easy to manage the particles, we create a javascript object which represent a particle. Our particle has the following properties:
- Position
Position property define the particle’s location on the canvas. It contains [cci]x[/cci] and [cci]y[/cci] variables which represent the particle’s coordinat on the canvas. The position property will be generated randomly.- Radius
Radius property defines the particle radius. Because we want to create an invisible particle, we’ll put [cci]0[/cci] as radius value.- Speed
Speed property determines how fast a particle can move- Color
Color property determines particle’s color. Because we want to create an invisible particle, this property will be used to color the line that connecting this particle with others. This property will be generated randomly- Steering Angle
Steering angle determines the particle’s movement direction. Steering angle has range from 0 to 360 and will be generated randomly.Below is the particle object definition on Javascript:
// Particle object var Particle = function() { // particle position this.x = Math.random()*width; this.y = Math.random()*height; // particle radius, 0 means invisible particle this.rad = 0; // particle speed this.speed = 4; // generate random particle color var r = Math.round(Math.random()*255); var g = Math.round(Math.random()*255); var b = Math.round(Math.random()*255); var a = Math.random(); this.color = "rgba("+r+","+g+","+b+","+a+")"; //particle steering angle, 0 to 360 this.angle = Math.round(Math.random()*Math.PI*2); };Variables [cci]width[/cci] and [cci]height[/cci] are respectively represent the canvas width and height. It is defined like this:
width = canvas.width; height = canvas.height;After the particle object definition is complete, we can populate a random particles by using this way:
// populate particles for(var i=0; i< NUM_PARTICLES; i++) { particles.push(new Particle()); }Variable [cci]NUM_PARTICLES[/cci] is global variable that defines the number of particle that will be generated.
Render The Particle
Now, we’ll add the rendering method for a particle. This method responsibles to render the particle that respect to the particle’ properties. This method also responsible to check the distance of the particle from another particles. If the distance is less than 230 pixels, the line will drawn connecting this particle to other.
// particle rendering method this.render = function() { // render the particle ctx.beginPath(); ctx.arc(this.x, this.y, this.rad, 0, 2*Math.PI, false); ctx.fillStyle = this.color; ctx.fill(); // count distance from another particle // if the distance less than 230px, connect the particles with line for(var i=0; i<NUM_PARTICLES; i++) { var p2 = particles[i]; var dx = p2.x - this.x; var dy = p2.y - this.y; // count the distance var distance = Math.sqrt(dx*dx + dy*dy); // if distance less than 230px, draw a line to connecting between two particles if(distance < 230) { ctx.beginPath(); ctx.lineWidth = 1; ctx.moveTo(this.x, this.y); ctx.lineTo(p2.x, p2.y); ctx.strokeStyle = this.color; ctx.stroke(); } } };
Move The Particle
Our animation will be nonsense if the particles don’t move. We’ll give the particle ability to move by adding a function that handle the movement into particle object. This function uses a simple vector operation to move the particles. The [cci]x[/cci] coordinat property will be increased by the speed multiplied by the cosinus of steering angle. The [cci]y[/cci] coordinat property will be increased by the speed multiplied by the sinus of steering angle. Because the particles is always move, there is a time when the particle reach the canvas border. To avoid the particles moves out of canvas, we’ll move the particles to opposite side when the border is reached.
// particle moving method this.move = function(){ this.x += this.speed*Math.cos(this.angle); this.y += this.speed*Math.sin(this.angle); //avoid particle to move out of canvas if(this.x < 0) this.x = width; if(this.y < 0) this.y = height; if(this.x > width) this.x = 0; if(this.y > height) this.y = 0; };Render The Canvas
We have our particle ready, now it’s time to render the canvas. Rendering the canvas means rendering all of the particles including the canvas background.
var render = function() { // render the background ctx.fillStyle = "rgba(0,0,0,0.1)"; ctx.fillRect(0, 0, width, height); // render particles for(var i=0; i<NUM_PARTICLES; i++){ var p = particles[i]; p.render(); p.move(); } };Render Scheduling
To make the animation life, we must schedule to call [cci]render[/cci] method. We want to set FPS (Frame Per Second) to be 30, so we must set the interval to be [cci]1000/FPS ms[/cci]
// setup FPS = Frame Per Second // render function will be called every 1000/FPS = 33 ms setInterval(render, 1000/FPS);Final Source Code
This is the final source code. Save it as html file and open it in your favorite browser.
<html> <head> <title>Cool Animation Effect Using HTML5 Canvas</title> <script type="text/javascript"> // define FPS(Frame Per Second) var FPS = 30; // define number of particles in the system var NUM_PARTICLES = 20; // hold the canvas width and height var width, height; // hold the canvas context var ctx; // array of particles var particles = []; // Particle object var Particle = function() { // particle position this.x = Math.random()*width; this.y = Math.random()*height; // particle radius, 0 means invisible particle this.rad = 0; // particle speed this.speed = 4; // generate random particle color var r = Math.round(Math.random()*255); var g = Math.round(Math.random()*255); var b = Math.round(Math.random()*255); var a = Math.random(); this.color = "rgba("+r+","+g+","+b+","+a+")"; //particle steering angle, 0 to 360 this.angle = Math.round(Math.random()*Math.PI*2); // particle rendering method this.render = function() { // render the particle ctx.beginPath(); ctx.arc(this.x, this.y, this.rad, 0, 2*Math.PI, false); ctx.fillStyle = this.color; ctx.fill(); // count distance from another particle // if the distance less than 230px, connect the particles with line for(var i=0; i<NUM_PARTICLES; i++) { var p2 = particles[i]; var dx = p2.x - this.x; var dy = p2.y - this.y; // count the distance var distance = Math.sqrt(dx*dx + dy*dy); // if distance less than 230px, draw a line to connecting between two particles if(distance < 230) { ctx.beginPath(); ctx.lineWidth = 1; ctx.moveTo(this.x, this.y); ctx.lineTo(p2.x, p2.y); ctx.strokeStyle = this.color; ctx.stroke(); } } }; // particle moving method this.move = function(){ this.x += this.speed*Math.cos(this.angle); this.y += this.speed*Math.sin(this.angle); //avoid particle to move out of canvas if(this.x < 0) this.x = width; if(this.y < 0) this.y = height; if(this.x > width) this.x = 0; if(this.y > height) this.y = 0; }; }; var render = function() { // render the background ctx.fillStyle = "rgba(0,0,0,0.1)"; ctx.fillRect(0, 0, width, height); // render particles for(var i=0; i<NUM_PARTICLES; i++){ var p = particles[i]; p.render(); p.move(); } }; window.onload = function() { // get canvas element var canvas = document.getElementById('canvas'); if(!canvas.getContext) { alert("Your browser doesn't support html5"); return; } width = canvas.width; height = canvas.height; // get drawing context ctx = canvas.getContext("2d"); // populate particles for(var i=0; i< NUM_PARTICLES; i++) { particles.push(new Particle()); } // setup FPS = Frame Per Second // render function will be called every 1000/FPS = 33 ms setInterval(render, 1000/FPS); }; </script> </head> <body> <div style="width:800px;padding-top:20px; margin:0 auto;"> <canvas id="canvas" width="800" height="500"></canvas> </div> </body> </html>