画布形状擦除问题

4
我正在canvas中制作涂鸦,但我遇到了一个问题。当我使用背景色覆盖对象以擦除它时,我会留下原始形状的轮廓。以下是我使用的代码。是的,我没有使用clear rect因为圆可以重叠。 enter image description here
    function erase(eraseColor) {
    ctx.fillStyle = ctx.strokeStyle = eraseColor || "#FFFFFF";
    drawCircle();
    ctx.fillStyle = ctx.strokeStyle = fillColor;
}

function drawCircle() {
    ctx.beginPath();
    ctx.arc(x, y, rad, 0, Math.PI * 2, true);
    ctx.closePath();
    ctx.fill();
}

这可能是由于反锯齿造成的。将清晰的圆稍微放大一点(比如101%)以弥补它。 - Aaron Yodaiken
1
你认为当圆形重叠时,这种方法会有效吗?我不太确定。为什么不坚持使用常规的基于帧的动画呢? - Ray Toal
1个回答

2
我认为这是由于反锯齿效果造成的。这种效果不应该出现在不需要反锯齿的形状上(比如矩形)。将擦除圆圈画大几个像素(一个就够了)。
如果有人问起:你不能关闭画布的反锯齿效果
正如Ray建议的那样,你应该考虑使用基于帧的动画,并通过使用脏矩形进行优化。
为此,只需标记一个矩形为脏矩形,如果其中任何像素发生变化(例如由于动画),则清除画布上的该矩形(clearRect),并将其设置为裁剪矩形(clip)。然后,迭代显示在画布上的所有元素,并检查它们是否与脏矩形重叠。如果是,则绘制该元素;否则,跳到下一个元素。

2
+1 支持这个想法,但是如果有很多移动的圆圈可能会重叠在一起,那么通过绘制背景来擦除的圆圈是行不通的。动画应该使用帧来完成(或者如果必要的话可以使用脏矩形进行优化)。 - Ray Toal
基于帧的动画会更加昂贵,擦除所有像素再重新绘制比仅仅覆盖绘制要低效得多...除非我漏掉了什么。 - samccone
你可以使用脏矩形来最小化需要重新绘制的数量。只需将一个矩形标记为“脏”,清除它并将其设置为剪辑矩形。然后检查每个元素是否与该矩形重叠。如果是,则绘制它。否则,检查下一个元素。对于每一帧都要重复这个过程。 - Daniel Baulig
1
凭借在画布中渲染动画的丰富经验,我认为这可能是过早优化的情况。首先清除整个画布并重新绘制整个帧。如果遇到性能问题,则开始寻找优化方法。在这种情况下,我认为检测脏区域的重叠成本比清除和重新绘制整个画布更高。 - Prestaul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接