如何实现Canvas路径内部透明的剪纸效果?
实现Canvas剪纸透明效果的解决方案
要实现你要的「剪纸」透明效果,clip()方法并不适用(它只是限制后续绘制的区域范围,无法让已有内容变为透明),正确的做法是利用Canvas的全局合成模式(globalCompositeOperation),通过destination-out模式来「挖掉」三角形区域,让它们变成真正的透明状态。
核心原理
destination-out模式的作用是:新绘制的图形区域会将画布上已有的内容清除为透明,相当于在已有图层上挖洞,完全匹配你的剪纸需求。
修改后的完整代码
JavaScript部分
function draw() { var canvas = document.getElementById('test'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); // 1. 先绘制完整的绿色背景层 ctx.fillStyle = 'green'; ctx.fillRect(0, 0, 400, 300); // 高度与canvas实际高度保持一致 // 2. 切换合成模式为destination-out,准备挖洞 ctx.globalCompositeOperation = 'destination-out'; // 绘制第一个三角形(挖第一个透明洞) ctx.beginPath(); ctx.moveTo(50, 70); ctx.lineTo(100, 100); ctx.lineTo(150, 200); ctx.closePath(); ctx.fill(); // 绘制第二个三角形(挖第二个透明洞) ctx.beginPath(); ctx.moveTo(100, 170); ctx.lineTo(300, 200); ctx.lineTo(350, 300); ctx.closePath(); ctx.fill(); // 如果之后需要继续绘制正常内容,记得改回默认合成模式 // ctx.globalCompositeOperation = 'source-over'; } }
HTML部分
<body onload="draw();"> <!-- 注意:canvas的width/height属性直接写数值,不要加px后缀 --> <canvas id="test" width="400" height="300" style="background: url('你的背景图路径') center/cover;"></canvas> </body>
关键注意点
- 必须先绘制完整背景层,再切换合成模式挖洞,顺序不能颠倒
- canvas的
width和height属性是像素数值,添加px后缀会导致画布尺寸异常 - 后续若要恢复正常绘制,需将
globalCompositeOperation改回默认的source-over
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

