HTML Canvas合成:鼠标移动擦除上层画布显露下层图片
实现方案
你只需要修改现有JS代码补充擦除逻辑、修正坐标计算即可,完整可运行的修改代码如下:
1. 核心实现逻辑说明
- 用canvas的
globalCompositeOperation = 'destination-out'合成模式,实现画新内容时擦除上层画布已有白色遮罩的效果 - 新增全局配置项,可直接调整擦除的形状和尺寸
- 修正鼠标坐标计算:原
clientX/Y是相对于浏览器视口的坐标,需要减去canvas元素的视口偏移,才能得到画布内的正确坐标 - 将上层画布上下文等公共变量挂载到window对象,方便跨函数调用
2. 修改后的完整JavaScript代码
// 擦除配置项,可自定义修改 const eraseConfig = { shape: 'circle', // 可选值 circle 圆形 / square 方形 size: 20 // 擦除的尺寸,单位像素 } window.onload = function() { //Create Bottom canvas & context var canvas = document.getElementById('canvas'); var ctxB = canvas.getContext('2d'); //Create Top canvas & context var canvas2 = document.getElementById('canvas2'); // 挂载到window,方便外部函数调用 window.ctxT = canvas2.getContext('2d'); window.canvas2 = canvas2; //Set waterfall image variable var waterfall = document.getElementById('waterfall'); //Set canvas w&h properties canvas.width = canvas2.width = waterfall.width; canvas.height = canvas2.height = waterfall.height; //Populate Bottom canvas with image ctxB.drawImage(waterfall, 0, 0, canvas.width, canvas.height); //Populate Top canvas with white rectangle ctxT.fillStyle = "white"; ctxT.fillRect(0, 0, canvas2.width, canvas2.height); } //Show Coordinates of mouse on Top canvas function HandleMouseMove(event) { // 计算canvas在视口的偏移,得到画布内的正确坐标 const rect = window.canvas2.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; // 显示坐标 var coords = x.toFixed(0) + ", " + y.toFixed(0); document.getElementById("demo").innerHTML = coords; // 擦除逻辑 const ctx = window.ctxT; ctx.save(); // 设置合成模式为擦除已有内容 ctx.globalCompositeOperation = 'destination-out'; if(eraseConfig.shape === 'circle') { // 画圆形擦除区域 ctx.beginPath(); ctx.arc(x, y, eraseConfig.size/2, 0, Math.PI * 2); ctx.fill(); } else if(eraseConfig.shape === 'square') { // 画方形擦除区域 ctx.fillRect(x - eraseConfig.size/2, y - eraseConfig.size/2, eraseConfig.size, eraseConfig.size); } ctx.restore(); }
3. 可选优化(按需开启)
如果需要实现「按住鼠标左键拖动才擦除,悬停不擦除」的交互,只需加个状态控制即可:
// 新增全局变量 let isDragging = false; // window.onload里补充绑定事件 window.onload = function() { // ...原有逻辑不变 canvas2.addEventListener('mousedown', () => isDragging = true); canvas2.addEventListener('mouseup', () => isDragging = false); canvas2.addEventListener('mouseleave', () => isDragging = false); } // HandleMouseMove里的擦除逻辑加判断 function HandleMouseMove(event) { // ...原有坐标计算逻辑不变 if(!isDragging) return; // 没按住鼠标就不执行擦除 // ...原有擦除逻辑不变 }
内容的提问来源于stack exchange,提问作者marg
相关产品推荐
相关产品推荐

