Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 Canvas moving alpha mask

I have a background, let's say it's green grass. On top of the background I have a black overlay. What I want now is to make a movable hole in the overlay so that you can see the background like in the image below.

enter image description here

I am pretty new to canvas so I'm not sure what I'm supposed to look for. Alpha mask?

So my question is how can I achieve the effect demonstrated in the image above?

If it were HTML I would have two images of the grass, one as the background and one above the overlay in a div with a border radius that can move and just calculate positions.

Thanks.

like image 900
tbleckert Avatar asked Mar 08 '13 18:03

tbleckert


1 Answers

Are you looking for a moving "flashlight" kind of effect?

If so, you can do that by drawing a circular path and then using it as a clipping region with: context.clip();

Anything drawn after the .clip() will be viewed through the clipping path.

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/pRzxt/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
    $(function(){

        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");


        window.requestAnimFrame = (function(callback) {
          return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
          function(callback) {
            window.setTimeout(callback, 1000 / 60);
          };
        })();

        var radius=50;
        var x=100;
        var dx=10;
        var y=100;
        var dy=10;
        var delay=10;
        var img=new Image();
        img.onload=function(){
            var canvas1=document.getElementById("image");
            var ctxImg=canvas1.getContext("2d");
            ctxImg.drawImage(img,0,0,img.width,img.height,0,0,canvas.width,canvas.height);
            animate();
        }
        img.src="http://lh3.ggpht.com/_Z-i7eF_ACGI/TRxpFywLCxI/AAAAAAAAAD8/ACsxiuO_C1g/house%20vector.png";

        function animate() {
          if(--delay<0){
                    // update
                    x+=dx;
                    if(x-radius<0 || x+radius>=canvas.width){dx=-dx;}
                    y+=dy;
                    if(y-radius<0 || y+radius>=canvas.height){dy=-dy;}
                    delay=10;

                    // draw stuff
                    ctx.clearRect(0, 0, canvas.width, canvas.height);
                    ctx.save();
                    ctx.beginPath();
                    ctx.arc(x,y, radius, 0, 2 * Math.PI, false);
                    ctx.clip();
                    ctx.drawImage(img,0,0,img.width,img.height,0,0,canvas.width,canvas.height);
                    ctx.restore();
          }

          // request new frame
          requestAnimFrame(function() {
            animate();
          });
        }


    }); // end $(function(){});
</script>

</head>

<body>
<p>Image clipped by moving circle</p>
<canvas id="canvas" width=300 height=200></canvas>
<br/><p>Unclipped image</p>
<canvas id="image" width=300 height=200></canvas>

</body>
</html>
like image 179
markE Avatar answered Sep 20 '22 10:09

markE