关于此类似的问题有很多,但不完全是我所知道的。
想要以慢节奏沿路径移动对象。这是我所拥有的一个例子。
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
有什么想法吗?
答案 0 :(得分:2)
您可以通过两种方式改进代码:
Javascript使用双打进行所有计算,因此您没有真正的准确性问题,但绝对跟踪公式更准确,更容易:以(x0, y0)
为起点,(x1, y1)
为终点可以计算两者之间的任何点:
x = x0 + t*(x1 - x0);
y = y0 + t*(y1 - y0);
其中t
从0.0(开始)到1.0(结束)。
这是您的代码存在严重问题的地方。 在Javascript(以及大多数其他情况下)设置计时器时,您无法确定该功能将被称为完全您想要的功能。你唯一知道的是你的功能不会被称为更多而不是你所要求的功能,但是有些呼叫在你需要的时间内会“迟到”是很常见的。 要获得随时间变化的受控移动,您需要检查时钟而不是假设呼叫时间是预期的:总结...
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);
}
此外,绝对定时的使用简化了例如“缓和”(缓慢启动和加速和减速停止):只需在计算t
线后添加
t = t*t*(3 - 2*t);
在这种情况下,speed
参数表示平均速度,单位为px / ms。