在分钟的速度对角线运动



关于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

任何想法?

您可以通过两种方式改进您的代码:

  1. 使用绝对跟踪而不是相对跟踪
  2. 使用绝对时间控制

绝对跟踪

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。

最新更新