Tutorial Canvas Animation: elasticity

Je browser ondersteunt geen Canvas. Update je browser naar de laatste versie.

Gravity with elastic bounce effect

The elasticity of a bouncing ball is related to the amount of energy that is absorbed during the contact with a surface. The degree of energy absorbed is dependent on the type of material of the surface and of the bouncing ball itself. For example, a cannonball falls on a squishy surface will lose all his energy during the contact with the ground and remain lying. By contrast, a gummy ball bouncing on a concrete surface will lose little energy and will highly bounce back. However, in all cases (in real life) the maximum height that can reached after bouncing of the ball will decrease after every bounce.

We can simulate this process by applying an elasticity factor (a constant) during the contact with the ground. In the example code for the animation we will call this constant elasticity and the value will be 0.8

HTML code for this animation:

  <!doctype html>
  <html>
  <head>
 	 <title>Het Canvas eenparig versnelde beweging</title>
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
	 <script src="js/functions.js"></script>
  </head>
  <body> 
 	 <canvas id="elastic_bounce" style="border: 1px solid;" width="636" height="288">
    Your browser does not support Canvas. Update your browser to the latest version.
    </canvas>
  </body>
  </html>

Javascript

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

function checkForCanvasSupport() {
  return !!document.createElement('some_canvas').getContext;
  }

function gravityElasticBounce(){
  var radius=15;
  var speedfactor =7;
 // define the direction the ball is moving
  var degrees = 305;
  var angle = degrees * Math.PI/ 180;
  var vx = Math.cos(angle) * speedfactor/2;
  var vy  = Math.sin(angle) * speedfactor;
  var gravity = 0.1;
  var elasticity = .8;
  var canvas=jQuery("#elastic_bounce");
  var context = canvas.get(0).getContext("2d");
  //Make the Canvas element responsive for desktop, tablet and smartphone	
  var parentWidth=jQuery(canvas).parent().width();
  var canvasWidth = context.canvas.width  = parentWidth;
  var canvasHeight = context.canvas.height  = 288;
  // define the coordinates of the starting point p0
  var p0 = {x:20,y:canvas.height()-radius};
  // define the start coordinates, the speed and the radius of the ball
  var ball = {x:p0.x, y:p0.y, vx:vx, vy:vy, radius:radius, elasticity: elasticity};
  var friction = .98;
  var breadcrumbs=new Array();
  var crumbRadius =1;
  
  if (!checkForCanvasSupport) {
  return;
  }
  init();
  
  function init(){
  myinterval = setInterval(draw, 12);
  }
  
  function draw(){
  //alert(ball.vy);
  ball.vy += gravity;
  
  if ((ball.y + ball.radius) > canvas.height()){
  
  if (ball.vy < 1){
  ball.vx *= friction; 
  ball.vy = 0;
  }
  if( ball.vx >-0.63 && ball.vx < -0.4 ){
  ball.vx=0;
  setTimeout('clearInterval(myinterval)', 0);
  //showbutton();
  //return;
  }
  ball.vy = -(ball.vy) * ball.elasticity
  }
  if((ball.x + ball.radius) > canvas.width()  ){
  ball.vx= -(ball.vx);
  ball.vy = -(ball.vy);
  }
  if((ball.x - ball.radius) < 0){
  ball.vx= -(ball.vx); 
  }
  ball.y += ball.vy;
  ball.x += ball.vx;
  context.clearRect(0,0, canvasWidth,canvasHeight);
  context.fillStyle = "#f16529";
  context.lineWidth=7;
  context.strokeStyle="black";
  context.beginPath();
  context.arc(ball.x,ball.y,ball.radius,0,Math.PI*2,true);
  context.closePath();
  context.fill();
  context.stroke();
  
  
  
  //draw the breadcrumbs
  //add an breadcrumb to the breadcrumbs array
  breadcrumbs.push({x:ball.x,y:ball.y});
  //draw the breadcrumbs which show that the track of the movement
  context.globalCompositeOperation = "destination-over";
  showBreadcrumbs(breadcrumbs);
 
  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();
  }
  }
  }
  
  }

Next tutorial

Leave a comment