1

Is it possible to add a background video that will loop over and over to a HTML5 Canvas? This is that work I have so far just want to add a simple video that will play to the background. I am able to add video to the HTML with the video tag but want it played on the canvas itself.

<canvas id="ex1" width="525" height="200" style="border: 5px solid black;" ></canvas>

<p id="text"> Increase/Decrease Speed</p>
<input type="button" value="+" id="btnAdd">
<input type="button" value="-" id="btnSub">

<script>
var x = 0;
var y = 15;
var speed = 10;
var isRight = true;

document.getElementById('text').innerText = speed;

document.getElementById('btnAdd').addEventListener('click', function (event) {

    if (isRight) speed++;
    else speed--;
    document.getElementById('text').innerText = speed;

    });

document.getElementById('btnSub').addEventListener('click', function (event) {
    if (isRight) speed--;
    else speed++;
    document.getElementById('text').innerText = speed;

    });

function animate() {

    reqAnimFrame = window.mozRequestAnimationFrame ||   window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame;

    reqAnimFrame(animate);

    x += speed;

    if (x <= 0 || x >= 475) {
        speed = -speed;

        isRight = !isRight;
    }
    document.getElementById('text').innerText = speed;

    draw();
  }

 function draw() {
    var canvas = document.getElementById("ex1");
    var context = canvas.getContext("2d");

    context.clearRect(0, 0, 525, 200);
    context.fillStyle = "#ff00ff";
    context.fillRect(x, y, 40, 40);
  }

animate();
  </script>
Jessica
  • 179
  • 1
  • 5
  • 15
  • 2
    http://html5doctor.com/video-canvas-magic/ – adeneo Dec 04 '13 at 01:23
  • The basic process is that you create a video element and hide it with CSS, then draw the video to the canvas in your animate loop using the drawImage method of the canvas context. – net.uk.sweet Dec 04 '13 at 01:29
  • I don't see anything related to video in the posted code? –  Dec 04 '13 at 08:57

2 Answers2

2

A frame currently running in a video element can be copied to canvas. Using setInterval we have to regularly sample the video element and copy it to canvas. It can be used to do interesting stuff.

From Mozilla drawImage

The first parameter can be any element to draw into the context; the specification permits any image element (that is, <img>, <canvas>, and <video>).

Here is a boiler plater code sample -

var videoElement, canvasContext;

videoElement.addEventListener('play', function(){
    copyCurrentFrameIntoCanvas(this);
    setInterval(copyCurrentFrameIntoCanvas,10,this);
},false);

function copyCurrentFrameIntoCanvas(videoElement) {
    canvasContent.drawImage(videoElement,0,0,<width>,<height>);
}

You need to initialise the videoElement and canvasContent appropriately which i think you know already. Also replace <width> and <height> placeholders appropriately.

Vikram Rao
  • 514
  • 3
  • 16
1

You can create an off-screen video element so you won't have to deal with CSS or cause extra reflowing. To create an off-screen video element is simple:

/// element
var video = document.createElement('video');

/// set video elemet size
video.width = 640;
video.height = 360;

/// setup with auto preload and loop
video.preload = 'auto';
video.loop = true;

Now you can attach an event handler so you start drawing when the video is ready to be played:

video.addEventListener('canplay', start, false);

Now set the source of the video. You need to check what types the browser can play by using the video.canPlayType('<mime-type-here>') method but for simplicity we set the source directly:

video.src = 'link/to/video.ogv';

In the handler we can now update the video. As the requestAnimationFrame tries to update 60 times per second we can reduce it to half as video is rarely above 30 FPS (US, 25 in Europe):

function start() {

    /// get context from canvas (canvas not shown in example)        
    var ctx = canvas.getContext('2d'),
        toggle = true;                  /// this is used to reduce FPS

    /// start video
    video.play();

    /// start loop
    requestAnimationFrame(loop);

    function loop() {

        /// reduce frame-rate to half
        toggle = !toggle;    

        if (toggle) {
            requestAnimationFrame(loop);
            return;
        }

        /// draw video frame
        ctx.draw(video, 0, 0);

        requestAnimationFrame(loop);
    }
}

Disclaimer: untested but you see the main steps. The code should create the video element and auto-start it when it's ready. Then it will run in a loop and draw the video frame to canvas every 30 FPS (or so).

Note: Safari browser do not support drawImage with a video element in iOS (at the moment writing this answer).