Programming
Drawing simple animated curves with JavaScript
July 31, 2013
0

Hi folks,

I’d like to talk about how to draw simple curve using HTML5 Canvas element, a little bit of basic math and JavaScript with some animation. The example is based one I found on a book I’m reading right now:

HTML5 for publishers

from which I took the code to draw the Cartesian grid.

The basic idea is not using Bezier JavaScript function or quadratic ones which are useful and powerful, but doesn’t have any animation. Since I think that sometimes is funny reinventing the wheel, I decided to try to draw a circumference and a parabola without using built-in functions. Here I will explain the basic facts and the complete code is available on codepen.

Let’s start; first of all I had to make some assumptions, to simplify the code:

  1. Circumference will have a predefined radius and its centre will be in the  cartesian origin i.e. point (0,0)
  2. Parabola will be centered in the cartesian origin

Wikipedia has a nice explanation of the circumference and parabola; what we really need is their cartesian equation and so:

  1. Circumference x^2+y^2 = r^2 (centre in the origin)
  2. Parabola y = ax^2 + by^2 + c

So, after a brief explanation of what it’s needed let’s start coding:

  1. Create a simple HTML  page with a Canvas object and a form with two buttons, one for the circumference and one for the parabola.
<div>
   <canvas id="main" width="400px" height="400px"></canvas>
  <form>
     <input type="button" id="parabola" value="parabola" class="button2" />
      <input type="button" id="circle" value="circle" class="button3" />
  </form>
</div>

With a few line of JavaScript let’s add a listener to each button:

var parabola_button = document.getElementById('parabola');

parabola_button.addEventListener('click',parabolaPressed,false);

var circle_button = document.getElementById('circle');

circle_button.addEventListener('click',circlePressed,false);

The actual drawing action is made up of two functions, called by pressing one of the two buttons; as an example I will write the circumference one:

function circlePressed(e){
  draw_circle(100,"blue");
}

As you can see, on the button click event the “circlePressed” function is called; this function calls draw_circle which takes two arguments, the radius and the line colour. This function simply calculates the y value based on the x value and the radius using this formula:

y =\sqrt{(r^2-x^2)}

You also have to remember that for each x point there are two y points, due to the nature of circumference and square root, so you will have to draw both of them.

Here is the function:

function draw_circle(radius,color){
  var radius = radius;
  if(graph_in_progress == 'yes'){
    alert('Another line being drawn, please wait');
  }else{
    init_x = -radius;
    init_y = -Math.sqrt(Math.pow(radius,2)-Math.pow(init_x,2));
    new_x = init_x;
    new_y = init_y;
    graph_in_progress = "yes";
    drawLineIntervalId = setInterval(do_animation_3,33);
  }
  function do_animation_3(){
    ctx.lineWidth = 6;
  ctx.fillStyle = color;
  ctx.beginPath();
  ctx.moveTo(init_x,init_y);
  //ctx.lineTo(new_x,new_y);
  ctx.fillRect(init_x,init_y,1,1);
  ctx.fillRect(init_x,-init_y,1,1);
  ctx.stroke();
  ctx.closePath();
  new_x =  new_x+1;
    new_y = -Math.sqrt(Math.pow(radius,2)-Math.pow(new_x,2));
  ctx.fillRect(new_x,new_y,1,1);
  ctx.fillRect(new_x,-new_y,1,1);
  if(new_x == canvas.width+5){
    clearInterval(drawLineIntervalId);
    graph_in_progress = "no";
  }
  }

}

The function starts by checking if any other graph is being drawn, if so, an alert is displayed.  Then it starts setting an initial point with the  x equal to the negative value of the radius. After that an interval of 33 ms is set so to animate the graph.In the drawing function  a path is started using the canvas context beginPath method, the path is then moved to the initial point and two 1 pixel rectangles are drawn. Afterwards the path must be closed and a the new x,y values are calculated and the rectangles are drawn again. To end the recursion, the function checks whether or not the current x value is bigger than the radius, if so, the time interval is cleared and the function is terminated.  And here is the result:

circle_post

 

 

 

 

 

 

 

 

 

Isn’t it easy?

Enjoy!!

Reference book: HTML5 for publishers

Complete code: codepen

Leave a Reply

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close