咱們都知道在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、前端可視化方面有深刻研究。對程序員思惟能力訓練和培訓、程序員職業規劃有濃厚興趣。