A problem I ran into with HTML5 video at 720p/i is screen tearing. That’s where some frames have ‘rips’ with a noticeable effect. As an artist and developer, minute mistakes like this annoy me.

At the time, I tested an animation library for HTML5 Canvas, and requestAnimationFrame(). It worked quite effectively at 60fps, with no tearing. So I asked, “How would the video perform if I painted it on the canvas?”

Maybe I’m stupid, or crazy, for rendering video onto canvas (with no intent of modifying the video). After all, it takes more resources to paint two images: the original <video> element, and the <canvas> element.

After giving it a shot, I’ve learned I can ensure the video frame is only painted when the animation frame is available to the browser. Typically this is at 60fps, but lower performance can bring it down to far less.

It’s possible the <video> element does not render with requestAnimationFrame(), but instead its own process. However, since each web page has a single UI thread, wouldn’t it make sense to operate on it? View the code sample at the end of this article.

The result: The video-to-canvas approach helped fix the screen tearing. (It may not be absolute, but its definitely far less detectable).

The cost: An extra pass of rendering in the UI thread.

Bonus Tip: Use web workers to control animation FPS. (Yes, requestAnimationFrame() is available in web workers, even though Web workers don’t have a UI thread!)

Code Sample

<video id="vidMain" width="1280" height="720" style="display:none;"></video>
<canvas id="canMain" width="1280" height="720"></canvas>
const video = document.getElementById('vidMain');
const canvas = document.getElementById('canMain');
let brush = canvas.getContext('2d');

//paints the video to the canvas
function paint() {
brush.drawImage(video, 0, 0, 1280, 720); //keep painting window.requestAnimationFrame(paint); } //event handlers video.oncanplaythrough = function() { video.play(); paint(); }; video.src = "../movie.mp4";

A more elegant solution should include events for play, pause, and errors, etc. A flag should be set to paint or not paint for the pausing.