我想创建类似于旧鼠标轨道的效果,其中div被延迟但跟在光标之后。
通过使用set interval将动画触发到光标坐标,我已经相当接近了。
$("body").mousemove(function (e) {
if (enableHandler) {
handleMouseMove(e);
enableHandler = false;
}
});
timer = window.setInterval(function(){
enableHandler = true;
}, 250);
function handleMouseMove(e) {
var x = e.pageX,
y = e.pageY;
$("#cube").animate({
left: x,
top: y
}, 200);
}
现在仍然存在两个问题:
追逐' div非常跳跃(因为需要使用设置间隔)
如果在触发动画之前鼠标移动停止,div将保留在远离光标的位置。
答案 0 :(得分:4)
删除SetInterval并添加$(“#cube”)。stop();停止基于旧(x,y)的旧动画,这样你就可以开始一个新的“更快”的动画。
$(document).ready(function() {
$("body").mousemove(function (e) {
$("#cube").stop();
handleMouseMove(e);
});
function handleMouseMove(event) {
var x = event.pageX,
y = event.pageY;
$("#cube").animate({
left: x,
top: y
}, 50);
}
});
答案 1 :(得分:4)
我的做法略有不同。而不是使用setInterval
(或甚至setTimeout
) - 我只是让动画需要x毫秒才能完成。动画越长,下面的div似乎就越不敏感。
我注意到的唯一问题是,如果鼠标移动很多,它会被备份。
$(document).ready(function () {
$("body").mousemove(function (e) {
handleMouseMove(e);
});
function handleMouseMove(event) {
var x = event.pageX;
var y = event.pageY;
$("#cube").animate({
left: x,
top: y
}, 1);
}
});
答案 2 :(得分:1)
这是一个可能会模拟鼠标轨迹的解决方案,因为它只记住最后100个位置并丢弃旧的那些设置鼠标轨迹的长度。
https://jsfiddle.net/acmvhgzm/6/
$(document).ready(function() {
var pos = new Array();
$("body").mousemove(function (e) {
handleMouseMove(e);
});
timer = window.setInterval(function() {
if (pos.length > 0) {
$('#cube').animate(pos.shift(),15);
}
}, 20);
function handleMouseMove(event) {
var x = event.pageX,
y = event.pageY;
if (pos.length = 100) {
pos.shift();
}
pos.push({'left':x, 'top':y});
}
});
答案 3 :(得分:1)
这里超级晚了,但是我真的不喜欢在这里添加延迟的任何选项,因为它们遵循鼠标的先前位置而不是朝鼠标移动。因此,我对Mike Willis的代码进行了重大修改,以获取此代码-
$(document).ready(function () {
$("body").mousemove(function (e) {
mouseMoveHandler(e);
});
var currentMousePos = { x: -1, y: -1 };
function mouseMoveHandler(event) {
currentMousePos.x = event.pageX;
currentMousePos.y = event.pageY;
}
mouseMover = setInterval(positionUpdate, 15);
function positionUpdate() {
var x_cursor = currentMousePos.x;
var y_cursor = currentMousePos.y;
var position = $("#cube").offset();
var x_box = position.left;
var y_box = position.top;
$("#cube").animate({
left: x_box+0.1*(x_cursor-x_box),
top: y_box+0.1*(y_cursor-y_box)
}, 1, "linear");
}
});
-----------------------------------------------------------------------
body { overflow:hidden; position:absolute; height:100%; width:100%; background:#efefef; }
#cube {
height:18px;
width:18px;
margin-top:-9px;
margin-left:-9px;
background:red;
position:absolute;
top:50%;
left:50%;
}
.circleBase {
border-radius: 50%;
}
.roundCursor {
width: 20px;
height: 20px;
background: red;
border: 0px solid #000;
}
https://jsfiddle.net/rbd1p2s7/3/
每次移动并以固定间隔保存光标位置时,它会以div位置与最新光标位置之间的差值的一小部分更新div位置。由于圆看起来更好,我也将其更改为一个圆。
这里需要担心的是,它经常触发,并且可能会使一台性能较差的机器变慢,降低更新频率会使光标跳得比我想要的还要多,但是在更新频率和跳动之间可能会找到一些中间立场,或使用我不熟悉的动画方法来自动执行动作。
答案 4 :(得分:0)
尝试使用setInterval
,.css()
css
transition
$(document).ready(function () {
var cube = $("#cube");
$("body").mousemove(function (e) {
handleMouseMove(e);
});
function handleMouseMove(event) {
var x = event.pageX,
y = event.pageY;
cube.css({
left: x + cube.width() / 2 + "px",
top: y + cube.height() / 2 + "px"
}).parents("body").mousemove()
}
});

body {
overflow:hidden;
position:absolute;
height:100%;
width:100%;
background:#efefef;
}
#cube {
height:50px;
width:50px;
margin-top:-25px;
margin-left:-25px;
background:red;
position:absolute;
top:50%;
left:50%;
transition:all 1.5s ease-in-out;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container">
<div id="cube"></div>
</div>
&#13;
答案 5 :(得分:0)
旧的鼠标跟踪功能使用了多个形状像光标的窗口的列表,这些窗口每帧都会更新其位置。基本上,它具有一个“光标”列表,并且列表中下一个“光标”的每一帧都被移动到当前光标位置,从而达到使每个假光标延迟fake cursors - 1
帧来更新其自身位置的效果。 / p>
可以使用requestAnimationFrame
,performance.now
和Event.timeStamp
模拟单个对象的平稳按需延迟运动。想法是将鼠标事件保留在内部列表中,并仅在创建后经过特定时间后使用它们。
function DelayLine(delay, action){
capacity = Math.round(delay / 1000 * 200);
this.ring = new Array(capacity);
this.delay = delay;
this.action = action;
this._s = 0;
this._e = 0;
this._raf = null;
this._af = this._animationFrame.bind(this);
this._capacity = capacity;
}
DelayLine.prototype.put = function(value){
this.ring[this._e++] = value;
if (this._e >= this._capacity) this._e = 0;
if (this._e == this._s) this._get();
cancelAnimationFrame(this._raf);
this._raf = requestAnimationFrame(this._af);
}
DelayLine.prototype._get = function(){
var value = this.ring[this._s++];
if (this._s == this._capacity) this._s = 0;
return value;
}
DelayLine.prototype._peek = function(){
return this.ring[this._s];
}
DelayLine.prototype._animationFrame = function(){
if (this._length > 0){
if (performance.now() - this._peek().timeStamp > this.delay)
this.action(this._get());
this._raf = requestAnimationFrame(this._af);
}
}
Object.defineProperty(DelayLine.prototype, "_length", {
get: function() {
var size = this._e - this._s;
return size >= 0 ? size : size + this._capacity;
}
});
var delayLine = new DelayLine(100, function(e){
pointer.style.left = e.x - pointer.offsetWidth/2 + "px";
pointer.style.top = e.y - pointer.offsetHeight/2 + "px";
});
document.addEventListener("mousemove", function(e){
delayLine.put(e);
}, false);