Tutorial Canvas Animation : movement along bezier curve

It is also possible to define paths for movements along which the movement should occur. For this we can use the bezier curve (for bezier curves read the tutorial 'HTML5 Canvas Tutorial: Lines & shapes')

Example 1: Movement along a bezier curve

HTML code for this animation:

<!doctype html>
<html>
<head>
<title>Canvas: Movement along a bezier curve</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="js/service.js"></script>
<script src="js/ball.js"></script>
<script src="js/functions.js"></script>
</head>
<body> 
<canvas id="bezier_motion1" style="border: 1px solid;" width="636" height="288"></canvas>
</body>
</html>

Javascript code in functions.js:

$(document).ready(function() {
    bezierMotion1();
});

function bezierMotion1(){
  
  var breadcrumbs = new Array();
  var crumbRadius=1;
  var canvas=jQuery("#bezier_motion1");
  var context = canvas.get(0).getContext("2d");
  var parentWidth=jQuery(canvas).parent().width();
  var canvasWidth = context.canvas.width  = parentWidth;
  var canvasHeight = context.canvas.height  = 288;
  var p0 = {x:canvasWidth-50, y:30};
  var p1 = {x:50, y:30};
  var p2 = {x:50, y:258};
  var p3 = {x:canvasWidth-50, y:258};
  //function Ball(x,y,radius,color,strokeColor,lineWidth) in ball.js
  var ball_4 = new Ball(0,0,12,'#f16529','#000',7);
  var speed;
  var t;
  ball_4.t=0;
  ball_4.speed=.01;
  
  if (!checkForCanvasSupport) {
  return;
  }
  
  (function drawFrame() {
  window.requestAnimationFrame(drawFrame, canvas);
  context.clearRect(0,0,canvasWidth,canvasHeight); // clear canvas
  
  t=ball_4.t;
 
  var cx = 3 * (p1.x - p0.x)
  var bx = 3 * (p2.x - p1.x) - cx;
  var ax = p3.x - p0.x - cx - bx;
  
  var cy = 3 * (p1.y - p0.y);
  var by = 3 * (p2.y - p1.y) - cy;
  var ay = p3.y - p0.y - cy - by;
 
  var xt = ax*(t*t*t) + bx*(t*t) + cx*t + p0.x;
  var yt = ay*(t*t*t) + by*(t*t) + cy*t + p0.y;
  
  ball_4.t += ball_4.speed;
 if (ball_4.t > 1) {
  ball_4.t = 1;
  }
  
  ball_4.x=xt;
  ball_4.y=yt;
  
  //Draw the moving ball
  ball_4.draw(context);
  
  //Draw the context point
  context.font ="10px Verdana";
  context.fillStyle = "#f16529";
  context.beginPath();
  context.arc(p0.x,p0.y,8,0,Math.PI*2,true);
  context.closePath();
  context.fill();
  context.globalCompositeOperation = "source-over";
  context.fillStyle = "#FFFFFF";
  context.fillText("0",p0.x-3,p0.y+3);
  
  //Draw the first control point
  context.fillStyle = "#f16529";
  context.beginPath();
  context.arc(p1.x,p1.y,8,0,Math.PI*2,true);
  context.closePath();
  context.fill();
  context.globalCompositeOperation = "source-over";
  context.fillStyle = "#FFFFFF";
  context.fillText("1",p1.x-3,p1.y+3);
  
  //Draw the second controlpoint
  context.fillStyle = "#f16529";
  context.beginPath();
  context.arc(p2.x,p2.y,8,0,Math.PI*2,true);
  context.closePath();
  context.fill();
  context.globalCompositeOperation = "source-over";
  context.fillStyle = "#FFFFFF";
  context.fillText("2",p2.x-3, p2.y+3);
  
//Draw the end point
  context.fillStyle = "#f16529";
  context.beginPath();
  context.arc(p3.x,p3.y,8,0,Math.PI*2,true);
  context.closePath();
  context.fill();
  context.globalCompositeOperation = "source-over";
  context.fillStyle = "#FFFFFF";
  context.fillText("3",p3.x-3, p3.y+3);
  
  //draw the breadcrumbs
  //add an breadcrumb to the breadcrumbs array
  breadcrumbs.push({x:xt,y:yt});
  //draw the breadcrumbs that show the track of the movement
  context.globalCompositeOperation = "destination-over";
  showBreadcrumbs(breadcrumbs);
 }());//end drawFrame 
 
  function showBreadcrumbs(breadcrumbs){
  for (var i = 0; i< breadcrumbs.length; i++) {
  context.beginPath();
  context.arc(breadcrumbs[i].x,breadcrumbs[i].y,crumbRadius,0, 2*Math.PI,false);
  context.closePath();
  context.fillStyle="#999";
  context.fill();
  }
  }//end showBreadcrumb
}//end bezierMotion1


The above motion may not make an impression, but what do you think of the following motion, shown below: the looping. For the looping, you need to ensure that the points p0 and p1 and p2 and p3 are positioned diagonally opposite each other in an X-shape. Points p0 and p3 must also be closer to the center of the canvas then p1 and p2. The items may, moreover, be located outside of the canvas, as is the case in Example 2 with the point P1(-120.328) and P2(-120, -40)

Example 2: The looping

All you need to do in the javascript code is replace rules 7 t/10 with the following lines in which the new points p0, p1, p2 and p3 are defined.

	var p0 = {x:580, y:110};
    var p2 = {x:-120, y:-40};
    var p1 = {x:-120, y:328};
    var p3 = {x:580, y:178};

Next tutorial

Leave a comment