关于SO类似的问题有很多,但据我所知并不完全是这样。
希望以缓慢的速度沿着路径移动物体。以下是我手头的一个例子。
var moverateX,moverateY;
function setup (){
var opp=targetY-startY;
var adj=targetX-startX;
var hyp=Math.sqrt ((opp*opp)+(adj*adj));
moverateY=10*(opp/hyp);
moverateX=10*(adj/hyp);}
function okgo (){
obj.style.left=currentX+moverateX+'px';
obj.style.top=currentY+moverateY+'px';
setTimeout (function (){okgo ();},50);}
它工作,但移动太快。如果我将比率乘以的数字更改为较小的数字,则对象将错过最终目标。如:
var moverateY=2*(opp/hyp);
var moverateX=2*(adj/hyp);
//moves slower but misses the end mark by a fair margin
任何想法?
您可以通过两种方式改进您的代码:
- 使用绝对跟踪而不是相对跟踪 使用绝对时间控制
绝对跟踪
Javascript使用双精度的所有计算,所以你没有一个真正的精度问题,但绝对跟踪的公式更准确和更容易:给定(x0, y0)
作为起点和(x1, y1)
作为终点,你可以计算两者之间的任何点:
x = x0 + t*(x1 - x0);
y = y0 + t*(y1 - y0);
其中t
从0.0 (start)到1.0 (end)。
绝对时间控制
这是你的代码有严重问题的地方。在Javascript中(以及在大多数其他情况下),当您设置计时器时,您无法确定该函数将准确地调用。唯一可以确定的是,函数调用的次数不会超过所请求的,但是很常见的情况是,某些调用会比所要求的时间"晚"。为了控制时间的变化,你需要检查时钟,而不是仅仅假设调用时间是预期的:To sum up…
function animate(div, x0, y0, x1, y1, speed) {
var dx = x1 - x0;
var dy = y1 - y0;
var dist = Math.sqrt(dx*dx + dy*dy);
var total_time = dist / speed;
var start_time = new Date().getTime();
var cback = setInterval(function() {
var now = new Date().getTime();
if (now >= start_time + total_time) {
// Animation is complete
div.style.left = x1 + "px";
div.style.top = y1 + "px";
//clearInterval(cback);
} else {
// We are still moving
var t = (now - start_time) / total_time;
div.style.left = (x0 + t*dx) + "px";
div.style.top = (y0 + t*dy) + "px";
}
}, 10);
}
绝对计时的使用也简化了,例如"easing"(缓慢启动和停止,伴随着加速和减速):只需在t
的计算之后加上
t = t*t*(3 - 2*t);
在本例中,speed
参数表示平均速度,单位为px/ms。