在javascript中平滑地预测鼠标光标的位置

时间:2014-09-24 01:26:03

标签: javascript html5 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;
}())

我做错了什么?

以上是上述内容:http://jsfiddle.net/p8Lr224p/

谢谢!

1 个答案:

答案 0 :(得分:4)

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

&#13;
&#13;
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);
}
&#13;
body{ background-color: ivory; }
#canvas{border:1px solid red;}
&#13;
<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>
&#13;
&#13;
&#13; ,