首页 > 代码库 > canvas 遮罩

canvas 遮罩

上一篇介绍了CSS3可以实现mask的方式,本篇介绍canvas同样也可以实现遮罩的方法:

原理:

 canvas是在画布上绘图,可以绘制各种形状,同时可以在一个层上重复画图,默认情况下后面的会覆盖前面的图,但是有一个属性可以设置多个图重复时的显示规则,就如同css3中的-webkit-mask-composite一样,canvas有一个属性叫globalCompositeOperation,他可以有以下取值:

        source-over(默认值):在原有图形上绘制新图形

        destination-over:在原有图形下绘制新图形

        source-in:显示原有图形和新图形的交集,新图形在上,所以颜色为新图形的颜色

        destination-in:显示原有图形和新图形的交集,原有图形在上,所以颜色为原有图形的颜色

        source-out:只显示新图形非交集部分

        destination-out:只显示原有图形非交集部分

        source-atop:显示原有图形和交集部分,新图形在上,所以交集部分的颜色为新图形的颜色

        destination-atop:显示新图形和交集部分,新图形在下,所以交集部分的颜色为原有图形的颜色

        lighter:原有图形和新图形都显示,交集部分做颜色叠加

        xor:重叠飞部分不现实

        copy:只显示新图形

此前有张图可以看出区别:

技术分享

 

为了实现遮罩,我们使用的值是 destination-out:只显示原有图形非交集部分,这样两层图形非交集部分的源图形将会显示,也就是第一层图形(源图形),而两者交集部分将不显示,也就是变成透明,这样背景图就会显示出来。

具体的区别可以通过以下的例子查看:

<!DOCTYPE html><html><head>    <title>简单的mask</title>    <style type=‘text/css‘>        #main_div{            width:300px;            height:300px;            background-color:silver;        }        #tips{            margin-top:10px;            font-size:13px;        }        #tenpay_txt{            width:879px;            height:234px;            margin-top:50px;            border:solid 1px silver;            background:url(‘back.jpg‘) no-repeat;        }    </style></head>           <body>    <div id="main_div"></div>    <div id="buttons">        <input type=‘button‘ id="showCanvas1" value="绘制目标层" onclick="showCanvas1()"></input>        <select id="select_type">            <option value="source-over">source-over</option>            <option value="destination-over">destination-over</option>            <option value="source-in">source-in</option>            <option value="source-out">source-out</option>            <option value="destination-out">destination-out</option>            <option value="source-atop">source-atop</option>            <option value="destination-atop">destination-atop</option>            <option value="lighter">lighter</option>            <option value="xor">xor</option>            <option value="copy">copy</option>        </select>        <input type=‘button‘ id="showCanvas2" value="绘制源层" onclick="showCanvas2()"></input>        <input type=‘button‘ id="showCanvas2" value="清空区域" onclick="clearCanvas()"></input>    </div>    <div id="tips">        红色为源图形,白色为目标图形    </div>            <script type="text/javascript">        var main_div = document.getElementById("main_div");        var canvas_s=document.createElement("canvas");          canvas_s.width=300;          canvas_s.height=300;          main_div.appendChild(canvas_s);          canvas_s.style.position="absolute";                          var c_context = canvas_s.getContext("2d");                function showCanvas1(){                        c_context.fillStyle = "white";            c_context.fillRect(50,50,200,200);        }        function showCanvas2(){                    var type = document.getElementById("select_type").value;            c_context.globalCompositeOperation=type;            c_context.fillStyle = "red";            c_context.fillRect(75,75,150,150);        }        function clearCanvas(){            c_context.clearRect(0,0,300,300);        }            </script>        <div id="tenpay_txt">    </div>            <script type="text/javascript">        var tenpay_txt = document.getElementById("tenpay_txt");        var canvas = document.createElement("canvas");          canvas.width=879;          canvas.height=234;          tenpay_txt.appendChild(canvas);          canvas.style.position="absolute";                          var context = canvas.getContext("2d");        var left_start = 100;        var left_right = 780;        var left_now = left_start;        var left_step = 5;        var direction = 1;        setInterval(drawMask,30);                        function drawMask()        {                        if(direction == -1 && left_now == left_start){                direction = 1;            }            if(direction ==1 && left_now > left_right){                direction = -1;            }            left_now += left_step*direction;                            context.clearRect(0,0,canvas.width,canvas.height);            context.globalCompositeOperation="source-over";              context.fillRect(0,0,canvas.width,canvas.height);            context.globalCompositeOperation="destination-out";            context.beginPath();              context.arc(left_now,130,100,0,Math.PI*2,true);              context.fill();                }            </script></body></html>

 

 

通过这种方法可以实现各种遮罩,包括刮刮卡等效果,具体可以自己动手试验下,不算复杂。

 

 

/// use save when using clip Pathctx2.save();ctx2.beginPath();ctx2.moveTo(0, 20);ctx2.lineTo(50,0);/// ... more here - see democtx2.lineTo(400, 20);ctx2.lineTo(400, 100);ctx2.lineTo(0, 100);ctx2.closePath();/// define this Path as clipping maskctx2.clip();

// Create an image elementvar img = document.createElement(‘IMG‘); // When the image is loaded, draw itimg.onload = function () {     // Save the state, so we can undo the clipping    ctx.save();     // Create a shape, of some sort    ctx.beginPath();    ctx.moveTo(10, 10);    ctx.lineTo(100, 30);    ctx.lineTo(180, 10);    ctx.lineTo(200, 60);    ctx.arcTo(180, 70, 120, 0, 10);    ctx.lineTo(200, 180);    ctx.lineTo(100, 150);    ctx.lineTo(70, 180);    ctx.lineTo(20, 130);    ctx.lineTo(50, 70);    ctx.closePath();    // Clip to the current path    ctx.clip();     ctx.drawImage(img, 0, 0);     // Undo the clipping    ctx.restore();} // Specify the src to load the imageimg.src = "http://i.imgur.com/gwlPu.jpg";
/// draw the image ctx2.drawImage(img, 0, 0); /// reset clip to default ctx2.restore();




http://jsfiddle.net/jimrhoskins/dDUC3/1/

canvas 遮罩