Today I learned about utilizing angle of reflection in physics to simulate bouncing. Basically the idea is that the angle of incidence (incoming angle) = angle of reflection (outgoing angle). This is usually used for calculation of light rays, but it can also be applied to simulate an object bounce.

This example isn’t perfect – you’ll notice the ball goes halfway into the wall before the bouncing occurs – but it captures the basic concept quite well.

The JavaScript Code

$(document).ready(function() {  
  // Uses Modernizr.js to check for canvas support
  function canvasSupport() {
    return Modernizr.canvas;
  }

  canvasApp();

  function canvasApp() {
    // Check for canvas support
    if (!canvasSupport()) {
      return;
    } else {
      // Grab the canvas and set the context to 2d
      var theCanvas = document.getElementById('canvasOne');
      var context = theCanvas.getContext("2d"); 
    }

    // Variables
    var speed = 5;
    var position1 = {x:20, y: 20};
    var angle = 35;
    var radians = 0;
    var xUnits = 0;  // represents pixels to move along the x-axis
    var yUnits = 0;  // represents pixels to move along the y-axis
    var ball = {x: position1.x, y: position1.y};
    updateBall();

    // Drawing interval
    setInterval(drawScreen, 33);

    // Functions
    function updateBall () {
      // Called every time we set a new angle for the ball.
      // Recalculations radians and sets new xUnits and yUnits values.
      radians = angle * Math.PI/180;
      xUnits = Math.cos(radians) * speed;
      yUnits = Math.sin(radians) * speed;
    }

    function drawScreen() {
      // Reset canvas
      context.fillStyle = "#ffffff";
      context.fillRect(0, 0, theCanvas.width, theCanvas.height);

      // Outside border
      context.strokeStyle = "#000000";
      context.strokeRect(1, 1, theCanvas.width - 2, theCanvas.height - 2);

      // Update the position of the ball and draw it
      ball.x += xUnits;
      ball.y += yUnits;

      // Draw the ball object
      context.fillStyle = "#000000";
      context.beginPath();
      context.arc(ball.x, ball.y, 15, 0, Math.PI * 2, true);
      context.closePath();
      context.fill();

      // Check if ball has hit a wall. If so, then call updateBall
      if (ball.x > theCanvas.width || ball.x < 0) {         // new angle = 180 - angle of incidence         angle = 180 - angle;         updateBall();       } else if (ball.y > theCanvas.height || ball.y < 0) {
        angle = 360 - angle;
        updateBall();
      }
    }

  }

});

The Example App

You can find the code running live here: https://www.zesix.com/html5/ballBouncingOffWalls/