【问题标题】:HTML5 Canvas erasing a drawn object?HTML5 Canvas 擦除绘制的对象?
【发布时间】:2012-06-08 03:54:02
【问题描述】:

我无法为我绘制的对象实现“擦除”功能。我像这样绘制对象:

function draw_obj1(context) {
    context.lineTo(...)
    context.arc(...)
    //etc
}

这些是在我为画布拥有的图像背景之上绘制的(通过 context.createPattern、fillStyle = pattern 等)。

所以说上面的函数使用各种 lineTo 调用来追踪一个三角形。现在要“擦除”或“撤消”此绘图,我的一个计划是在其上重新绘制同一对象的“异或”版本,以撤消它。我通过 context.globalCompositeOperation 执行此操作(请参阅:https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html)。

这几乎可以正常工作,只是最终结果在我的浅蓝色背景下并非完全空白。它是一个浅灰色的三角形,而不是原来的黑线三角形。

编辑 - 忘了提及我尝试过的另一个想法。在我需要离开的区域上执行“clearRect”会在我的浅蓝色背景中产生一个白洞,这不好。

那么我应该如何撤消我绘制的线条/弧线?

干杯

【问题讨论】:

    标签: javascript jquery html


    【解决方案1】:

    仅使用您的 Canvas 内容是不可能的。 画布元素的反应就像一个真正的画布:因为事物被绘制,它们被合并并绑定到整个图片。

    这是因为在大多数图形 API 中,canvas 只是一个字节数组。 计算机无法单独知道如何识别和区分构成当前帧的对象。

    最好的方法是实现“场景图”之类的东西,即图树。 然后,您可以将对象附加到此图树并构建自己的算法以在画布上绘制每个对象。

    您可以拥有一个历史数据结构,以允许撤消/重做从场景图中添加/删除对象并在较小的时间片(纳毫秒)内重绘每个对象。

    这是对您的问题的整体看法。希望您知道如何以编程方式处理图表。

    更多信息:How to add undo-functionality to HTML5 Canvas?

    这里:http://www.abidibo.net/blog/2011/10/12/development-undo-and-redo-functionality-canvas/

    【讨论】:

    • 开枪,看来我得在这里学习一种新的网络技术了。感谢您的回复
    • 这是二维图形编程中普遍存在的东西。不是技术问题,更像是简单性问题:图形 API 为您提供高级别的可能性,您可以决定如何使用它。 2D 图形需要快速,并且允许开发人员深入研究,我们可以拥有最佳的动画循环、响应和这类东西。
    【解决方案2】:

    您应该改为使用“绘制队列”。也就是说,将在画布上完成的操作序列放入一个数组中。这种方法的好处是你所做的每一个动作都会在一个数组中被跟踪。不利的一面是必须重新绘制整个画布以适应变化。

    Canvas 动画框架大部分时间都是这样做的。

    一个简单的表示是这样的:

    var drawingQueue = [
        {
            shape : 'rectangle',
            fill : 'red'
        },
        {
            shape : 'circle',
            fill : 'blue'
        },
        {
            shape : 'arc',
            fill : 'green'
        }
    ];
    

    drawingQueue 是一个命令/属性数组,用于指示在画布中绘制什么的命令。在本例中,此队列将绘制一个红色矩形、蓝色圆圈和绿色弧线。

    例如,我想删除圆圈,我只需将其从数组中删除并重绘队列中的所有内容 - 现在没有圆圈。假设我们进行撤消,我们将使用数组pop() 删除最后一项,然后重新绘制画布 - 现在没有弧线。

    但为了加快开发速度,我建议改用框架。他们将为您的形状提供内部跟踪系统,以便在画布中轻松添加和删除“元素”。首选是 KineticJS 和 FabricJS。

    【讨论】:

      【解决方案3】:
      prev_comp = context.globalCompositeOperation
      context.globalCompositeOperation = 'destination-out'
      context.strokeStyle = "rgba(255, 255, 255, 1)"
      
      /* Draw some "eraser" lines/shapes ..*/
      
      context.globalCompositeOperation = prev_comp
      

      【讨论】:

        猜你喜欢
        • 2019-11-04
        • 1970-01-01
        • 1970-01-01
        • 2013-02-15
        • 2014-11-12
        • 2016-09-14
        • 1970-01-01
        • 2017-12-21
        • 2011-08-28
        相关资源
        最近更新 更多