HTML5 Canvas 如何使用destination-out仅清除最新绘制的图形?
问题原因
destination-out 全局合成模式的作用逻辑是:新绘制的图形与画布上所有已有像素重叠的区域都会被清除。你的代码中绘制的圆形同时和上层蓝色、下层绿色重叠,因此两层的重叠部分都会被删除,无法看到绿色透出。
解决方案1:使用奇偶填充规则直接绘制带洞的蓝色矩形
不需要修改合成模式,直接把蓝色矩形和圆形孔洞作为同一路径的两个子路径,使用evenodd(奇偶)填充规则,重叠的圆形区域会自动变为透明,只保留蓝色矩形的剩余部分,不会影响下层已经绘制的绿色。
修改后的JS代码:
const ctx = document.querySelector("#canvas").getContext("2d"); // 绘制底层绿色矩形 ctx.fillStyle = "green"; ctx.fillRect(0, 0, 50, 100); // 绘制带圆形孔洞的蓝色矩形 ctx.fillStyle = "blue"; ctx.beginPath(); // 添加蓝色矩形路径 ctx.rect(0, 0, 50, 50); // 添加需要挖除的圆形路径 ctx.arc(50 / 2 - 10 / 2, 50 / 2, 10, 0, Math.PI * 2); // 按奇偶规则填充,两个路径重叠区域会自动镂空 ctx.fill('evenodd');
HTML代码保持不变:
<canvas id="canvas" width="500" height="200" style="background: black" ></canvas>
解决方案2:使用离屏Canvas单独处理上层蓝色层
如果你的场景需要单独对上层蓝色图层做更多处理,可以先把蓝色矩形和挖洞操作放在离屏Canvas中完成,再把处理好的带洞蓝色图层整体绘制到主画布,完全不会影响下层的绿色内容。
对应JS代码:
const ctx = document.querySelector("#canvas").getContext("2d"); // 绘制底层绿色矩形 ctx.fillStyle = "green"; ctx.fillRect(0, 0, 50, 100); // 创建离屏Canvas专门处理蓝色层 const offscreenCanvas = document.createElement('canvas'); const offCtx = offscreenCanvas.getContext('2d'); offscreenCanvas.width = 50; offscreenCanvas.height = 50; // 离屏画布绘制蓝色矩形 offCtx.fillStyle = "blue"; offCtx.fillRect(0, 0, 50, 50); // 离屏画布上挖除圆形孔洞 offCtx.globalCompositeOperation = "destination-out"; offCtx.beginPath(); offCtx.arc(50 / 2 - 10 / 2, 50 / 2, 10, 0, Math.PI * 2); offCtx.fill(); // 将处理好的带洞蓝色层绘制到主画布 ctx.drawImage(offscreenCanvas, 0, 0);
内容的提问来源于stack exchange,提问作者Kazuto_Ute
相关产品推荐
相关产品推荐

