咱们都知道在canvas 能够经过clip来实现剪裁功能,其步骤通常是先设置要裁剪的区域(路径),而后经过ctx.clip()的实现裁剪,裁剪以后,后续的绘制只能在裁剪的区域显示效果,好比以下一段代码,实现了一个圆形裁剪:javascript
ctx.beginPath();
ctx.arc(100,100,50,0,Math.PI*2); ctx.clip(); ctx.rect(0,0,200,200); ctx.fillStyle='red'; ctx.fill();
最终效果以下:html
有的时候,咱们但愿可以实现反向裁剪,好比上面例子中,咱们但愿是圆圈外面是裁剪区域,而不是圆圈内部是裁剪区域。这就是标题所说的反向裁剪。效果以下图所示:前端
如何实现反向裁剪呢?
笔者经过实践,发现有如下几种思路。html5
经过设置globalCompositeOperation的值,能够实现相似的反向裁剪的效果。大体思路是:java
示例代码以下:node
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI * 2); ctx.fillStyle = 'red'; ctx.fill(); ctx.beginPath(); ctx.globalCompositeOperation = 'source-out'; ctx.rect(0, 0, 200, 200); ctx.fillStyle = 'red'; ctx.fill();
最终效果参考上面的图形“反向裁剪”。程序员
另一种思路是使用clip + clearRect方法,大概的思路以下:数据库
示例代码以下:canvas
ctx.beginPath();
ctx.rect(0, 0, 200, 200); ctx.fillStyle = 'red'; ctx.fill(); ctx.beginPath(); ctx.arc(100, 100, 50, 0, Math.PI * 2); ctx.clip(); ctx.clearRect(0, 0, 200, 200);
最终效果参考上面的图形“反向裁剪”。架构
咱们知道非零环绕原则,能够经过调整路径的方向(顺时针和逆时针),来实现挖空的效果,大体思路以下:
示例代码以下:
ctx.beginPath();
ctx.rect(0, 0, 200, 200); //顺时针方向 ctx.arc(100, 100, 50, 0, Math.PI * 2, true); // 逆时针方向 ctx.clip(); ctx.beginPath(); ctx.rect(0, 0, 200, 200); ctx.fillStyle = 'red'; ctx.fill();
arc方法的最后一个参数能够控制顺时针(false)和逆时针(true),而rect方法没有,能够经过moveTo,lineTo,本身构建逆时针的rect方法,以下代码所示:
function counterclockwiseRect(ctx, x, y, w, h) { ctx.moveTo(x, y); ctx.lineTo(x, y + h); ctx.lineTo(x + w, y + h); ctx.lineTo(x + w, y); ctx.lineTo(x, y); }
最终效果参考上面的图形“反向裁剪”。
https://stackoverflow.com/questions/22168619/reverse-clipping-in-canvas
https://stackoverflow.com/questions/18988118/how-can-i-clip-inside-a-shape-in-html5-canvas
http://caibaojian.com/canvas/21.html(非零环绕原则 )
欢迎关注公众号“ITman彪叔”。彪叔,拥有10多年开发经验,现任公司系统架构师、技术总监、技术培训师、职业规划师。熟悉Java、JavaScript、Python语言,熟悉数据库。熟悉java、nodejs应用系统架构,大数据高并发、高可用、分布式架构。在计算机图形学、WebGL、前端可视化方面有深刻研究。对程序员思惟能力训练和培训、程序员职业规划有浓厚兴趣。