【问题标题】:Flickering occurs when mouse moves over the object- Javascript当鼠标移动到对象上时会发生闪烁 - Javascript
【发布时间】:2014-04-14 18:28:11
【问题描述】:

我正在画布上绘制一些对象(例如矩形)。它也有背景图片。

但是当我使用鼠标事件绘制矩形时,屏幕会闪烁很多。 当我改变对象的位置时,如何停止鼠标移动/鼠标向下的闪烁,以便一次又一次地重新绘制画布。 我们可以渲染它一段时间或任何其他解决方案吗?

我听说在 java 和 C# 中有一些函数为“Redraw = false”,但我的代码是在 JavaScript 中。

http://jsfiddle.net/G6tLn/7/`function myMove(e) { 如果(isDrag){ getMouse(e);

        mySel.x = mx - offsetx;
        mySel.y = my - offsety;

        // something is changing position so we better invalidate the canvas!
        invalidate();
    } else if (isResizeDrag) {
        // time ro resize!
        var oldx = mySel.x;
        var oldy = mySel.y;

        // 0  1  2
        // 3     4
        // 5  6  7
        switch (expectResize) {
            case 0:
                mySel.x = mx;
                mySel.y = my;
                mySel.w += oldx - mx;
                mySel.h += oldy - my;
                break;
            case 1:
                mySel.y = my;
                mySel.h += oldy - my;
                break;
            case 2:
                mySel.y = my;
                mySel.w = mx - oldx;
                mySel.h += oldy - my;
                break;
            case 3:
                mySel.x = mx;
                mySel.w += oldx - mx;
                break;
            case 4:
                mySel.w = mx - oldx;
                break;
            case 5:
                mySel.x = mx;
                mySel.w += oldx - mx;
                mySel.h = my - oldy;
                break;
            case 6:
                mySel.h = my - oldy;
                break;
            case 7:
                mySel.w = mx - oldx;
                mySel.h = my - oldy;
                break;
        }

        invalidate();
    }

    getMouse(e);
    // if there's a selection see if we grabbed one of the selection handles
    if (mySel !== null && !isResizeDrag) {
        for (var i = 0; i < 8; i++) {
            // 0  1  2
            // 3     4
            // 5  6  7

            var cur = selectionHandles[i];

            // we dont need to use the ghost context because
            // selection handles will always be rectangles
            if (mx >= cur.x && mx <= cur.x + mySelBoxSize &&
                    my >= cur.y && my <= cur.y + mySelBoxSize) {
                // we found one!
                expectResize = i;
                invalidate();

                switch (i) {
                    case 0:
                        this.style.cursor = 'nw-resize';
                        break;
                    case 1:
                        this.style.cursor = 'n-resize';
                        break;
                    case 2:
                        this.style.cursor = 'ne-resize';
                        break;
                    case 3:
                        this.style.cursor = 'w-resize';
                        break;
                    case 4:
                        this.style.cursor = 'e-resize';
                        break;
                    case 5:
                        this.style.cursor = 'sw-resize';
                        break;
                    case 6:
                        this.style.cursor = 's-resize';
                        break;
                    case 7:
                        this.style.cursor = 'se-resize';
                        break;
                }
                return;
            }

        }
        // not over a selection box, return to normal
        isResizeDrag = false;
        expectResize = -1;
        this.style.cursor = 'auto';
    }

}

`

【问题讨论】:

  • 编辑了问题。请帮助停止由于鼠标移动而导致的闪烁
  • 我试过你的小提琴,它没有闪烁。我正在使用 Chrome。
  • 在小提琴中它没有闪烁,但是当我将它添加到我的应用程序时。当我改变矩形的位置时它会闪烁。

标签: javascript jquery canvas


【解决方案1】:

500 多条线...需要诊断的内容很多!

快速扫描该代码后的一些想法:

  1. 创建矩形或调整其大小时,使用覆盖在结果画布顶部的单独编辑画布。这样,唯一被重绘的是你正在处理的矩形——不是每个以前的矩形。创建/调整大小完成后,将覆盖画布绘制到显示画布。

  2. 使用 requestAnimationFrame 代替 setInterval 进行定时重绘。 R.A.F 将其重绘与显示器的刷新周期同步,以获得更好的性能。

  3. 不要使用单独的大小调整器。管理单独的大小调整器需要大量计算时间。而是做 o/s 做的事情,让用户拖动调整形状边框的大小。

【讨论】:

    【解决方案2】:

    您可以考虑设置断点并仔细查看代码中实际发生的情况。

    闪烁意味着清除画布清除和重绘不会同步发生。发生这种情况的原因可能有很多。

    一种方法是您清除画布或将其作为事件处理程序的一部分调整大小,留下空白画布,直到您的绘制循环发生并重绘所有内容。

    如果某些内容与事件同步更新非常重要,例如鼠标移动或滚动,请将画布重新绘制为事件处理程序的一部分。

    window.addEventListener("mousemove", function(event){
        doSomething();
        redrawOnce();
    },false);
    

    但请注意不要意外启动多个循环。确保您的绘图函数不会调用自身。就像在这个例子中一样:

    function redrawOnce(){
       //That's not how to redraw once
       requestAnimationFrame(redrawOnce);
    }
    

    而是将抽奖与循环分开

    function loop(){
        requestAnimationFrame(loop);
        redrawOnce();
    }
    

    由于重绘整个画布以更新其中一小部分的更改是颓废的,您也可以考虑仅重绘由事件更改的部分,如果这是您正在做的一个选项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 2016-02-18
      • 1970-01-01
      相关资源
      最近更新 更多