【问题标题】:javascript event too slowjavascript事件太慢
【发布时间】:2014-08-27 02:48:51
【问题描述】:

下面的html5例子有什么办法改进,或者是浏览器 只是为了减慢处理鼠标事件? 它是一个网格,在您将鼠标移动到的点上,您会看到一个红色矩形。 但是这个矩形是一种滞后于鼠标的,所以移动到它的位置要慢。 (如果鼠标移动得很快)

http://jsfiddle.net/191rmac8/

代码如下:

<body>
    <canvas id="canvas" width="400" height="400">error or not supported.</canvas>
    <script>
        var lineSize = 10;
        var rasterSize = 5;
        var bx = 0;
        var by = 0;

        g2d = document.getElementById("canvas").getContext("2d");
        g2d.setFillColor("rgb(10, 10, 10)");
        g2d.fillRect(0, 0, g2d.canvas.width, g2d.canvas.height);
        g2d.setStrokeColor("rgb(0, 0, 255)");
        g2d.setLineWidth(lineSize);

        function repaint(){
            g2d.clearRect(0, 0, g2d.canvas.width, g2d.canvas.height);
            g2d.beginPath();
            for(i = 0; i < rasterSize + 1; i++){
                g2d.moveTo(0, (lineSize / 2) + i * (g2d.canvas.height - lineSize) / (rasterSize));
                g2d.lineTo(g2d.canvas.width, (lineSize / 2) + i * (g2d.canvas.height - lineSize) / (rasterSize)); 
                g2d.moveTo((lineSize / 2) + i * (g2d.canvas.width - lineSize) / (rasterSize), 0);
                g2d.lineTo((lineSize / 2) + i * (g2d.canvas.width - lineSize) / (rasterSize), g2d.canvas.height);
            }
            g2d.stroke();
            g2d.setFillColor("red");
            g2d.fillRect(bx - 5, by - 5, 11, 11);
        }
        repaint();

        g2d.canvas.addEventListener("mousemove", function(e){
            bx = e.offsetX;
            by = e.offsetY;
            repaint();
        });
    </script>
</body>

body {
    margin: 0;
    width: 100%;
    height: 100%;
    display: block;
    background: black;
}
canvas {
    margin: auto;
    margin-top: 50px;
    display: block;
}

【问题讨论】:

  • 鼠标的绘制速度总是比浏览器中的任何东西都快,所以无论你做什么都会有延迟
  • 处理不当的不是鼠标事件,而是mousemove 是“在很短的时间内调用了很多”类型的事件之一。这意味着 repaint 每秒被调用一个 lot,因此您需要优化该函数才能看到性能提升。
  • 你总是可以把 cursor: none 放在画布 css 中来隐藏鼠标,它会减少延迟的感知
  • 如果不是检查mousemove 并在它移动时重新绘制,您只需设置一个超时循环并每 100 毫秒或 1 毫秒或任何看起来不错的方式重新绘制鼠标?

标签: javascript html optimization canvas


【解决方案1】:

您可以将鼠标事件与绘图分开以提高性能。

  • 创建一个数组来保存鼠标点
  • 在 mousemove 中,将当前鼠标位置推入数组中。
  • 根据您的设计,您可以使用 Aboca 的想法来限制点的捕获率。
  • 使用 requestAnimationFrame 创建一个循环。
  • 在循环中,将自上次执行循环以来的所有点绘制为 1 条路径。

好处是:

  • requestAnimationFrame 在绘图方面非常高效。
  • 您正在通过一批点绘制多段线,而不是一次绘制一个点。
  • 更改上下文状态有点昂贵,这让您只能更改一次状态。

【讨论】:

    【解决方案2】:

    您可以像我在这里所做的那样限制重绘的速率:

    http://jsfiddle.net/sh6o91g4/1/

    调整你认为合适的,因为它会提高性能,但它也会降低渲染的质量(跳帧有它的缺点)

                var now = new Date().getTime();
                if(now - time > 10){
                    time = now;
                    bx = e.offsetX;
                    by = e.offsetY;
                    repaint();
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-29
      • 1970-01-01
      • 2014-11-12
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多