准确计算鼠标速度

Calculating mouse velocity with accuracy

本文关键字:速度 鼠标 计算      更新时间:2023-09-26

我制作了一个小脚本,用于输出鼠标移动的速度。我遇到的问题是,偶尔脚本会输出数字中不准确的数字,并将整个数字丢弃。此外,当用户释放鼠标按钮时,脚本并不总是终止。为了解决第一个问题,我认为我可能会将值放入一个数组中,然后确定异常值,但我希望这里有人能告诉我我在做一些愚蠢的事情,有一种方法可以修复我的代码,使其更高效。

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/

因为这不是鼠标的速度。您当前计算的是鼠标在x方向上移动的距离。这被称为距离

您遇到的不准确可能既源于忽略y方向,也源于setTimeout的不准确——使用Date时间戳。

此外,您正在构建mousemove处理程序的级联(这不仅不正确,而且效率很差)。在每个事件上(通常都是这样!),您要等待0.1s,然后添加一个新的侦听器,该侦听器将在每个事件中输出鼠标自第一个事件以来移动的距离。另一个问题是,当按下鼠标时,您正在调用值为0mouse_coors函数,但鼠标几乎不会在那里。

更好:全局存储鼠标的当前坐标。每次更新它们时,计算差值,然后除以上次更新后经过的时间。然后记录速度。

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);
        });
    });
});

更新的fiddle