偶尔会用到弹簧类似的缓动效果,就是不是直接从 A点缓动到B点, 而是 从A点出发,但是到最终停在B点之前,会以阻尼的方式在B点来回若干次。类似弹簧一样。 其实已有 bounce ease 的算法公式,比如:
Bounce: { easeIn: function(t,b,c,d){ return c - Tween.Bounce.easeOut(d-t, 0, c, d) + b; }, easeOut: function(t,b,c,d){ if ((t/=d) < (1/2.75)) { return c*(7.5625*t*t) + b; } else if (t < (2/2.75)) {
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
} else if (t < (2.5/2.75)) {
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
} else {
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
}
},
easeInOut: function(t,b,c,d){
if (t < d/2) return Tween.Bounce.easeIn(t*2, 0, c, d) * .5 + b;
else return Tween.Bounce.easeOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
}
}
可惜通常这样的公式都满足不了需求。我们要的是简易的,又易于控制的代码。所以:
move: function () {
var disX = this.endX - this.x;
var disY = this.endY - this.y;
var dis = Math.sqrt(Math.pow(disX, 2) + Math.pow(disY, 2));
var force = dis * parseFloat(document.getElementById('force').value);
var angle = Math.atan2(disY, disX); // atan2(x, y) 表示 点(x,y)到x轴的弧度
this.vx += force * Math.cos(angle);
this.vy += force * Math.sin(angle);
this.vx *= 0.92;
this.vy *= 0.92;
//
this.x += this.vx;
this.y += this.vy;
},
上面简单的代码可以做到我们想要的, 关键的在于 Math.atan2 获取某个点到x轴的反正弦。注意 两个参数,x,y调了个位置。 这个是为了配合下面 vx 阻尼时 乘以的系数。 因为
通常更习惯的是 x方向乘以 cos 的系数, y方向乘以 sin的系数。