You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Canvas JS中实现擦除时不清除背景?

解决Canvas擦除工具清除背景图片的问题

问题核心

你的擦除工具是用画布当前填充色作为画笔颜色覆盖内容,但图片背景直接绘制在绘画画布上,擦除时会用纯色覆盖掉图片;同时保存功能只存储了绘画线条,未保留背景图片信息,导致加载后背景无法恢复。

解决方案:分离背景层与绘画层

使用两层Canvas实现隔离:

  • 底层Canvas:专门承载背景(纯色或图片),不参与绘画操作
  • 上层Canvas:用于绘画和擦除,初始为透明,擦除时通过混合模式让绘画区域变透明,露出下层背景

具体代码修改

1. 新增背景Canvas变量

// 在原有变量定义后添加
var bgCanvas = document.createElement('canvas');
var bgCtx = bgCanvas.getContext('2d');

2. 修改createCanvas函数,初始化两层画布

function createCanvas() {
    // 初始化背景画布
    bgCanvas.id = "bg-canvas";
    bgCanvas.width = parseInt(document.getElementById("sizeX").value);
    bgCanvas.height = parseInt(document.getElementById("sizeY").value);
    bgCanvas.style.zIndex = 7; // 层级低于绘画画布
    bgCanvas.style.position = "absolute";
    bgCanvas.style.border = "1px solid";
    bgCanvas.style.left = "150px";
    bgCanvas.style.top = "45px";
    // 填充背景色
    bgCtx.fillStyle = currentBg;
    bgCtx.fillRect(0, 0, bgCanvas.width, bgCanvas.height);
    // 绘制背景图片
    if (newImage.complete) {
        bgCtx.drawImage(newImage, 0, 0, 500, 500);
    }
    body.appendChild(bgCanvas);

    // 初始化绘画画布
    canvas.id = "canvas";
    canvas.width = bgCanvas.width;
    canvas.height = bgCanvas.height;
    canvas.style.zIndex = 8;
    canvas.style.position = "absolute";
    canvas.style.border = "none"; // 背景画布已有边框
    canvas.style.left = "150px";
    canvas.style.top = "45px";
    // 绘画画布初始透明,不填充背景
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    body.appendChild(canvas);
}

3. 修改擦除工具逻辑,用混合模式实现透明擦除

function eraser() {
    currentSize = 50;
    currentColor = "rgba(0,0,0,1)"; // 任意颜色,混合模式会生效
    ctx.globalCompositeOperation = 'destination-out'; // 绘制区域变为透明
}

// 切换回绘画模式(颜色选择器触发)
document.getElementById('colorpicker').addEventListener('change', function() {
    currentColor = this.value;
    ctx.globalCompositeOperation = 'source-over'; // 恢复正常绘画模式
});

4. 更新保存与加载功能,同步背景信息

// 保存时同时存储背景和线条
function save() {
    localStorage.removeItem("savedCanvas");
    localStorage.removeItem("savedBg");
    localStorage.setItem("savedCanvas", JSON.stringify(linesArray));
    // 保存背景色和图片地址
    localStorage.setItem("savedBg", JSON.stringify({
        bgColor: currentBg,
        bgImage: newImage.src
    }));
    console.log("Saved canvas!");
}

// 加载时先恢复背景,再重绘线条
function load() {
    // 恢复背景
    if (localStorage.getItem("savedBg") != null) {
        const savedBg = JSON.parse(localStorage.getItem("savedBg"));
        currentBg = savedBg.bgColor;
        newImage.src = savedBg.bgImage;
        newImage.onload = () => {
            bgCtx.fillStyle = currentBg;
            bgCtx.fillRect(0, 0, bgCanvas.width, bgCanvas.height);
            bgCtx.drawImage(newImage, 0, 0, 500, 500);
        }
    }
    // 恢复线条
    if (localStorage.getItem("savedCanvas") != null) {
        linesArray = JSON.parse(localStorage.savedCanvas);
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        redraw();
        console.log("Canvas loaded.");
    } else {
        console.log("No canvas in memory!");
    }
}

5. 修改下载函数,合并两层画布内容

function downloadCanvas(link, canvasId, filename) {
    // 创建临时画布合并背景和绘画层
    const tempCanvas = document.createElement('canvas');
    const tempCtx = tempCanvas.getContext('2d');
    tempCanvas.width = bgCanvas.width;
    tempCanvas.height = bgCanvas.height;
    // 先画背景
    tempCtx.drawImage(bgCanvas, 0, 0);
    // 再画绘画层
    tempCtx.drawImage(document.getElementById(canvasId), 0, 0);
    // 生成下载链接
    link.href = tempCanvas.toDataURL();
    link.download = filename;
}

6. 调整背景色选择器逻辑,修改底层画布

document.getElementById('bgcolorpicker').addEventListener('change', function() {
    currentBg = this.value;
    bgCtx.fillStyle = currentBg;
    bgCtx.fillRect(0, 0, bgCanvas.width, bgCanvas.height);
    // 重新绘制背景图片
    if (newImage.complete) {
        bgCtx.drawImage(newImage, 0, 0, 500, 500);
    }
});

关键修改说明

  • 双层Canvas:彻底分离背景与绘画内容,擦除仅影响上层透明画布,不破坏底层背景
  • destination-out混合模式:绘画区域直接变为透明,无需匹配背景色即可实现擦除
  • 保存背景信息:确保加载时能完整恢复背景状态
  • 合并画布下载:保证导出图片包含完整背景和绘画内容

内容的提问来源于stack exchange,提问作者Stevenseagull

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 19:15:34