有没有办法加速mousemove事件?

IT技术 javascript dom mousemove
2021-03-08 01:27:07

我为这个网站写了一个小绘图脚本(画布):http : //scri.ch/

当您单击文档时,每个mousemove事件基本上都会执行以下操作:
- 获取坐标。
-context.lineTo()在这一点和前一点之间
-context.stroke()线

如您所见,如果您非常快地移动光标,则事件触发不够(取决于您的 CPU / 浏览器 / 等),并且会跟踪一条直线。

在伪代码中:

window.addEventListener('mousemove', function(e){
  myContext.lineTo(e.pageX, e.pageY);
  myContext.stroke();
}, false);

这是一个已知问题,解决方案很好,但我想对其进行优化。

因此,不是stroke()每次触发 mousemove 事件时,我都会将新坐标放入数组队列中,并使用计时器定期绘制/清空它。

在伪代码中:

var coordsQueue = [];

window.addEventListener('mousemove', function(e){
  coordsQueue.push([e.pageX, e.pageY]);
}, false);

function drawLoop(){
  window.setTimeout(function(){
    var coords;
    while (coords = coordsQueue.shift()) {
      myContext.lineTo(coords[0], coords[1]);
    }
    myContext.stroke();
    drawLoop();
  }, 1000); // For testing purposes
}

但它并没有改善线路。所以我试着只在mousemove. 相同的结果:点之间的空间太大。

这让我意识到第一个代码块足够高效,只是mousemove事件触发太慢了。

所以,在我花了一些时间实现了一个无用的优化之后,轮到你了:有没有办法优化mousemoveDOM 脚本中触发速度?

是否可以随时“请求”鼠标位置?

感谢您的建议!

2个回答

如果你想提高举报频率,恐怕你就倒霉了。老鼠每秒只向操作系统报告n它们的位置,我认为n通常小于 100。(如果有人能用实际规格确认这一点,请随时添加它们!)

因此,为了获得平滑的线条,您必须想出某种插值方案。有很多关于这个主题的文献。我推荐单调三次插值,因为它是局部的、易于实现且非常稳定(没有过冲)。

然后,一旦计算了样条曲线,就可以用足够短的线段对其进行近似处理,使其看起来平滑,或者您可以全力以赴编写自己的Bresenham算法来绘制它。

如果对于一个简单的绘图应用程序来说这一切都是值得的……当然,这由您来决定。

普通鼠标每秒发送大约 100-150 次更新。我的罗技 G3 发送 500。游戏鼠标可能发送更多。
2021-05-01 01:27:07
SVG Edit ( code.google.com/p/svg-edit ) 是开源的,并且显然会进行一些平滑计算,因此您可能不需要重新创建轮子。
2021-05-02 01:27:07
感谢您的链接,但是是的,这对于这个应用程序来说有点矫枉过正。我认为问题不是来自操作系统(Photoshop 快很多),而是来自浏览器,它们自愿限制 mousemove 事件触发,当然是因为很多脚本直接依赖它来执行密集任务。但是为什么不允许作者请求鼠标位置呢?window.getMousePosition()什么?
2021-05-13 01:27:07

很酷的站点,不幸的是没有办法用 JavaScript 请求鼠标的当前位置,你拥有的唯一钩子是你已经在使用的事件。如果您必须拥有更多控制权,我会考虑使用 flash,您可以在其中更改帧速率并请求鼠标位置。

trace("Mouse X: " + _xmouse);
trace("Mouse Y: " + _ymouse);
谢谢,但我不会使用 Flash,我是开放标准的传播者!;-)
2021-04-23 01:27:07
比受 Flash 摆布要好得多。
2021-04-28 01:27:07
那么你就会受到这些标准的支配:-)
2021-05-06 01:27:07