鼠标左键向下并在 Chrome 上移动时 Html Canvas 滞后
Posted
技术标签:
【中文标题】鼠标左键向下并在 Chrome 上移动时 Html Canvas 滞后【英文标题】:Html Canvas lag when Left Mouse is down and moving on Chrome 【发布时间】: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;"到画布标签
【参考方案1】:
当您按住鼠标左键并同时移动它时,您就是拖动。
编辑:在某些版本的 Chrome 中,有一个错误(当我发布这个答案时,我有它,现在我没有),导致 drag
事件甚至被触发没有具有draggable
属性的元素。通常,drag
事件只能从 draggable
属性设置为 true
的元素中触发(默认情况下可拖动的图像和锚点除外)。
根据MDN,当drag
事件被触发时,mouse
事件,例如mousemove
,不是,这意味着你的函数没有被调用。
一种可能的解决方案是对drag
和mousemove
事件使用相同的函数:
function mouseMove(e)
//do your things here
...
document.addEventListener('mousemove', mouseMove);
document.addEventListener('drag', mouseMove);
注意:如果您对两个事件使用相同的函数,您应该知道您在函数中使用了事件的哪些属性,因为 @987654333 之间的区别@ 和 mousemove
事件。这两个事件不包含完全相同的属性,并且它们的某些属性的行为可能不同。
【讨论】:
【参考方案2】:你考虑过节流吗?
查看https://blog.toggl.com/2013/02/increasing-perceived-performance-with-_throttle/
【讨论】:
【参考方案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
...
【讨论】:
尝试添加一些描述。以上是关于鼠标左键向下并在 Chrome 上移动时 Html Canvas 滞后的主要内容,如果未能解决你的问题,请参考以下文章