Canvas中destination-atop模式无法完整显示内容,如何实现擦除露出标题?
解决方案
要实现“用画笔擦除黄色背景,逐步显现标题”的效果,你需要调整绘制顺序和正确的合成模式,具体修改如下:
核心问题分析
你之前使用destination-atop不符合需求:这个合成模式的规则是「新绘制的内容仅在已有内容的区域显示,同时保留已有内容」,导致线条只能出现在标题位置,无法实现擦除效果。而我们需要的是「用新绘制的线条清除已有背景,露出下方标题」,对应合成模式是destination-out。
修改后的代码
JavaScript 部分
window.requestAnimationFrame(draw); let FirstTime = Date.now(); function draw(){ var canvas = document.getElementById("myCanvas"); const width_mid = canvas.width/2; const height_mid = canvas.height/2; var timeStamp = Date.now(); var num = Math.floor((timeStamp-FirstTime)/300); if(num>15) return; var ctx = canvas.getContext("2d"); // 1. 先绘制最终要显示的标题 ctx.font = "200px 华文行楷"; ctx.textAlign="center"; ctx.fillText("CHH算法网", width_mid, height_mid+40); // 2. 用黄色填充整个画布,覆盖标题作为可擦除的背景 ctx.fillStyle = "rgb(255, 213, 0)"; ctx.fillRect(0, 0, canvas.width, canvas.height); // 3. 设置合成模式:新绘制内容会清除已有背景(黄色区域) ctx.globalCompositeOperation = 'destination-out'; // 4. 绘制曲线,作为“橡皮擦” ctx.beginPath(); ctx.moveTo(0,300); ctx.quadraticCurveTo(70,100,200,70); var end_x=200; var bezier_x; for(var i=0;i<num;i++){ if(i%2==0){ end_x+=10; bezier_x=end_x+100; } else{ end_x+=200; bezier_x=end_x-130; } ctx.quadraticCurveTo(bezier_x,i%2?100:100,end_x,i%2?70:280); } ctx.lineWidth=200; ctx.stroke(); // 重置合成模式(避免后续绘制受影响) ctx.globalCompositeOperation = 'source-over'; window.requestAnimationFrame(draw); }
关键修改点
- 绘制顺序调整:先画标题,再用黄色画布覆盖标题,最后用线条擦除黄色
- 合成模式替换:用
destination-out替代destination-atop,该模式会让新绘制的线条区域清除掉已有的黄色背景,露出下方的标题 - 填充画布背景:新增
fillRect用黄色填满整个画布,确保标题被完全覆盖,之后通过擦除逐步显现
内容的提问来源于stack exchange,提问作者LRR
相关产品推荐
相关产品推荐

