16

我为这个网站写了一个小绘图脚本(画布):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 脚本中的触发速度?

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

感谢您的建议!

4

2 回答 2

21

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

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

然后,一旦你计算了样条,你可以用足够短的线段来近似它,使它看起来很平滑,或者你可以全力以赴,编写自己的Bresenham算法来绘制它。

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

于 2011-03-16T18:25:24.453 回答
0

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

trace("Mouse X: " + _xmouse);
trace("Mouse Y: " + _ymouse);
于 2011-04-02T00:28:27.863 回答