HTML5画布移动的Alpha蒙版

7
我有一个背景,假设它是绿色的草地。在背景上方有一个黑色遮罩。现在我想在遮罩中创建一个可移动的孔,这样你就可以看到下面的背景,就像下面的图像一样。
我的问题是如何实现上述图像中的效果?如果是HTML,我会有两个草地图像,一个作为背景,另一个位于带有边界半径的div上方的覆盖层中,可以移动和计算位置。
谢谢。

这不是一个问题吗? - tbleckert
公平地说,也许这个问题太宽泛了?也许应该将它移动到程序员的StackExchange上? - mafafu
所以说询问技术是错误的吗?像“使用剪切路径”这样简单的回答对我来说就足够了。我只是不知道要寻找什么。 - tbleckert
2个回答

10

您是否正在寻找一种类似于“手电筒”的移动效果?

如果是这样,您可以通过绘制一个圆形路径,并将其作为剪切区域使用:context.clip();

在.clip()之后绘制的任何内容都将通过剪辑路径显示。

以下是代码和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>

哦,谢谢,这正是我想要的。我会试一试并回来。 - tbleckert
如果我要在你的代码中添加一个停止/开始按钮来控制视图圆的运动,我需要调整什么? - Charles Haughey

2

我曾经为一个小型画布测试做了类似的事情。你可以创建一个带有画布元素的div,将其放在底层上方,并在该顶层画布上绘制具有透明度的径向渐变。这里有一个演示:http://jsfiddle.net/CnEBQ/14/

特别是要看一下这段径向渐变的代码。该上下文附加到顶部div画布上:

var gradient = tCTX.createRadialGradient(CANVAS_SIZE.x/2, CANVAS_SIZE.y/2, 250, CANVAS_SIZE.x/2, CANVAS_SIZE.y/2, 0);  
gradient.addColorStop(0, "#000");  
gradient.addColorStop(1, "transparent");  
tCTX.fillStyle = gradient;
tCTX.fillRect(0, 0, CANVAS_SIZE.x, CANVAS_SIZE.y);  

这里可能有一些糟糕的代码,但是这应该能让您了解是否需要继续。您可以在计时器或某些事件上根据需要重绘顶部图层“孔”以使其移动。您可以调整渐变设置以获得更多或更少的“黑暗度”。

我很难找到一个好的参考来解释我在这里使用的函数,但查找更多关于这些函数的说明的不错地方是 Mozilla Canvas API 其中解释了渐变函数的参数。特别有用,因为它们并不立即显而易见。


不错的效果——将渐变作为透明度! - markE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接