Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=utf-8 />
<title>Boucing rectangle with high resolution timer and adjustable frame rate</title>
  <script>
    var canvas, ctx;
    var width, height;
    var x, y, incX; // incX is the distance from the previous drawn rectangle to the new one
    var speedX; // speedX is the target speed of the rectangle
    
  
    
    // for time based animation, DelayInMS corresponds to the target framerate
    var now, delta, delayInMS, totalTimeSinceLastRedraw=0;
    // High resolution timer
     var then = performance.now();    
    
    // Michel Buffa : set the target framerate TRY TO CHANGE THIS VALUE AND SEE
    // THE RESULT. Try 2 frames/s, 10 frames/s, 60, 100 frames/s Normally there
    // should be a limit at 60 frames/s in the browser's implementations.
    setFrameRateInFramesPerSecond(60); 
    
    function setFrameRateInFramesPerSecond(framerate) {
      delayInMs = 1000 / framerate;
    }
    
    // Called after the DOM is ready (page loaded)
    function init() {
      // init the different variables
      canvas = document.querySelector("#mycanvas");
      ctx = canvas.getContext('2d');
      width = canvas.width;
      height = canvas.height;
      
      x=10; y = 10;
      // Target speed in pixels/second, try with high values, 1000, 2000...
      speedX = 2000;
      
      // Start animation 
      requestAnimationFrame(animationLoop)
    }
     
    function animationLoop(time) {
      // Measure time, with high resolution timer
      now = time
      // How long between the current frame and the previous one ?
      delta = now - then; 
      //console.log("delta = " + delta + " total = " + totalTimeSinceLastRedraw + " delay = " + delayInMs);
      
      if(totalTimeSinceLastRedraw > delayInMs) {
        //console.log("yes")
      // Compute the displacement in x (in pixels) in function of the time elapsed since the last draw and
      // in function of the wanted speed. This time instead of delta we
        // use totalTimeSinceLastRedraw as we're not drawing always at
        // each execution of mainloop
      incX = calcDistanceToMove(totalTimeSinceLastRedraw, speedX);
      //console.log("dist = " + incX);     
      // an animation is : 1) clear canvas and 2) draw shapes, 
      // 3) move shapes, 4) recall the loop with requestAnimationFrame
      
      // clear canvas
      ctx.clearRect(0, 0, width, height);
      
      ctx.strokeRect(x, y, 10, 10);
      
      // move rectangle
      x += incX;
 
      // check collision on left or right
      if((x+10 >= width) || (x <= 0)) {
        // cancel move + inverse speed
        x -= incX;
        speedX = -speedX;
      }
      // reset the total time since last redraw
      totalTimeSinceLastRedraw = delta;
    } else {
         //console.log("no");
        // sum the total time since last redraw
        totalTimeSinceLastRedraw += delta;
    }
            // Store time
      then = now;
     
    // animate. This works only in Chrome. For FF use mozRequestAnimationFrame
    // For support for all browsers, look at the shym in the HTML5 course.
    requestAnimationFrame(animationLoop);
  }    
 
    // We want the rectangle to move at speed pixels/s (there are 60 frames in a second)
    // If we are really running at 60 frames/s, the delay between frames should be 1/60
    // = 16.66 ms, so the number of pixels to move = (speed * del)/1000. If the delay is twice
    // longer, the formula works : let's move the rectangle twice longer!
  var calcDistanceToMove = function(delta, speed) {
    return (speed * delta) / 1000; 
  }
    
  </script>
</head>
  
<body onload="init();">
  <canvas id="mycanvas" width="200" height="50" style="border: 2px solid black"></canvas>
</body>
</html>
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
MichelBuffapro
0viewers