2013-07-07 57 views
4

我做了一个小脚本,用于输出鼠标移动的速度。我遇到的问题是,偶尔脚本会输出数字中不准确的数字,并将整个事件抛出。而且,当用户释放鼠标按钮时,脚本并不总是终止。为了解决第一个问题,我假设我可以将值放入一个数组,然后确定异常值,但是我希望这里有人能够告诉我我正在做一些愚蠢的事情,并且有一种方法可以修复我的代码它更有效率。精确计算鼠标速度

JS:

var test_obj = { 
    mouse_coors: function(x2) { 

     $(document).on("mousemove", function(e) { 
      var x = e.clientX, 
      velocity = Math.abs(x-x2); 

      console.log(velocity); 
      $(document).off("mousemove"); 

      setTimeout(function() { 
       x2 = e.clientX; 
       test_obj.mouse_coors(x2); 
      }, 100); 
     }); 

     $(document).on("mouseup", function() { 
      $(document).off("mouseup").off("mousemove"); 
     }); 
    }, 
}; 


$(document).ready(function() { 

    $('#testbox').on("mousedown", function() { 
     test_obj.mouse_coors(0); 
    }); 

}); 

HTML:

的jsfiddle:http://jsfiddle.net/mkb2t/

回答

12

很简单,因为这不是鼠标的速度。你目前正在计算的是鼠标在x方向移动的距离。这就是所谓的距离

您遇到的不准确可能源于忽略y方向和setTimeout的不准确性 - 使用Date时间戳。

另外,您正在构建一个mousemove处理程序的级联(这不仅不正确,而且效率不佳)。在每一个事件(而且他们经常!)你等待0.1秒,然后添加一个新的侦听器,将从每个事件输出,从第一个事件后鼠标移动了多远。另一个问题是,当按下鼠标时,您调用mouse_coors函数的值为0,但鼠标几乎不会在那里。

更好:全局存储鼠标的当前坐标。每当您更新它们时,计算差异并将其除以自上次更新以来的时间。然后记录速度。

function makeVelocityCalculator(e_init, callback) { 
    var x = e_init.clientX, 
     y = e_init.clientY, 
     t = Date.now(); 
    return function(e) { 
     var new_x = e.clientX, 
      new_y = e.clientY, 
      new_t = Date.now(); 
     var x_dist = new_x - x, 
      y_dist = new_y - y, 
      interval = new_t - t; 
     var velocity = Math.sqrt(x_dist*x_dist+y_dist*y_dist)/interval; 
     callback(velocity); 
     // update values: 
     x = new_x; 
     y = new_y; 
     t = new_t; 
    }; 
} 
$(document).ready(function() { 
    $('#testbox').on("mousedown", function(e) { 
     var log = makeVelocityCalculator(e, function(v) { 
      console.log(v+"pixel/ms"); 
     }); 
     $(document).on("mousemove", log).one("mouseup", function(){ 
      $(document).off("mousemove", log); 
     }); 
    }); 
}); 

updated fiddle

+0

我没有试图让y方向。也许速度是一个用词不当,因为我不关心方向,只是随着时间的推移水平距离。谢谢! –

+2

@tomc:好的,但你仍然忘了时间......我认为我的脚本很容易适应只有水平速度。 – Bergi

+0

我认为超时会占用时间,因为它会在收集坐标之间产生暂停,但您的确看起来更准确! –