刚刚学习了一下网页动画中上的缓动效果,分享一下学习心得。
缓动曲线的概念:
缓动曲线是一个0为起点的连续函数曲线,x轴表示时间变化,y轴表示位移变化。曲线的斜率反映出运动的数度。
缓动效果在Flash动画中比较常见,用于模拟一些现实中常见的运动轨迹,或者制造一些超绚的效果。
而且新版本的Flash中,内置了一些常用的缓动曲线函数。
可惜,Flash的这些曲线函数不是开源的,我们不知道内部如何实现,也就无法将其移植到JS中。感受其绚丽的同时,未免有一丝遗憾。
于是乎,自己琢磨琢磨。
首先,我对Flash的渐变函数接口非常不满。
搞那么多参数干吗?
要描述一个区间的渐变运动特征,只需一个y = f(x)足已。那么一大堆参数,真够罗嗦。
//原理:我们以终点位移为参考,只需要知道中间个点相对于最终位移,我们就能确定运动的规律。
y= f(x)
//约定
//x ∈ [0,1] #将x变化换算成[0,1]是最简单不过的操作
//f(0) = 0 #运动是连续的嘛^_^.
//f(1) != 0 #如果f(1) = 0了,那不就没有运动嘛,中间即使有位移,我也无法计算中间的位移相对于总体位移的比例。
曲线转换
每种类型的渐变都有三种变形
渐入(in)
|
在过渡的开始提供缓动效果。
|
渐出(out)
|
在过渡的结尾提供缓动效果。
|
渐入渐出(inOut/Both)
|
在过渡的开始和结尾提供缓动效果。
|
其中,我们只要知道一个的曲线,其他两个都可以转换生成:
知道渐入曲线之后,将其相对于(0.5,0.5)点绘制镜像,就是一个缓出运动,分段叠加就是一个完整的缓入缓出运动。
首先,常见的加速/减速运动:
初中物理就能搞定。
加速渐变函数为(easeIn):
y=x*x; //y轴比例常数无需考虑
这是一个简单的2次曲线,表现一个渐入运动。
简单的变换一下:y = 1-(1-x)*(1-x) 减速运动(easeOut)
复杂一点:
y = x>0.5? 1-2(1-x)*(1-x) :
2*x*x :
先加速后减速运动(easeBoth)
既然有二次曲线,很自然就想到三次、四次曲线。是的,这些曲线都有类似特征,区别在中间更陡峭,两头平缓(缓入缓出)
接下来,我就想实现一下弹动效果:
这类效果就好像一个甲虫飞到蜘蛛网上,在网上抖动两下,静下来听天由命。
抖动,周期运动,好,我们很快就想到正弦曲线。
方法基本正确,不过我起初还是走弯路了,我自作聪明的想着延长开始的半周期(x轴边形处理,振动让周期先大后小)。
但最终发现效果非常不理想,最后查看yui的实现。模仿一下,走出了这个误区。
我们通常看到的振荡移位效果,都是开始移动了较长位移,给人一种开始的振动周期更长的错觉,振动周期是不需要变化的。
纠正这个错误后,实现曲线函数如下:
y = Math.pow(1024,x-1)*Math.sin(x*((2*(period||1)+0.5)*Math.PI));
利用指数函数的第二象限的渐变特征变形,取处理正弦波形的振幅,达到一个衰减的效果。
趁热打铁,看看yui的其他几类渐变效果:
回退起步效果。
喜欢看动画片的话,你一定记得这个常见的场面,当一个家伙想快跑的时候,一点要先回撤一段距离,能后如突然加速前进。ok要的就是这个效果。
实现其实也很简单,一个二次曲线就可以搞定
y = x*(x-(backDistance||0.1)*4)
撞墙效果
这个名字可能不太合适吧,应该叫撞地效果更合适,鉴于撞墙这个名词更常见一些,也就标题党一回好了:)
玩过弹球吧,弹球的运动规律一定还记得。
对就是这种轨迹。
运功轨迹就是若干条二次曲线的分段拼接。改写一个yui里面的模拟实现。
this.bounceOut = function (x) {
if (x < (1/2.75)) {
return x*x;
} else if (x < (2/2.75)) {
return (x-=(1.5/2.75))*x + .75/7.5625;
} else if (x < (2.5/2.75)) {
return (x-=(2.25/2.75))*x + .9375/7.5625;
}
return (x-=(2.625/2.75))*x + .984375/7.5625;
};
这里手动指出了一大堆参数,其实,这些参数都可以通过计算得出,偷个懒,就这么地吧,^_^
演示url (IE不支持)
posted on 2007-10-14 21:14
金大为 阅读(1210)
评论(0) 编辑 收藏 所属分类:
JavaScript