Using HTML5 video with canvas
You’ve already learned a lot about the
<video>
element in my previous article “What I’ve Learned From Working With HTML5 Video Over A Month”, but did you know that the <video>
and <canvas>
elements would be a great choice to use together? In fact, the two elements are absolutely wondrous when you combine them! I will show you a handy demo using these two elements, which I hope will prompt cool future projects from you. Firstly, place the <video>
and <canvas>
elements in your HTML. Give your dimensions(width, height) to <canvas>
according to your video. And of course, hide your video with the hidden attribute or “display: none” styling. Because <canvas>
will do the trick for you ;) Let’s go through them one by one.View
<canvas width="1280" height="720"></canvas>
<video src="foo.mp4" preload="auto" autoplay playsinline webkit-playsinline muted hidden></video>
We’re hiding the video element because we just want<canvas>
to show the video, not<video>
element itself.
Declarations
Let’s declare the variables that will be used.
// These our <canvas> and <video> elements that will be used later.
const canvas = document.querySelector('canvas')
const video = document.querySelector('video')
// fps means frame per second. It’s important according to the video’s
// frame. You may want to use it as 24, or 30, or 60. It will be used
// for the intervals millisecond value.
const fps = 60
// width and height are the dimensions in pixels of the video. They
// will be given to the canvas element. If you do not specify them,
// <canvas> will take 300 for width and 150 for height as default
// which may break your view.
const width = 1280
const height = 720
// I will use canvasInterval variable to set and clear an interval to
// make <canvas> follow and unfollow the <video> element.
const canvasInterval = null
Logic
Here is the magical part, with the whole code.
const canvas = document.querySelector('canvas');
const video = document.querySelector('video');
const fps = 60;
const width = 1280;
const height = 720;
const canvasInterval = null;
drawImage() {
canvas.getContext('2d', {
alpha: false
}).drawImage(video, 0, 0, width, height);
}
canvasInterval = window.setInterval(() => {
drawImage(video);
}, 1000 / fps);
video.onpause = function() {
clearInterval(canvasInterval);
};
video.onended = function() {
clearInterval(canvasInterval);
};
video.onplay = function() {
clearInterval(canvasInterval);
canvasInterval = window.setInterval(() => {
drawImage(video);
}, 1000 / fps);
};
drawImage()
method draws the video onto the canvas. video.onpause()
, video.onended()
, and video.onplay()
methods are related to the performance issue. When the video paused or ended, we do not need to draw <video>
onto the<canvas>
, because you know, the frame is not changing after paused or ended. And when the <video>
starts playing/resuming, <canvas>
should start/resume drawing the <video>
onto <canvas>
as well.