在javascript中顺利预测鼠标光标的位置

Joe*_*oel 2 html javascript canvas

我想在画布上围绕鼠标光标绘制一个矩形,该矩形平滑地跟随光标。不幸的是, mousemoved 事件触发的速度不够快,并且绘图不断落后于它。所以我假设我需要预测鼠标在哪里,并在该点绘制矩形。我正在尝试编写一个简单的库来抽象它,但它并没有像我想要的那样紧密地跟踪快速移动(事实上,快速移动是令人紧张的)。对于缓慢的移动,它的跟踪效果相当好,并且比使用原始鼠标坐标的简单解决方案更好。

基本思想是 mousemove 用鼠标的当前位置更新几个外部变量。requestAnimationFrame 循环(Watcher 函数)随着时间的推移跟踪这些变量及其先前的值,以计算鼠标移动的速度(在 x 轴上)。当调用 PredictX 函数时,它返回当前的 x 位置,加上 x 的最后变化乘以速度。不同的 reqeustAnimationFrame 循环根据预测的 x 值移动矩形。

var MouseLerp = (function () {
    var MOUSELERP = {};
    var current_x = 0;
    var last_x = 0;
    var dX = 0;
    var last_time = 0;
    var x_speed = 0;

    var FPS = 60;

    function Watcher(time) {
        var dT = time - last_time
        if (dT > (1000 / FPS)) {
            dX = last_x - current_x;
            last_x = current_x;
            x_speed = dX / dT

            last_time = time;
        }

        requestAnimationFrame(Watcher);
    }

    MOUSELERP.PredictX = function () {
        return Math.floor((dX * x_speed) + current_x);
    }

    MOUSELERP.Test = function () {
        var target_element = $(".container")
        target_element.append('<canvas width="500" height="500" id="basecanvas"></canvas>');
        var base_ctx = document.getElementById("basecanvas").getContext("2d");

        var offset = target_element.offset()
        var offset_x = offset.left;
        var offset_y = offset.top;

        var WIDTH = $(window).width();
        var HEIGHT = $(window).height();

        var FPS = 60;

        var t1 = 0;

        function updateRect(time) {

            var dT = time - t1
            if (dT > (1000 / FPS)) {
                base_ctx.clearRect(0, 0, WIDTH, HEIGHT)
                base_ctx.beginPath();
                base_ctx.strokeStyle = "#FF0000";
                base_ctx.lineWidth = 2;

                base_ctx.rect(MOUSELERP.PredictX(), 100, 100, 100)
                base_ctx.stroke();
                t1 = time;
            }
            requestAnimationFrame(updateRect)
        }
        updateRect();

        $(target_element).mousemove(function (event) {
            current_x = event.pageX - offset_x;
        });

        requestAnimationFrame(Watcher);
    }
    MOUSELERP.Test()
    return MOUSELERP;
}())
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

这是上面的 jsfiddle: http: //jsfiddle.net/p8Lr224p/

谢谢!

mar*_*rkE 5

鼠标指针总是比绘图更快,因此最好的选择是不要让用户的眼睛有理由感知延迟。因此,在用户绘图时关闭鼠标光标。在鼠标位置绘制一个矩形,在视觉上充当鼠标光标。

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;

var mouseX=0;
var mouseY=0;

canvas.style.cursor="none";

$("#canvas").mousemove(function(e){handleMouseMove(e);});

function handleMouseMove(e){
  ctx.clearRect(mouseX-1,mouseY-1,9,9);
  mouseX=e.clientX-offsetX;
  mouseY=e.clientY-offsetY;
  ctx.fillRect(mouseX,mouseY,8,8);
}
Run Code Online (Sandbox Code Playgroud)
body{ background-color: ivory; }
#canvas{border:1px solid red;}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Less 'lagging' when mouse is invisible & canvas draws cursor.</h4>
<canvas id="canvas" width=300 height=300></canvas>
Run Code Online (Sandbox Code Playgroud)
,

  • 老鼠,我真的希望有一种聪明的方法来预测老鼠的位置。 (2认同)