【问题标题】:Drawing lines on canvas with IE9 lags使用 IE9 滞后在画布上绘制线条
【发布时间】:2012-04-25 22:04:09
【问题描述】:

我最近尝试使用画布创建一个简单的画家。我使用 mousedown 来捕获起点。在 mousemove 上,我从起点到当前点画了一条线,并用当前点替换了起点。最后我删除了 mouseup 上的事件处理程序。这个解决方案在 Chrome、Firefox 和 safari 上运行良好,但是当我在 IE9 上测试它时,我遇到了一个烦人的错误。我绘制的线条仅在 mouseup 事件之后出现。关于为什么会发生这种情况以及我应该如何解决它的任何想法?

我添加了一个简单的测试页面来演示该问题 http://kfirg.com/rage/main.htm 试着画一条长线,或者一个圆圈或类似的东西。在 chrome 上它可以完美运行,但在 IE9 上它会像疯了一样滞后。

注意事项: 我为这个简单的画家使用了 jQuery 和 jCanvas。我也尝试直接使用canvas api自己实现它,我遇到了同样的问题。

更新 jsFiddle:http://jsfiddle.net/t5QpN/1/

【问题讨论】:

  • 我在网上找到了这个演示 ie.microsoft.com/testdrive/Graphics/CanvasPad/Default.html 看看鼠标演示,它在 IE 中就像一个魅力,但我似乎找不到那个代码和我的代码之间的区别。如果有人能帮助我找出其中的区别,那就太好了。
  • 经过一番玩耍后,我发现如果我像这样清除画布 ctx.fillStyle = "rgba(0,0,0,0.05)"; ctx.fillRect(0, 0, canvas.width, canvas.height);比IE上的性能好很多,谁能解释一下为什么?另一种方法是做 canvas.width = canvas.width; canvas.height = canvas.height;

标签: jquery html internet-explorer canvas jcanvas


【解决方案1】:

实际上,您的错误比 IE 中的要多。根据我的测试,线条是零星的。

I made a jsFiddle of this to test

我没有答案,只有想法。我从来没有用过这样的铅笔画类型的画布应用程序,当鼠标按下时我已经完成了轮询。很明显,如果您查看控制台,您的绘图代码正在 IE 中按预期运行。鼠标移动必须尽可能多地触发。

那么交易可能是什么。我在想两件事之一

  1. IE 太忙于线程中的其他内容,无法在鼠标启动之前绘制画布
  2. (与 1 相关)可能是你画得太频繁了,超载了

如果这两个中的任何一个是正确的,我认为您需要切换到每 X 毫秒轮询一次鼠标的位置。它不会给您带来平滑的线条,但您可以调整 X 直到它看起来不错。

希望这会有所帮助!

【讨论】:

  • 这似乎成功了!但是有一个问题,您使用哪个函数进行池化? setTimeout,setInterval,requestAnimationFrame
  • 我使用了 setTimeout,然后在需要时将其重置。我不确定这是否重要。
  • 很遗憾,我检查了旧版本的 ie 并在 flashcanvas 上运行,而不是在本机 ie 上运行。似乎在 flashcanvas 上它应该像它应该的那样工作,但在常规上它没有:(
【解决方案2】:

我认为你的代码对于 mousemove 事件来说很重:

 var fncMouseMoveHandler = function (e) {
        console.log('Move!', 'e', { x: e.offsetX, y: e.offsetY }, 'prev', prev);
        $main_canvas.drawLine({
            strokeStyle: settings.color,
            strokeWidth: 2,
            strokeCap: "round",
            strokeJoin: "miter",
            x1: prev.x,
            y1: prev.y,
            x2: e.offsetX,
            y2: e.offsetY
        });
        prev = { x: e.offsetX, y: e.offsetY };
    }

您正在使用 API,应用样式并计算不需要的东西。绘图代码应该很简单: 你得到坐标,然后用 :

context.lineTo(x, y);
context.stroke();

您的笔画样式不应在 mousemove 事件中定义,画布会记住这些设置。

Opera 开发中心提供了一个很棒的教程:http://dev.opera.com/articles/view/html5-canvas-painting/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 2013-12-21
    相关资源
    最近更新 更多