当前位置: 首页 > 知识库问答 >
问题:

如何撤消HTML5画布绘制应用的橡皮擦操作

吕霄
2023-03-14

我已经创建了一个HTML5绘图应用程序,它具有基本功能,允许用户选择一种颜色来绘制,改变绘图工具的大小(半径),撤消,重做,以及完全清除画布。

我最近添加了一个橡皮擦工具,使用globalCompositionProperty(desitnation-out)擦除画布的选定区域。这部分工作良好,但当我去撤销擦除,整个画布被清除,重做功能不起作用。当我用常规的绘图工具(使用source-over)恢复绘图时,撤消/重做工作。我已经包含了应用程序中使用的一些函数的代码。每次脱离绘图工具时,我都会存储画布的快照。这将添加到用于撤消和还原画布的数组中。

有人能解释一下我在这里做错了什么吗?我不知道globalCompositeOperation属性如何影响保存的画布DataURI。

function storeSnapshot() {
    cStep++;
    if (cStep < cPushArray.length) { cPushArray.length = cStep; }
    cPushArray.push(canvas.toDataURL());
}

var putPoint = function(e){
    if(dragging){
    context.lineTo(e.clientX - 174, e.clientY - 50);
    context.stroke();
    context.beginPath();
    if(eraser == true){
        context.globalCompositeOperation="destination-out";

    }else{
        context.globalCompositeOperation="source-over"; 
    }
    context.arc(e.clientX - 174, e.clientY - 50 , radius, 0, 2 * Math.PI);
    context.fill();
    context.beginPath();
    context.moveTo(e.clientX - 174, e.clientY - 50);
    }
}

更新:在玩了一段时间后,我尝试了一些东西来修复我的问题。我不确定这是不是正确的做事方法,但我想我会让你们看看我做了什么。

我有一个脱离功能,在鼠标向上触发。下面是前面的函数:

var disengage = function(){
dragging = false;
context.beginPath();
storeSnapshot();
    }

我添加了这段代码,这允许用户使用橡皮擦工具和撤消/重做操作。我还不是很清楚为什么这会起作用,所以如果有人有洞察力的话,我会非常感激。

var disengage = function(){
dragging = false;
context.beginPath();
if(eraser == true)
{
    context.globalCompositeOperation="source-over"; 
}
storeSnapshot();
    }

共有1个答案

慕容宇
2023-03-14

我有和你完全一样的问题,我很高兴我遇到了你的问题/解决方案,因为这对我来说是一个电灯泡的时刻。我一看到你的解决方案,就完全明白是怎么回事了。

为了深入了解解决方案的工作原理,GlobalCompositeOperation是画布的一个属性,它基本上指示了如何将内容(在本例中为线条笔划)放在画布上。默认情况下,它是source-over,它只是在任何现有笔画的顶部放置一个新的行笔画。正如您所提到的,擦除使用的是目标输出,它保留所有现有内容,使其不与新的行笔画重叠(因此擦除)。对于一些信息丰富的图表和解释,我强烈推荐GlobalCompositeOperation的MDN文档:https://developer.mozilla.org/en-us/docs/web/api/CanvasRenderingContext2d/GlobalCompositeOperation

因此,如果进入擦除模式(对您来说,eraser=true),擦除,然后立即尝试撤消,globalCompositeOperation仍然将设置为destination-out。这意味着当撤消尝试将存储的图像绘制到画布时,所有内容都将消失,因为它基本上仍在擦除(正如destination-out所说的,它将丢弃与新内容重叠的任何现有内容,在本例中,新内容是整个画布空间)。因此,您需要像在解决方案中所做的那样,将其设置回source-over,以便恢复的图像实际出现在画布上。希望能有帮助!

 类似资料:
  • 我想使用Fabric.js在我的web应用程序中实现eraser。在Fabric.js中有没有实现橡皮擦的方法?例如,如在MS Paint?

  • 在画布上画画是非常好的。即使橡皮擦也能工作得很好。问题是当画布保存为图像时,它画的是黑线,而不是橡皮擦。 为了更好地理解,我添加了屏幕、镜头和代码。 1.在擦除图的同时- 我不明白为什么橡皮移动被替换为黑色,而保存画布作为一个图像。

  • 我正在一个绘画应用程序,与撤消/重做功能,并希望添加橡皮擦功能。 橡皮擦上的代码怎么写得合适?(保留撤消/重做) 提前多谢!

  • 我已经在谷歌上搜索了这个问题,并提出了各种解决方案。 但是,没有一个对我有效。 我在一个应用程序中有一个绘图画布。 画布的背景被设置为活动中的png图像,该活动使用自定义视图(drawView); 在DrawingView类(drawview是实例)中,我将绘制的路径存储在一个PathPaints集合中,该集合有3个属性(路径、使用的油漆以及如果是橡皮擦); 我已经尝试在drawpath上设置油漆

  • 绘画工具和绘画描边 笔刷工具 、仿制图章工具 和橡皮擦工具 都是绘画工具。您可以在“图层”面板中使用各个绘画工具将绘画描边应用于图层。每个绘画工具分别应用将修改图层区域的颜色或透明度而不修改图层源的笔刷笔迹。 每个绘画描边都有各自的持续时间条、“描边选项”属性和“变换”属性,您可以在“时间轴”面板中查看和修改这些属性。默认情况下,每个绘画描边均根据创建它的工具命名,并包含一个表示其绘制顺序的数字。

  • 这是我的密码。现在钢笔绘图工作,橡皮擦绘图擦除,但它擦除背景图像。我只想让它擦去钢笔。 如果你能给我提示该怎么做,我将不胜感激。 === ====