【问题标题】:Html Canvas lag when Left Mouse is down and moving on Chrome鼠标左键向下并在 Chrome 上移动时 Html Canvas 滞后
【发布时间】:2015-12-09 10:05:51
【问题描述】:

我已经创建了一个画布,并在其中添加了鼠标事件:

canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
canvas.width = screenWidth;
canvas.height = screenHeight;

... 

// CALLED AT START:
function setup() {
    // Mouse movement:
    document.onmousemove = function(e) {
        e.preventDefault();
        target.x = e.pageX;
        target.y = e.pageY;
        angle = Math.atan2((target.y - localPlayer.getY()),
            (target.x - localPlayer.getX()));
        // Distance to mouse Check:
        var dist = Math.sqrt((localPlayer.getX() - target.x)
            * (localPlayer.getX() - target.x) + (localPlayer.getY() - target.y)
            * (localPlayer.getY() - target.y));
        var speedMult = dist / (canvas.height / 4);
        socket.emit("update", {
            ...
        });
    }
    document.onmousedown = function(e) {
        e.preventDefault();
    }
}

现在的问题是,当我按住唯一的鼠标左键并同时移动鼠标时,我的游戏会滞后很多。简单地移动鼠标不会导致延迟。我已经在 chrome 和 firefox 上对此进行了测试。看来我只能在 chrome 上重新创建问题。使用鼠标中键或右键在游戏中具有相同的行为并且不会导致延迟。只有在使用鼠标左键时才会导致延迟。

我四处寻找答案,发现我应该防止像这样的默认行为:

e.preventDefault();

但这并没有解决问题。我还尝试更新屏幕上代表鼠标位置的数字。并且更新正常。只有游戏本身落后了。是不是在按住左键时永远不会调用 onMouseMoved ?但是为什么用中间和右键调用呢?

问题应该出在我在 move 方法中调用的代码上,因为当我不按住左键时它可以正常工作,并且在 firefox 上也可以正常工作。一定有其他事情发生。

编辑:我决定在 chrome 上录制,看看发生了什么。结果如下:

真正奇怪的是,当我按下鼠标中键或右键时,游戏会做同样的事情,但一点也不卡顿。你在做什么铬?

编辑:在这里进行测试:www.vertix.io 请注意,似乎并非每个人都能够重现此问题。

感谢您的宝贵时间。

【问题讨论】:

  • 您真的每 0.033 秒分配两个新的事件处理程序吗?为什么?另外,draw() 在哪里
  • 我会使用画布本身来代替文档...
  • 如果你需要帮助,你需要创建一个 MCVE
  • 首先将所有代码移出onmousemove 事件并使用window.requestAnimationFrame 更新您需要的内容。在鼠标移动事件中,只需抓取并存储鼠标坐标,它不应该是您执行应用程序逻辑的地方。还为 Chrome 添加 user-select: none; 样式规则添加“-webkit-”到正文或画布元素以停止拖动选择。我不知道这是否会解决您的问题,因为您没有提供复制问题所需的内容
  • 可能有html解决方案:尝试添加oncontextmenu="return false;"到画布标签

标签: javascript html google-chrome canvas


【解决方案1】:

当您按住鼠标左键并同时移动它时,您就是拖动

编辑:在某些版本的 Chrome 中,有一个错误(当我发布这个答案时,我有它,现在我没有),导致 drag 事件甚至被触发没有具有draggable 属性的元素。通常,drag 事件只能从 draggable 属性设置为 true 的元素中触发(默认情况下可拖动的图像和锚点除外)。

根据MDN,当drag事件被触发时,mouse事件,例如mousemove,不是,这意味着你的函数没有被调用。

一种可能的解决方案是对dragmousemove 事件使用相同的函数:

function mouseMove(e) {
    //do your things here
    ...
}

document.addEventListener('mousemove', mouseMove);

document.addEventListener('drag', mouseMove);

注意:如果您对两个事件使用相同的函数,您应该知道您在函数中使用了事件的哪些属性,因为 @987654333 之间的区别@ 和 mousemove 事件。这两个事件不包含完全相同的属性,并且它们的某些属性的行为可能不同。

【讨论】:

    【解决方案2】:
    【解决方案3】:

    您在文档上有鼠标事件。由于我们看不到您在文档上的内容,因此很难知道这是否是您的问题的原因。

    尝试仅将鼠标事件移动到画布上,因为我认为这是您唯一需要它的地方。如果文档不是游戏的一部分,则没有必要为文档处理事件,如果子元素附加了事件,则文档是列表中的最后一个。他们先走,然后它会冒泡到你的。

    看起来您正在使用某种类型的框架,很有可能另一个鼠标事件侦听器是框架工作的一部分,它可能会因为不阻止默认设置而减慢您的速度。您必须搜索框架以查看它是否具有任何鼠标事件的侦听器。

    并使用addEventListener,而不是直接通过.onmousedown = eventHandler附加事件
    例如canvas.addEventListener("mousedown",eventHandler);

    并将事件侦听器添加到您需要它的元素,而不是文档。

    【讨论】:

      【解决方案4】:
      function mouseMove(e) {
      //do your things here
      ...
       }
      
       document.onmousemove = mouseMove;
      
        document.ondrag = function(e) {
      mouseMove(e);
      //do another things
      ...
      }
      

      【讨论】:

      • 尝试添加一些描述。
      猜你喜欢
      • 2017-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多