【转】原来Tween缓冲是这么回事

转自:http://bbs.9ria.com/viewthread.php?tid=63977

Tween缓冲

Tween缓冲大家应该都不陌生,说白了就是从一起始位置逐渐移动到目标位置的过程,这个过程可以是加速移动,也可以是减速移动,这些不同的缓动方式就是Tween的各种ease。

Tween算法

概念知道了,了解一下Tween的算法对我们更好的使用Tween或者编写自己的Tween都是很有帮助的。

在缓动过程中,随着时间的推移,对象从起始位置开始逐渐向目标位置移动,我们假设移动的距离为disX,并将其作为y轴,时间t作为x轴,这样可以轻松的得到一条曲线,如下图:

在上图中我取了三个时间点ta、tb和tc,他们对于的移动的距离分别是da、db和dc,其中ta到tb与tb到tc之间的时间相同,但是很明显的可以看到db-da比dc-db小,也就是说相同的时间内,时间越靠后,对象移动的越快,实际上着就是Tween中的Cubic缓动模式,你可以在下面的SWF中看到它的效果。

请使用下面的链接升级 Flash Player 到最新版本:

安装最新的Flash Player插件

如果曲线是下面这种情况,你觉得缓动应该是什么样子的呢?

在开始部分的SWF的舞台中点击,试着找到这条曲线,看到了吗?上面的方块像是一个篮球掉在地上一样,反弹了几下然后停止在目标位置,这是Tween种的Bounce缓冲效果。Tween中还有很多很好玩的缓冲模式,你可以在TweenLite开源类库中找到这些缓冲模式。

效果是看到了,但是缓动是怎么计算的呢?别着急,听我们慢慢给你细说。

首先我先声明几个变量:

  • time:缓动经历过的时间
  • beforeMove:起始位置
  • changeDistance:起始位置与目标位置的距离,也就是距离上的一个变化量
  • duration:我们要求对象从起始位置移动到目标位置所需的时间,也就是缓动的总时长

我们假设对象是匀速像目标位置移动,那么根据这四个变量可以轻松的计算出对象在经历time时间后应处的位置pos,公式如下:

1pos = changeDistance * ( time/duration ) + beforeMove

能看明白上面的公式吗?在经历的time时间后,用changeDistance乘以这个时间time占缓动总时长duration的比例,可以得到移动的距离,再加上初始位置便是对象实际应该处的位置。 请你试着代开TweenLite开源类中的Linear类,你会看到下面的代码:

 1package gs.easing {
 2public class Linear {
 3	public static function easeNone (t:Number, b:Number, c:Number, d:Number):Number
 4	{
 5		return c*t/d + b;
 6	}
 7	public static function easeIn (t:Number, b:Number, c:Number, d:Number):Number 
 8	{
 9		return c*t/d + b;
10	}
11	public static function easeOut (t:Number, b:Number, c:Number, d:Number):Number 
12	{
13		return c*t/d + b;
14	}
15	public static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number 
16	{
17		return c*t/d + b;
18	}
19}
20}

是不是很眼熟?是的,就是刚刚我讲过的那个公式,这就是TweenLite中Linear缓动模式的算法,你可以试着打开其他缓动模式类看一下它们的源码,虽然easeIn、easeOut和easeInOut的算法不同,但是它们都包含了这四个参数:t(time)、b(beforeMove)、c(changeDistance)及d(duration)。

但是在TweenLite计算缓动时,并不是直接将起始位置和起始与目标位置的距离作为参数传递给easeIn函数,因为TweenLite不只是缓动坐标,还包括对象的宽高,透明度等等,所以实际上TweenLite是将这两个数值分别用0和1代替,得到经历时间与缓动时间长的比例factor,然后再用factor应用到对象属性的缓动上。

1factor = Linear.easeIn ( t,0,1,d);
2object.para = changeValue * factor + beforeValue;

理解了缓动的计算原理,你是不是可以运用大学里学的曲线方程写出自己的缓动模式呢?!