Stopbyte

How to made animations in HTML Page with Canvas

Hello Stopbyters! :robot:

In this article, Me and my team would like to discuss with you how to made animations in HTML, in web environments, using WebGL (aka OpenGL ES 2.0) with the HTML Canvas.

Nowadays, the browser have enough power to handle with complex element: As an example, we can think about the high quality HTML games like this one, in which many developing techniques was join togheter in order to build a great (for children) entertainment system. It is fantastic, don’t it? :slight_smile:

Having an awesome UI on your website can ensure a great amount of traffic! Then, you could consider to stop your work and starting gaining money with Click and Impression. :joy::joy:

#A little Overview
During the last years, the power of the internet browser has dramatically increased and an huge number of applications was built like a WebAPP. This means that theze application can run on your mobile device, in your old fashioned desktop and in your SmartTV! The browser has become the new JVM: A single language (javascript) can allow us to build e-commerce systems (Amazon), game (Agar.IO), scientific application (3DMol molecular viewer), chat room (Fritzme), realtime streaming website (Youtube) and so forth. Javascript and the browsers allow us to handle with the new-era multimedia object!
####Just few lines on the media handler
What we have behind the multimedia Object?
In the past, Flash Player and Silverlight handles the media object because the browser did not have native components for this purpose. If you developed multimedial website in the recent past, surely you have spended a lot of time in order to interact with the embedded and with the object tag. In the extreme case, developer has spent week in order to embed the old ActiveX components… :face_with_head_bandage:

With HTML5, a new tag is born: The canvas!

The canvas tag allow the programmer to draw pixel, images, and it primary goal is to allow the programmer to interact with OpenGL for Web (WebGL) features! This was a great step for a new way to web using! With WebGL developer can use shader and all other primitives provided with OpenGL ES 2.0 API.

What is WebGL

With WebGL, we refer to a Javascript API that interact with OpenGL ES (a small version of the OpenGL API) that handle 2D and 3D objects, using well defined primitives. It provides the fundamental routines with which developer can draw on a layer (the canvas).

Of course, it is impossible to analyze all the aspects that a good WebGL programmer should know. For the purpose of this article we will use some exemplifications:

  1. We will imagine the canvas as a white paper and WebGL a set of pencils. :slight_smile:
  2. We will assume that during the canvas lifecycle (from the document-ready event to the document-discard event) it is refreshed every X time_delta.

As an example, consider that we can request to the browser to update the canvas element every 0.04 seconds. What this means? This means that, the browser will allow you to redraw on the canvas (will give in your hand the set of pencils) every 0.04seconds (1/25). Also, this means that you can redraw the canvas 25 times per sec:Yes, the 25fps of the PAL standard.

This is a great thing! If we can use our pencils every 0.04secs, we can imagine to clean and redraw the canvas every frames and if you think about it, you are imagining the working model of the classic cinema.

Thinking as WebGL

For this example, we will animate our beautiful planet in a web page! We will need to interact with OpenGL, so we will use pure Javascript and not jQuery. The following script structure should apper to your eyes very different from classic Html Javascript due to the nature of WebGL.

When we interact with WebGL we have to request every single action that we need to perform. Think to our exemplification! If we want to draw a line on a white paper we have to:

  1. Take the paper
  2. Take a pencil of C color
  3. Draw a line on the paper touching the first point (x,y) and moving the pencil until the last point (x1,y1)

In order to use WebGL we have to perform every single action on it drawing pipeline.
#Prepare our white paper (canvas)

Open new blank page and put in it this simple structure.

<html>
        <head>
<script
  src="https://code.jquery.com/jquery-3.2.1.min.js"
  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
  crossorigin="anonymous"></script>
        </head>
        <body>
                <canvas id="ctx" width="800" height="600" style="height:100%"></canvas>

       </body>
</html>

As you can see, we defined an object canvas that have size 800x600 pixels and that is stretched on the entire page height (height:100%). This mean that we will have a blank paper of 800x600 pixel on which we will be able to draw!

As second step, we will download a simple texture of our planet! I chosen this image, but you can choose all the texture that you prefer :wink:

Drawing an Image is the same thing as drawing a line. We only have to drive WebGL in the correct way! In the following code you will be able to see how to drive WebGfor animating the earth in order to see it running from left to right on the screen.

But, befoe the code, we want to explain the steps that are needed in order to animate an object.

  1. We need to request to browser to update the canvas ASAP in order to have the animation perception. This action can be done calling window.requestAnimationFrame function with our drawing function passrd as argument. You have to imagine that browser will put the pencils in your hand many times every seconds.
  2. We have to clean the paper everytime we need to redraw on it. If we don’t clean the canvas, we will overwrite the previous frame (like a drawed paper on which we continue to draw). This action can be done with clearRect() function
  3. We have to fill the paper woth a dark background (we want to animate earth in space)
  4. We have to draw a circle (the border of the earth) in the correct position. Everytime we draw a new frame, the earth must be shifted on the right on the X coordinate. This can be done adding a simple ++ to x variable.
  5. We have to draw the image in the circle :slight_smile:

Using the code

Following, you can see the code that implements the previous five steps. Each line is commented in order to allow you to understand what WebGL is doing.

<script>
                        // register the startup datestamp
                        start = Date.now();
                         // request access to the canvas (our paper)
                        var ctx = document.getElementById("ctx").getContext("2d");      //2d context is the pencils container
                        // load the texture
                        var thumbImg = document.createElement('img');
                        thumbImg.src = './earth.jpg';

                        // will animate the earth on the X-coordinate (from left to right)
                        var xo = 0;
                        function _repaint()
                        {
                                window.requestAnimationFrame(_repaint); 
                                  var current = Date.now(), // get current datetime
                                  elapsed = current - start; // check how many msec is elapsed from previous frame
                                  start=current;
                                  // clear our paper (yes it will be cleared)
                                  ctx.clearRect(0,0,800,600);
                                  ctx.fillStyle="black";  // say to webgl to use black as background
                                  ctx.fillRect(0,0,800,600); //fill paper with black background
                                  // save current paper state
                                  ctx.save();
                                  ctx.beginPath(); //init drawing a circle
                          
                                  ctx.strokeStyle="blue"; //request to webgl to draw circle in blue
                                  ctx.arc(300+xo, 300, 200, 0, Math.PI * 2, true) // draw a circle (centered at position 300+xo,300) => xo is current offset in order to animate the earth
;                                 ctx.stroke(); //draw border
                                  ctx.closePath(); // 
                                  ctx.clip(); //draw the texture
                                  ctx.drawImage(thumbImg,100+xo,100,600,500);
                                  xo = xo +1;
                                  ctx.restore(); // go ahead! 

                                  if (xo > 1200) xo=-300; //if earth is out of screen (at the right) then return to left
                                 //this instruction is like carrier return \r ;)

          
                         // when the texture is ready then request to browser to update our canvas ASAP                            
                        
                        thumbImg.onload = function() {
                                window.requestAnimationFrame(_repaint);
                        }
                </script>

Ta da!

Finally, we done our first animation. You can see the earth animation [here] (http://www.arrowsoft.it/examples/canvas.html)!

Learning WebGL could be the killer application of your life! There are a tons of thing that can be implemented with 2D/3D graphics. The only limit is your fantasy!