在mx.effects.easing包中,二次缓动命名为Quadratic.as。它是最普通的一种缓动类型,Flash的时间轴缓动就是使用了二次缓动。二次缓动中的“二次”表示这种运动的表达式是基于变量的平方。在这里就是t2。
p(t) = t2
下图就是二次缓动曲线。大家知道,二次函数的图像是一条抛物线。二次缓动曲线实际上是0-1定义域上的抛物线。
下面是二次缓入的ActionScript函数:
public static function easeIn(t:Number, b:Number, c:Number, d:Number):Number{ return c * (t /= d) * t + b; }
在分析标准指数滑动的部分中,我们已经得出了向缓动函数传递的4个参数,即t是时间,b是起始位置,c是位置的改变,d是补间的持续时间。
代码中的t/=d是一种优化技术。这种组合操作符可以在一步中完成除法和t的重新赋值,并使用它的值进行进一步的操作。也就是说将t除以d并将结果附以参数t,从而实现t落在0-1的范围内,完成对它的标准化。比如缓动的持续时间d为10帧,要计算第五帧的位置,也就是说t为5。将5/10的结果也就是0.5又重新赋给了参数t。完成这个运算之后,后面要乘以的t的值也发生了改变。所以,(t/=d) * t实际等同于t2,只不过t参数中保存的数值发生了改变。乘以t后从而产生二次曲线,这时的t已经被标准化了。然后将标准化的值乘以c,以放大到所需的输出。最后加上初始偏移量b完成计算,并返回结果。
下面是二次缓出函数:
public static function easeOut(t:Number, b:Number, c:Number, d:Number):Number{ return -c * (t /= d) * (t - 2) + b; }
对二次缓出函数的推导:-c * (t /= d) * (t – 2) + b
= -c * t * (t – 2) + b
= -c * (t2 – 2t +1 – 1) + b
= -c * ((t – 1)2 – 1) + b
= c * (-(t – 1)2 + 1) + b
根据抛物线平移公式,等于是将曲线y= t2乘以-1,实现图像的垂直翻转。-(t – 1)2将曲线延t轴向右平移1个单位,-(t – 1)2 + 1再使曲线延p轴向上平移1个单位。从而实现二次缓出曲线。可以看到,缓出公式曲线实际就是将缓入曲线垂直翻转,延t轴往右平移1个单位,再使曲线延p轴向上平移1个单位得到的。
二次缓入-缓出函数的代码如下:
public static function easeInOut(t:Number, b:Number, c:Number, d:Number):Number{ if ((t /= d / 2) < 1) return c / 2 * t * t + b; return -c / 2 * ((--t) * (t - 2) - 1) + b; }
这个公式的代码比较晦涩难懂,特别是后半段。公式的逻辑很明确:运动补间的总时间为t,前一半时间执行缓入公式,后一半时间执行缓出公式。从图像上分析,其实就是将缓入曲线和缓出曲线拼接起来。
以下面的两个函数为基,然后在这个基础上拉伸或收缩。
p(t) = t2 (0<=t<1)
p(t) = -(t – 2)2 + 2 (1 <=t<=2)
那如何改变参数从而实现曲线的拉伸呢?以y = x2为例,如果要将曲线在y轴上压缩到一半大小,则函数变化为y = x2 /2;如果要将曲线在x轴上压缩一半,则x必须减少一半。
首先分析函数中实现缓入的上半段代码。执行if ((t /= d / 2) < 1)后,使t值限定在0 <= t <= 2的范围,当0 <= t < 1时,执行代码 return c / 2 * t * t + b。这时,和二次缓入差别不大,只是由于缓入只占到整个补间的位置改变的一半,所以c必须除以2。
然后再来分析一下实现缓出的后半段代码:return -c / 2 * ((–t) * (t – 2) – 1) + b。注意一下代码中的–t(两个减号),实际上它等于(t – 1)。当–t执行后,实际上后面的t的值也已经改变,也就是说–t执行后,(t – 2)已经等价于((t – 1) – 2),所以详细的推导为:
-c / 2 * ((–t) * (t – 2) – 1) + b
= -c / 2 * ((t – 1) * (t – 1 -2) – 1) + b
= -c / 2 * (t2 – 4t + 3 – 1) + b
= -c / 2 * (t2 – 4t + 2) + b
= -c / 2 * ((t – 2)2 – 2) + b
= c / 2 * (-(t – 2)2 + 2) + b
经过推导之后,大家发现后半段的缓出曲线,实际上就是将标准曲线p(t) = t2,向下翻转,然后向右、向上平移2个单位,并截取定义域(1 <= t <= 2)之间的那段抛物线。最后当然还是将标准化的值乘以位置的改变的一半即c / 2,以放大到所需的输出。最后加上初始偏移量b完成计算,并返回结果。