Clear Canvas Rect(但保留背景)

fes*_*fes 13 html drawing canvas

我正在尝试动画一个圆圈,只是水平移动它,工作正常.然而,当圆圈移动时,我必须对该圆圈执行clearRect,以便在水平方向上重新绘制它.当我做一个clearRect时,它也会使背景周围有白框,这样它就会在圆圈移动的方向上成为一条白色的水平线.

  1. 有没有办法在没有clearRect的情况下清除圆圈?
  2. 如果我必须在clearRect之后继续重新绘制背景,那么当theres说10个圆圈在那个区域移动时,画布将会闪烁.

还有其他解决方法吗?

    function drawcircle() {
        clear();    

        context.beginPath();
        context.arc(X, Y, R, 0, 2*Math.PI, false);                  
        context.moveTo(X,Y);            
        context.lineWidth = 0.3;
        context.strokeStyle = "#999999"; 
        context.stroke();

        if (X > 200)
        {
            clearTimeout(t); //stop
        }
        else
        {
            //move in x dir
            X += dX;
            t = setTimeout(drawcircle, 50);
        }
    }

    function clear() {
        context.clearRect(X-R, Y-R, 2*R, 2*R);
    }
Run Code Online (Sandbox Code Playgroud)

Phr*_*ogz 26

基础知识:HTML5 Canvas作为非保留的绘图模式图形API

首先,让我们讨论HTML5 Canvas的工作方式.就像现实世界的帆布快干油漆,当你stroke()fill()drawImage()到画布油漆变成画布的一部分.尽管您画了一个"圆圈"并且看到它,但圆圈的像素完全取代了背景(或者在圆形边缘处消除锯齿,混合并永远改变它们).如果你让他把一幅画中的一个人"移动"到右边,Monet会怎么说?你无法移动圆圈,你无法擦除圆圈,你无法检测圆圈的鼠标悬停...因为没有圆圈,只有一个2D像素阵列.

一些选项

  1. 如果您的背景是完全静态的,请canvas通过CSS 将其设置为元素的背景图像.这将显示并覆盖您绘制的内容,但在清除画布时不会被清除.

  2. 如果你不能做到这一点,那么你也可以清除整个画布并在每一帧重新绘制它.在我的测试中,除非重绘画布非常昂贵,否则清除和重绘画布的一部分所需的工作是不值得的.

    例如,请参阅此测试:http:
    //phrogz.net/tmp/image_move_sprites_canvas.html在Safari v5.0.4中,如果每帧清除并重新绘制整个画布一次,则会看到59.4fps,如果使用20,则会看到56.8fps clearRect()电话和20个drawImage()电话每个帧只重新绘制背景的脏污部分.在这种情况下,聪明并跟踪小脏区域的速度较慢.

  3. 作为另一种选择,使用保留绘图图形系统,如SVG或HTML.有了这些,每个元素都是独立维护的.你可以改变物品的位置,它会神奇地移动; 浏览器可以以最有效的方式智能地绘制更新.

    您可以通过在同一HTML页面中创建和分层多个画布(使用CSS绝对定位和z-index)来保留自定义画布绘制的强大功能.正如在这个性能测试中看到的那样,通过CSS移动20个精灵比在一个画布上尝试自己动作要快得多.

闪烁?

你写了:

如果我必须在clearRect之后继续重新绘制背景,那么当theres说10个圆圈在那个区域移动时,画布将会闪烁.

这从来就不是我的经历.您能否提供一个小例子来说明您声称会出现这种"闪烁"问题(请指明您遇到的操作系统,浏览器和版本)?以下是着名浏览器开发人员的两条评论,指出Firefox和Safari都不应该显示任何闪烁.