标签:
上一篇介绍了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/
标签:
原文地址:http://www.cnblogs.com/zhusheng2008/p/4244901.html