偶尔会用到弹簧类似的缓动效果,就是不是直接从 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的系数。
Demo 1
Demo 2