How Video and Canvas Elements Jointly Create Interactive Video Experiences?

google+

linkedin

pinterest

Do you want to create interesting and interactive experiences? Get ready to work with the built-in goodies in HTML5 and combine them to develop the innovative experiences. In this article, we are going to take "non-interactive" mp4 video and can create how to create choose-your-own-adventure-style interactive experience through functionality of the <video> and <canvas> tags.

interactive video experience

Firstly, we have needed a video. It is advisable to start with a short, light one (about 1 minute in length). Now, you have to set up a super basic HTML file:

<!doctype html>
<html>
<head>
<title>
Making an interactive video using Javascript
</title>
</head>
<body>
</body>
</html>

Now, you have to put a pair of video tags in the body section. Here, we are giving an id of “myVideo” and assign a width and height of it. You have to add a source tag between the two video tags that defines the location of the actual file and its type.

After that, you have to add a canvas tag. Please Note: the order is not arbitrary, so if you are placing the video tag below the canvas tag in the code then canvas would be hidden behind the video and interaction with it would be blocked. Give canvas an id of “myCanvas” and give it the same width and height as the video so it overlies completely.

This thing can be done with a few simple lines of CSS. Now, you have to add a pair of <style> tags to the <head> and if you prefer, then create an external separate style sheet. Check out below given code for overlapping the two elements.

<style>
#myVideo,#myCanvas{
position:absolute;
left:0px;
top:0px;
}
</style>

With this, you can set your video and canvas in the top-left corner. If you want to move it around the screen, then you have to tweak the left and top values. Ensure to assign this to both the IDs. Here, we found the powerful transparent wrapper than watch-only video. In next step, we have to set up Javascript file by adding below give lines to the head of your HTML page:

<script src="myScript.js"></script>

In next step, you have to set up a .js file named myScript.js and paste it in the same directory as your HTML file. After that, you have to set up reference the video and the canvas in Javascript. This can be done by inserting lines to the top of myScript.js:

var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d"); 
var video = document.getElementById("myVideo");

Now, we are creating a variable, named as canvas that accesses the HTML <canvas> element through its ID. It’s time to create a second variable that holds the context of the canvas. It will give access to many powerful tools which can be called directly through the variable context. In next step, you have to refer the video tag.

After that, you will see the both elements are fully accessible through Javascript that simply means you don’t have to access all their built-in methods and properties.

Those people, who have an idea about canvas, can easily use it to draw shapes, show images, create animations, etc. You have to draw a rectangle on the canvas by adding this simple code to the script file:

context.fillRect(100,100,50,50);

After that, you have to work with some essential methods and a very important property of the video element, namely:

video.play();
This plays the video, as you can imagine.
video.pause();
This pauses the video.
And…
video.currentTime

It gives current position of the playback that we require to give to mess around with the sequence of our video. Now, you have to create a simple, grey rectangle. But before that you have to create a generic Javascript object that helps with the collision detection later. for that, you just wrote codes given below:

var buttonObject =
 {
   width: 0,
   height: 0,
   x: 0,
   y: 0,
   centerX: function()
   {
     return this.x + (this.width / 2);
   },
   centerY: function()
   {
     return this.y + (this.height / 2);
   },
   halfWidth: function()
   {
     return this.width / 2;
   },
   halfHeight: function()
   {
     return this.height / 2;
   }
 };

After that, you use the Object.create() method and develop our actual button which will inherit the properties of the buttonObject.

var button = Object.create(buttonObject);
button.x = 200;
button.y = 200;

Now, you have to save and run it in your favorite browser and you notice that nothing happens. This is because you haven’t drawn anything yet. Now, you have to specify abstract element’s characters on the screen. You have to follow below given method to draw it,

context.fillStyle = "#333";
context.fillRect(button.x,button.y,button.width,button.height);

One will see a grey (hex value: #333) rectangle on your screen if everything went well above the video. After that, you have to add two event listeners to deal with our mouse activities.

window.addEventListener("mousemove",onMouseMove,false);
window.addEventListener("mousedown",onMouseDown,false);

Now, we have to add a variable to decide whether or not the mouse has been clicked…

var clicked = false;

after that you have to create two simple variables for tracking the X and Y values of the mouse…

var mouseX;
var mouseY;

…and let’s finish it off with their respective handlers:

function onMouseDown(event)
 {
 clicked = true;
 }
 function onMouseMove(event)                {
 mouseX = event.pageX - canvas.offsetLeft;
 mouseY = event.pageY - canvas.offsetTop;
 }

A command will be simply executed by the mousedown when the mouse button is being pressed. Along with clicked, it will let you know if we’ve clicked on button. On other side, constant update on our mouse’s X and Y position will help on the mousemove function. Below given code you have to update on collision detection to add something:

main(); 
function main() { 
window.setTimeout(main,33);
 context.clearRect(0,0,canvas.width,canvas.height);
var vx = mouseX - button.centerX();                      
var vy = mouseY - button.centerY();
var combinedHalfWidths = 1 + button.halfWidth();
var combinedHalfHeights = 1 + button.halfHeight();
 if(Math.abs(vx) < combinedHalfWidths)
 {
    if(Math.abs(vy) < combinedHalfHeights)
    {
//THE RESULT OF THE COLLISION DETECTION GOES HERE… 
 } 
} 
}

Now, you have to do some couple of things. First of all, you have to create a main loop called main() that itself recursively and repeats itself continuously thanks to the setTimeout timer. The canvas is cleared at every call and it will help you to create the illusion of motion. In next step, you have to check the collision between the mouse and the rectangle.

However, one thing is clear that if you run above as is, you will notice the grey rectangle disappears. It is due to the dust back in frame one. In order to have to it obvious, you have to add it to the main loop. Now, you have to go ahead and cut these two lines and paste it to above the collision detection check we wrote:

context.fillStyle = "#333";
context.fillRect(button.x,button.y,button.width,button.height);

Here, you will find a complete code. First the HTML files:

<!doctype html>
<html>
<head>
<title>

Use Javascript to create interactive video:

</title>
 <style>
 #myVideo,#myCanvas {
 position:absolute;
 left:0px;
 top:0px;
 }
 </style>
 <script src="myScript.js"></script>
 <video id="myVideo" width="500" height = "400"> 
 <source src="SampleVideo.mp4" type="video/mp4">
 </video>
 <canvas id="myCanvas" width ="500" height="400"> </canvas>
 </head>
 <body>
 </body>
 </html>

And here’s the JavaScript file (myScript.js):

var buttonObject =
 {
   width: 100,
   height: 100,
   x: 0,
   y: 0,
   centerX: function()
   {
     return this.x + (this.width / 2);
   },
   centerY: function()
  {
     return this.y + (this.height / 2);
   },
   halfWidth: function()
   {
     return this.width / 2;
   },
   halfHeight: function()
   {
     return this.height / 2;
   }
 };
 var canvas = document.getElementById("myCanvas");
 var context = canvas.getContext("2d");
 var video = document.getElementById("myVideo");
 var button = Object.create(buttonObject);
 button.x = 200;
 button.y = 200;
 window.addEventListener("mousemove",onMouseMove,false);
 window.addEventListener("mousedown",onMouseDown,false);
 var clicked = false;
 var mouseX;
 var mouseY;
 function onMouseDown(event)
 {
 clicked = true;
 }
 function onMouseMove(event)                {
 mouseX = event.pageX - canvas.offsetLeft;
 mouseY = event.pageY - canvas.offsetTop;
 }
 main();
 function main() {
 window.setTimeout(main,33);
 context.clearRect(0,0,canvas.width,canvas.height);
 context.fillStyle = "#333";
 context.fillRect(button.x,button.y,button.width,button.height);
 var vx = mouseX - button.centerX();                      
 var vy = mouseY - button.centerY();
 var combinedHalfWidths = 1 + button.halfWidth();
 var combinedHalfHeights = 1 + button.halfHeight();
   if(Math.abs(vx) < combinedHalfWidths)
   {
     if(Math.abs(vy) < combinedHalfHeights)
     {
    }
 //THE RESULT OF THE COLLISION DETECTION GOES HERE…
   }
 }

Now, you have to payoff for clicking on the rectangle. You have to delete the comments in the collision detection formula and add the following:

if(clicked)
 video.play();

After that, you have to run the code and check out what happens when you click on the square. Just for change, you have to change above code with below given code:

if(clicked)  {
    video.currentTime = 10;
    video.play();
    clicked = false;
 }

It will allow to skip forward or back to the 10 second mark every time you click on the box. Another example: You have to add another variable at the top under the mouseY variable:

var buttonVX = 5;

After that, you have to check back in the main loop and add code for collision detection:

video.pause();

Lastly, you have to add some basic mechanics to make the box move from the left to right:

video.play();
 button.x += buttonVX;
 if(button.x > canvas.width - button.width)
 {
 buttonVX = -5;
 }
 if(button.x < 0)
 {
 buttonVX = 5;
 }

This amazing guide helps you to create Interactive Video Experiences with Video and Canvas Elements. For more information you can contact me.


0 comments:

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted.

If you want to link your website with your comment than choose "Comment as: Name/URL" option with respect of above notice.

Let's have a personal and meaningful conversation instead. Thanks for dropping by!