上一篇介绍了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 Path
ctx2.save();

ctx2.beginPath();
ctx2.moveTo(0, 20);
ctx2.lineTo(50,0);
/// ... more here - see demo
ctx2.lineTo(400, 20);
ctx2.lineTo(400, 100);
ctx2.lineTo(0, 100);
ctx2.closePath();

/// define this Path as clipping mask
ctx2.clip();

// Create an image element
var img = document.createElement('IMG');
 
// When the image is loaded, draw it
img.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 image
img.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/
posted on 2015-01-23 19:03  zhusheng  阅读(3762)  评论(0编辑  收藏  举报