
- 本栏最新文章
- flash缓入缓出运动 04-01
- Flash AS制作上升的水泡效果动画 03-31
- AS柔化函数(解决马赛克) 03-31
- flash+webservice 乱码问题解决一例 03-31
- flash动态改变注册点解决方案 03-31
- Flash 制作晃动的烛光 03-27
- AS2:动态改变注册点(英文) 03-27
- 注册点与中心点 03-27
- AS改变“注册点”的方法,需要flash8以后版本 03-27
- Flash制作仿苹果界面的互动图标界面 03-26

- 本栏推荐文章
- Photoshop教程:水灵灵的美女调出来 12-30
- AS3与后台交互 12-21
- AS3通俗教程---AS3自身loading制作 12-19
flash缓入缓出运动
Robert Penner [加拿大] 著的《Programming Macromedia Flash MX》(中文译本:《Flash MX 编程与创意实现》)是一本非常经典的关于flash脚本actionscript的运用及创意的实例宝书。
这种经典书籍值得反复咀嚼,温故知新,就好像小时候的课本,近来就在读这本经典,学习之余,觉得有必要写写学习笔记,很多东西是这样的:当时可能灵感突来,天赋奇发,一点便就通了,可是过背几日,又都忘了,或者思维便秘了,堵在那硬是不通,所以需要学习笔记这样一副泻药来疏通疏通,一通,便神清气爽,两腋生津了……
AS(actionscript简称)变形的最著名的形式要属“缓冲”(缓动),缓冲包括两种运动:缓入和缓出。特别是“缓出”(ease-out),其中最著名的技术是所谓的“标准指数滑动”。这个滑动过程是向着目标运动,并逐渐减慢速度直至停止--我们称之为所谓的“缓出”。之所以称这个滑动是指数的,是因为运动的速度可以用一个指数表达式来表示。
标准指数滑动公式:
this.onEnterFrame=function(){
var distance=this.destinationX-this._x;
this._x=this._x+distance/2;
}
简化之:
this.onEnterFrame=function(){
var distance=this.destinationX-this._x;
this._x+=(this.destinationX-this._x)/2;
}
Robert Penner 指出这种技术的三个不满:
第一:这种技术只能用于缓出,不能用于缓入;
第二:不能根据指定的时间直接计算出运动变形的位置;
第三:不能确切地指定运动变形的持续时间;
然后他在书中列出了各种缓动变形公式,以及简单的公式说明,没有详细的推导,我数学本来就烂,这么多年没用,早就忘掉1+1等于几了~,但是知其然,不知其所以然,就是堵在心里不舒服,于是煞费苦心,dowanload来高中的数学课本,拿了纸笔,又是画图又是写算式,一步一步推导,终于有个一知半解,下面是我的各种缓动公式的详细推导,作为“泻药”给自己备用:)~
二次缓入公式:
Math.easeInQuad=function(t,b,c.d){
return c*(t/=d)*t+b; }
其中,t是时间,b是起始位置,c是位置的改变,d是运动变形的持续时间。
将t除以d从而将它标准化。这使t落在0~1的范围内。然后乘以t产生二次曲线。然后将标准化的值乘以c,以放大到所需的输出。最后加上初始偏移量b完成计算,并返回结果。
上面的代码中的t/=d是一种优化技术。这种组合操作符可以在一步中完成除法和t的重新赋值,并使用它的值进行进一步的操作。
二次缓出公式:
Math.easeOutQuad=function(t,b,c,d){
return -c*(t/=d)*(t-2)+b; }
我的详细推导:-c*(t/=d)*(t-2)+b
=-c*t*(t-2)+b
=-c*(t^2-2t+1-1)+b
=-c*((t-1)^2-1)+b
注意:这种推导并非单纯的数学公式推导,而是结合了代码运算的推导,
比如: -c*(t/=d)*(t-2)+b =-c*t*(t-2)+b 之所以(t/=d)变成了t,是因为代码执行时,完成除以d后对t进行了重新赋值,这时候t等价于没执行代码时的(t/=d)。
根据抛物线平移公式,y=-c*(t-1)^2+1 等于是将曲线 y=c*t^2 乘以-1(图像垂直翻转),然后将曲线延t轴往左平移1一个单位【(t-1)^2】,然后再曲线延p轴往上平移1个单位【(t-1)^2+1 】
可以看到,缓出公式曲线实际就是将缓入曲线垂直翻转,然后延t轴往左平移1一个单位,再曲线延p轴往上平移1个单位。
二次缓入-缓出公式:
Math.easeInOutQuad=function(t,b,c,d){
if((t/=d/2)<1) return c/2*t*t+b;
return -c/2*((--t)*(t-2)-1)+b; }
这个公式的代码很晦涩,很难懂,特别是后半截,公式的逻辑很明确:运动变形的总时间为t,前一半时间(前t/2)执行缓入公式,后一半时间(后t/2)执行缓出公式。
从曲线图像上来分解,其实就是将缓入曲线和缓出曲线不论高宽都缩小到原来的一半,然后无缝拼接。(如上图7.6)。我们要的是S型的曲线。
用
y=x^2 (0=<x<=1)
y=-(x-2)*(x-2)+2(1<=x<=2)
做一个基,然后在这个基础上"拉伸"或"收缩"就行了。
然后,我又翻看了一下高中课本,温习了一下曲线拉伸的参数变化:
以y=X^2为范例,如果要将曲线延y轴缩小到一半大小,则y=(x^2)/2;如果要将曲线延x轴缩小到一半大小,则x要缩小一半,即2x(现在的)=x(原来的),代入得:y=(2x)^2/2=2x^2
通过这个基,推导出来的标准公式为:
Math.easeInOutQuad=function(t,b,c,d){
if((t/=d/2)<1/2) return c*2*t*t+b;
return -c((2t-2)*(2t-2)-2)+b; }
没错~正常运行,和原书的公式有些出入,其实只是稍做了些等式变化而已~下面做原公式的推导分析
先来分析推导公式的上半截【 if((t/=d/2)<1) return c/2*t*t+b】:代码执行if((t/=d/2)<1)后,这时候t就定在了0<t<2的范围内,t 的值等价于以前的2t值,即:c/2*t*t+b=c/2*2t*2t ,缓入曲线图像的t轴大小缩小了1/2,然后c/2,缓入曲线图像的p轴大小也缩小了1/2,和上面的标准公式的推导一样。
然后是公式下半截的推导【return -c/2*((--t)*(t-2)-1)+b 】,首先,我犯了一个非常低级的常识性错误(唉,自己还常说,人可以没有知识,但不能没有常识),什么错误呢?我居然把--t看成了“负负t”,就是正t,带入大错特错。(躲到厕所骂了自己250一百遍)。实际上--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*((t-1)*(t-3)-1)+b
=-c/2*(t^2-4t+2)+b
=-c/2*((t-2)*(t-2)-2)+b
同样,代码执行if((t/=d/2)<1)后,这时候t就定在了0<t<2的范围内,t 的值等价于以前的2t值,即:-c/2*((t-2)*(t-2)-2)+b=-c/2*((2t-2)*(2t-2)-2)+b,缓入曲线图像的t轴大小缩小了1/2,然后c/2,缓入曲线图像的p轴大小也缩小了1/2,同样和上面的标准公式的推导一样。
呼~终于写完第一部分二次缓入缓出公式的详细推导,给自己准备了一副思维泻药……
好长,真TMD的长,二次缓入缓出公式推导出来后,其他的缓入缓出公式的推导,便基本大同小异,很容易推导了,随后有空的时候就写……
加油,呵~青蛙大爷我,温故而知新也~


