javascripthtmlcanvashtml5-canvasimage-clipping

Canvas Animate Clipping Mask Path


I want to (I have accomplished 1-3):

  1. grab an image from the page
  2. add it to a canvas element
  3. clip the image to a mask
  4. move (animate) the mask around the image

I have accomplished the first 3, but cannot figure out how to move the mask.. Please help!

// get the canvas
var canvas = document.getElementById('c');
var context = canvas.getContext('2d');  

// get a div from the page
var stuff = document.getElementsByName('testElem')[0];

// add a class to the div
stuff.setAttribute('class', 'pleaseWork');
var newImage = new Image();

// get the background image of the div
var bgClass = document.getElementsByClassName('pleaseWork')[0].style.backgroundImage;

  var x = canvas.width / 2;
  var y = canvas.height / 2;
  var radius = 75;
  var offset = 50;  

  // clip the context to create a circular clipping mask
  context.save();
  context.beginPath();
  context.arc(x, y, radius, 0, 2 * Math.PI, false);
  context.clip();

// on load put the image into the clipping mask
newImage.onload = function () {
    context.drawImage(newImage,0,0);
}

// put the background image from the div into the canvas (without the url())
newImage.src = bgClass.replace(/^url|[\(\)]/g, '');

How can I move (animate) the clipping mask from the canvas to show different parts of the clipped image?

Thanks for any ideas!


Solution

  • You can put your clip+drawing code in a function and call that function inside an animation loop:

    Example code and a Demo: http://jsfiddle.net/m1erickson/07mzbat9/

    Drawing Function:

    function draw(){
    
        // clear the canvas
        ctx.clearRect(0,0,cw,ch);
    
        // save the unclipped context
        ctx.save();
    
        // draw a circular path
        ctx.beginPath();
        ctx.arc(cx,cy,radius,0,PI2);
        ctx.closePath();
        ctx.stroke();
    
        // create a clipping path from the circular path
        // use the clipping path to restrict drawing 
        ctx.clip();
        ctx.drawImage(img,0,0);
    
        // restore the unclipped context (to remove clip)
        ctx.restore();
    }
    

    Animation loop:

    var cw=canvas.width;
    var ch=canvas.height;
    var cx=50;
    var cy=50;
    var radius=35;
    var PI2=Math.PI*2;
    
    // animate the mask across the canvas
    function animate(time){
        if(cx-radius>cw || cy-radius>ch){return;}
        requestAnimationFrame(animate);
        cx+=0.2;
        cy+=0.2;
        draw();
    }