1

background

I have a looping video of some time-lapsed clouds downloadable here. I would like to add a gradient over top of the clouds in real time.

I would put live link to code however, video cannot be streamed played with via canvas due to security. so please download video if you want a sample (or your own)

The end result (I made in Photoshop): cloud's gradient

In the end, I'll be generating the colors of this gradient at run time.

question

How do I create a linear gradient over my canvas that will alter the video?

code

html:

<canvas id="c"></canvas>
<video autoplay  loop id="v">
    <source src='images/cloud.mp4'  type='video/mp4' />
</video>

css:

#c {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: 100%;
}

javascript:

document.addEventListener('DOMContentLoaded', function(){
    var v = document.getElementById('v');
    var canvas = document.getElementById('c');
    var context = canvas.getContext('2d');
    var back = document.createElement('canvas');
    var backcontext = back.getContext('2d');

    var cw,ch;

    v.addEventListener('play', function(){
        cw = v.clientWidth;
        ch = v.clientHeight;
        canvas.width = cw;
        canvas.height = ch;
        back.width = cw;
        back.height = ch;
        draw(v,context,backcontext,cw,ch);
    },false);

},false);

function draw(v,c,bc,w,h) {
    if(v.paused || v.ended) return false;
    // First, draw it into the backing canvas
    bc.drawImage(v,0,0,w,h);
    // Grab the pixel data from the backing canvas
    var idata = bc.getImageData(0,0,w,h);
    var data = idata.data;

    // Currently this loops through the pixels, turning them grayscale as a proof of concept.  I believe this is where the gradient + blending modes would go.
    for(var i = 0; i < data.length; i+=4) {
        var r = data[i];
        var g = data[i+1];
        var b = data[i+2];
        var brightness = (3*r+4*g+b)>>>3;
        data[i] = brightness;
        data[i+1] = brightness;
        data[i+2] = brightness;
    }
    idata.data = data;
    // Draw the pixels onto the visible canvas
    c.putImageData(idata,0,0);
    // Start over!
    setTimeout(function(){ draw(v,c,bc,w,h); }, 0);
}

notes

  1. The colors are easier in hsla and I would like to change the Hue at run time.

Colors:

----HSLA(268,92%,19%,.5);

----HSLA(30,100%,50%,.5);
  1. The gradient has a blending mode of Overlay.
Armeen Moon
  • 18,061
  • 35
  • 120
  • 233
  • What's the issue ? create the gradient and fillRect the canvas with desired blending mode. And just drawImage the video, do not use get/putImageData. – GameAlchemist Jul 29 '14 at 10:28
  • I think you got me further in thought. But for the blending modes like multiply it takes to parameters (target *blend) so I'll have two loops that iterate through both canvas pixel by pixel and then paint to a final canvas at the end? Or is there a helper for blending modes? – Armeen Moon Jul 29 '14 at 16:31
  • Do not do it by hand when you can have the canvas (hence the GPU) do it for you 20 times faster. In fact there is, since a few month, a new feature not so well known, supported on Chrome and FF, which allows to define a blending mode as globalCompositeOperation. ( look here : http://dev.w3.org/fxtf/compositing-1/#canvascompositingandblending ) – GameAlchemist Jul 29 '14 at 16:47
  • ugh this is so over my head. – Armeen Moon Jul 30 '14 at 02:02

0 Answers0