我想在鼠标光标周围的画布上绘制一个矩形,该矩形平滑地跟随光标。不幸的是,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/
谢谢!
答案 0 :(得分:4)
鼠标指针总是比绘图更快,所以最好的选择不是让用户的眼睛有理由感知延迟。因此,在用户绘图时关闭鼠标光标。在鼠标位置绘制一个矩形,以便在视觉上充当鼠标光标。
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;