TweenLite 的一个应用(代码优化)

      Flash学习笔记 2008-8-29 9:27

  聊天室里见到这样一个效果,有一行图块,中间放大的时候,周围图块要进行避让,并且降低透明度,当中间图块缩小时,周围图块要聚拢过来。

  原来的代码中通过 Timer 类来控制时间间隔,用 TweenLite 来实现缓动的过程,其中还使用了外置的三个类,用来记录原始位置及位置点的运算,中间的一个核心算法函数更是复杂,代码如下:

function fadeIn(e:TimerEvent){
 for(var i:int=0;i<icons.length;i++){
  var ico:Icon=icons[i];
  if(i!=2){
   TweenLite.to(ico,.8,{x:ico.originPoint.x,alpha:1,ease:Back.easeOut});
  }else{
   TweenLite.to(ico,.8,{scaleX:ico.originScale.x,scaleY:ico.originScale.y,ease:Back.easeOut,onComplete:function(){
              
              for(var i:int=0;i<icons.length;i++){
               var ico:Icon=icons[i];
               if(i==0){
                ico.originPoint.x-=ico.width+span;
                pico=new Icon(ico.frameId);
                pico.originScale=new Scale(.5,.5);
                pico.scaleX=.5;
                pico.scaleY=.5;
                pico.x=icons[icons.length-1].x+ico.width+span;
                pico.y=ico.y;
                pico.originPoint=new Point(icons[icons.length-1].x,ico.y);
                addChild(pico);
               }else{
                ico.originPoint.x=icons[i-1].x;
               }
               TweenLite.to(ico,.8,{x:ico.originPoint.x,ease:Back.easeOut});
              }
              TweenLite.to(pico,.8,{x:pico.originPoint.x,ease:Back.easeOut,onComplete:function(){
                             var ico:Icon=icons.shift();
                             removeChild(ico);
                             icons.push(pico);
                             timer1.start();
                            
                                    }});
                         
                                }});
  }
 }
}

  这段函数中对 TweenLite 进行了三层嵌套使用,因此,不能自动套用格式,系统会报错,多一个花括号或是少一个也是不可以的。该动画效果引起了我的注意,并且发现 TweenLite 是一个可以替代 Tween 类的一个好东西。于是详细的翻译了TweenLite 的参数说明,并且对 TweenLite 有了更深入的了解。

  当我对  TweenLite 了解更多之后,我发现

  1.这个效果的核心是中间图块的缓动,其它图块只是根据中间的来进行相对运动,位置是可以简单计算的,因此不需要对所有图块都进行位置上的缓动处理。

  2.  TweenLite 提供有延迟处理参数 delay ,因此,在一个缓动完成后,我们可以通过参数指定下一次缓动开始的时间,从而避免使用 Timer 类来控制时间间隔。

  3.  TweenLite 在缓动开始、进行中、结束时均提供了调用函数的功能,这为我们提供了一个良好的代码流程结构,因此,不需要嵌套来写函数,我们的目的只是一个缓动结束后进行下一个缓动,那么在缓动结束时调用的函数中,加入下次缓动的代码就行了,阅读代码时会方便许多,而不会像上面显示的那样,难于调试,更不要说去扩充或是修改了。

  总结以上三个问题之后,再来考虑这个效果,我们可以先将单独的图片加载到 mc 中,再将mc 统一放到一个数组中去,(图片较少时,也可以不用数组),每次只对中间的图块进行缓动,其它的图块做相应的位置调整,从而得到整体的运动效果。

import gs.TweenLite;
import gs.easing.*;

//因为 TweenLite 中提供有延迟缓动的参数 delay ,因此不需要使用定时器 timer 类,并且,缓动的开始、中间、结束位置
//均可以指定相关的处理函数,所以 timer 更加的不需要。

//第一步,将图块摆放到舞台上。原始图片较大,故采用 scalX = 0.47 ,图块间相隔15像素,图块的注册点在几何中心。

var pic_arr:Array = new Array();
pic_arr.push( new Pic1());
pic_arr.push( new Pic2());
pic_arr.push( new Pic3());
pic_arr.push( new Pic4());
pic_arr.push( new Pic5());
pic_arr.push( new Pic6());

var originScaleX:Number = 0.47;  //最初的缩放比
var originWidth:Number = pic_arr[0].width * originScaleX;//最初的图片宽度
var dist = originWidth + 15;//图片间的坐标间隔

for (var i:int = 0; i<pic_arr.length; i++) {
 //指定所有图块的大小及位置
 pic_arr[i].scaleX = pic_arr[i].scaleY = originScaleX;
 pic_arr[i].x = i * dist + 0.5 * originWidth + 15;
 pic_arr[i].y = 200;
 addChild( pic_arr[i] );
}

//第二步,建立位置移动函数,用来在中心图块放大或缩小时,调整其它图块的位置。

function pushAside( ){
 //根据中心图块的大小变化,让周边图块发生移动
 var step = pic_arr[2].width/2 + 0.5 * originWidth + 15;
 pic_arr[0].x = pic_arr[2].x - step - dist;
 pic_arr[1].x = pic_arr[2].x - step;
 pic_arr[3].x = pic_arr[2].x + step;
 pic_arr[4].x = pic_arr[2].x + step + dist;
 pic_arr[5].x = pic_arr[2].x + step + 2 * dist;
}

//第三步,对中心图块进行缓动,这三个缓动效果是依次进行的,所以在onComplete 中指定的就是下次要执行的函数。

function enLargeMotion(){
 //中心图块放大的效果
 TweenLite.to(pic_arr[2], 0.8, {scaleX:0.8, scaleY:0.8, ease:Back.easeOut,delay:2,onStart:fadePic,onUpdate:pushAside,onComplete:toSmallMotion});
}
function toSmallMotion(){
 //中心图块缩小的效果
 TweenLite.to(pic_arr[2], 0.8, {scaleX:originScaleX, scaleY:originScaleX, ease:Back.easeOut,delay:1,onStart:lightPic,onUpdate:pushAside,onComplete:toLeftMotion});
}
function toLeftMotion(){
 //中心图块向左移动的效果
 var mc:MovieClip = pic_arr[2];
 TweenLite.to(mc, 0.8, {x:mc.x - dist , ease:Back.easeOut,delay:1,onUpdate:pushAside,onComplete:rePlay});
}

//第四步,通过观察原来的效果,当中心图块放大时,其它的图块有一个变淡的效果,通过设置 onStart ,可以进行同步处理,这里需要添加两个函数,用来控制透明度的。

function fadePic(){
 //降低透明度
 TweenLite.to(pic_arr[0], 1, {alpha:0.5, ease:Back.easeOut});
 TweenLite.to(pic_arr[1], 1, {alpha:0.5, ease:Back.easeOut});
 TweenLite.to(pic_arr[3], 1, {alpha:0.5, ease:Back.easeOut});
 TweenLite.to(pic_arr[4], 1, {alpha:0.5, ease:Back.easeOut});
 TweenLite.to(pic_arr[5], 1, {alpha:0.5, ease:Back.easeOut});
}
function lightPic(){
 //增大透明度
 TweenLite.to(pic_arr[0], 1, {alpha:1, ease:Back.easeOut});
 TweenLite.to(pic_arr[1], 1, {alpha:1, ease:Back.easeOut});
 TweenLite.to(pic_arr[3], 1, {alpha:1, ease:Back.easeOut});
 TweenLite.to(pic_arr[4], 1, {alpha:1, ease:Back.easeOut});
 TweenLite.to(pic_arr[5], 1, {alpha:1, ease:Back.easeOut});
}

//第五步,三个缓动函数执行完后,需要再 rePlay(再来一遍),但是重来之前需要对数组内容进行调整,将第一个元素搬到最后去,其它依次向前动,数组的 shift 方法可以帮我们做到这一点,这样,始终都可以方便的找到中心图块 pic_arr[2] 。

function rePlay(){
 //将数组中的首个图块搬到最后一个位置,同时将该块从舞台左侧移动到舞台右侧
 var mc = pic_arr.shift();
 pic_arr.push( mc );
 mc.x = pic_arr[4].x + originWidth + 15; 
 //重新启动缓动效果
 enLargeMotion();
}

//第六步,前面的函数依次调用关系建立之后,可以来观看我们的效果了,不要忘了用下面的代码让一切动起来, 一旦运动起来之后,函数之间的相互调用,会让缓动效果一直持续下去,如果担心时间的累积,会让图块产生漂移,可以在 rePlay 函数中用数字直接指定具体的位置,从而减少误差的累积。
//首次启缓动效果
enLargeMotion();

 源文件下载

相关文章:

TweenFilterLite 参数说明  中文翻译
http://blog.5d.cn/user12/dzxz/200809/500545.html

TweenMax 参数说明 中文翻译
http://blog.5d.cn/user12/dzxz/200809/500547.html

TweenLite 参数说明 中文翻译
http://blog.5d.cn/user12/dzxz/200808/497831.html

一个Flash 网页导航效果
http://blog.5d.cn/user12/dzxz/200811/506117.html

个性签名 时钟版
http://blog.5d.cn/user12/dzxz/200810/504465.html

标签集:TAGS:TweenLite 应用举例
回复Comments() 点击Count()

回复Comments

{commentauthor}
{commentauthor}
{commenttime}
{commentnum}
{commentcontent}
作者:
{commentrecontent}