Creating Cool Animation Effect Using HTML5 Canvas

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.

Cool Animation Effect

Cool Animation Effect



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 getContext('2d') 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:

  1. Position
    Position property define the particle’s location on the canvas. It contains x and y variables which represent the particle’s coordinat on the canvas. The position property will be generated randomly.
  2. Radius
    Radius property defines the particle radius. Because we want to create an invisible particle, we’ll put 0 as radius value.
  3. Speed
    Speed property determines how fast a particle can move
  4. 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
  5. 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 width and height 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 NUM_PARTICLES 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 x coordinat property will be increased by the speed multiplied by the cosinus of steering angle. The y 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 render method. We want to set FPS (Frame Per Second) to be 30, so we must set the interval to be 1000/FPS ms

// 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>

Related Posts:

Javascript