O'Reilly logo

HTML5 Canvas by Jeff Fulton, Steve Fulton

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Animation Revisited: Moving Videos

Now we are going to revisit the bouncing balls demo from Chapter 5 to show you how you can achieve the same effect with images and videos. Since we covered this in detail in Example 5-5 (CH5EX5.html), we don’t need to examine all the code—just the changes that make the videos move.

Note

Remember that videos are drawn in much the same way as images, so with very few changes this application would work just as well with a static image.

While there are a few other changes, the most important is in the drawScreen() function when we draw the videos onto the canvas. Recall that in Chapter 5 we created an array named balls and a dynamic object to hold the properties of each ball that looked like this:

tempBall = {x:tempX,y:tempY,radius:tempRadius, speed:tempSpeed, angle:tempAngle, 
    xunits:tempXunits, yunits:tempYunits}

For videos, we will create a similar array, named videos, but we will alter the dynamic object:

tempvideo = {x:tempX,y:tempY,width:180, height:120, speed:tempSpeed, angle:tempAngle, 
    xunits:tempXunits, yunits:tempYunits}

The big difference here is that we no longer need a radius that represents the size of the ball; instead, we need the width and height so we can render the video to our desired size in the drawScreen() function.

Back in Chapter 5 we used the canvas drawing command to draw balls on the screen like this:

context.beginPath();
context.arc(ball.x,ball.y,ball.radius,0,Math.PI*2,true);
context.closePath();
context.fill();

To draw videos, we need to change the code:

context.drawImage(videoElement, video.x, video.y, video.width, video.height);

That is pretty much all you need to do! There are some others changes here (e.g., we start all the videos in the center of the screen before they start moving), but the items mentioned above are the main things you need to concentrate on to move video, not yellow balls, around the screen. Figure 6-13 shows what the example looks like with bouncing videos instead of balls. You can see the full code in Example 6-12.

Canvas video animation demo

Figure 6-13. Canvas video animation demo

Example 6-12. Multiple video bounce

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CH6EX12: Multiple Video Bounce</title>
<script src="modernizr-1.6.min.js"></script>
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);

var videoElement;
var videoDiv;
function eventWindowLoaded() {

   videoElement = document.createElement("video");
   var videoDiv = document.createElement('div');
   document.body.appendChild(videoDiv);
   videoDiv.appendChild(videoElement);
   videoDiv.setAttribute("style", "display:none;");
   var videoType = supportedVideoFormat(videoElement);
   if (videoType == "") {
      alert("no video support");
      return;
   }
   videoElement.setAttribute("src", "muirbeach." + videoType);
   videoElement.addEventListener("canplaythrough",videoLoaded,false);

}

function supportedVideoFormat(video) {
   var returnExtension = "";
   if (video.canPlayType("video/webm") =="probably" || 
       video.canPlayType("video/webm") == "maybe") {
         returnExtension = "webm";
   } else if(video.canPlayType("video/mp4") == "probably" || 
       video.canPlayType("video/mp4") == "maybe") {
         returnExtension = "mp4";
   } else if(video.canPlayType("video/ogg") =="probably" || 
       video.canPlayType("video/ogg") == "maybe") {
         returnExtension = "ogg";
   }

   return returnExtension;

}

function canvasSupport () {
     return Modernizr.canvas;
}

function videoLoaded() {
   canvasApp();

}

function canvasApp() {

  if (!canvasSupport()) {
          return;
        }

  function  drawScreen () {

      context.fillStyle = '#000000';
      context.fillRect(0, 0, theCanvas.width, theCanvas.height);
      //Box
      context.strokeStyle = '#ffffff';
      context.strokeRect(1,  1, theCanvas.width-2, theCanvas.height-2);

      //Place videos
      context.fillStyle = "#FFFF00";
      var video;

      for (var i =0; i <videos.length; i++) {
         video = videos[i];
         video.x += video.xunits;
         video.y += video.yunits;

         context.drawImage(videoElement ,video.x, video.y, video.width, video.height);

         if (video.x > theCanvas.width-video.width || video.x < 0 ) {
            video.angle = 180 - video.angle;
            updatevideo(video);
         } else if (video.y > theCanvas.height-video.height || video.y < 0) {
            video.angle = 360 - video.angle;
            updatevideo(video);
         }
      }

   }

   function updatevideo(video) {

      video.radians = video.angle * Math.PI/ 180;
      video.xunits = Math.cos(video.radians) * video.speed;
      video.yunits = Math.sin(video.radians) * video.speed;

   }

   var numVideos = 12 ;
   var maxSpeed = 10;
   var videos = new Array();
   var tempvideo;
   var tempX;
   var tempY;
   var tempSpeed;
   var tempAngle;
   var tempRadians;
   var tempXunits;
   var tempYunits;

   var theCanvas = document.getElementById("canvasOne");
   var context = theCanvas.getContext("2d");
   videoElement.play();

   for (var i = 0; i < numVideos; i++) {

      tempX = 160 ;
      tempY = 190 ;
      tempSpeed = 5;
      tempAngle = Math.floor(Math.random()*360);
      tempRadians = tempAngle * Math.PI/ 180;
      tempXunits = Math.cos(tempRadians) * tempSpeed;
      tempYunits = Math.sin(tempRadians) * tempSpeed;

      tempvideo = {x:tempX,y:tempY,width:180, height:120, speed:tempSpeed, angle:tempAngle, 
          xunits:tempXunits, yunits:tempYunits}
      videos.push(tempvideo);
   }

   setInterval(drawScreen, 33);

}

</script>

</head>
<body>
<div style="position: absolute; top: 50px; left: 50px;">

<canvas id="canvasOne" width="500" height="500">
 Your browser does not support HTML5 Canvas.
</canvas>
</div>
</body>
</html>

Note

The HTML5 video element combined with the canvas is an exciting, emerging area that is being explored on the Web as you read this. One great example of this is the exploding 3D video at CraftyMind.com: http://www.craftymind.com/2010/04/20/blowing-up-html5-video-and-mapping-it-into-3d-space/.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required