使用actionscript3.0构建一个异步加载图片的画廊(完结篇)

发布于,归属于actionscript33个座位已被强势霸占! 共有947人围观    

引言


这篇教程将是这个actionscript3.0实战系列教程的完结篇,也是整个系列教程最为重要的一篇,明河将讲解如何使用actionscript3.0制作华丽的滑动效果
首先先来回顾下系列教程:

使用actionscript3.0制作华丽的滑动效果

1、构思交互效果

  • 图片剪辑在滑动时要随机旋转,当然旋转的角度要有个范围
  • 中间的图片剪辑为当前图片剪辑,适当放大
  • 多余图片剪辑移出时带有透明度、位置、大小的变化
  • 随滑动块的滑动,图片剪辑也开始滑动

2、关键变量说明

  1. //显示图片的个数
  2.         private var imagesToShow : Number = 4;

这里要留意imagesToShow为4,并不是显示4张图片,而是显示5张,这是为什么呢?跟作者的算法有关,将在下面讲解。

3、goTo函数讲解

goTo位于lib.Gallery
goTo函数的用途让指定di的图片剪辑移动到中间位置,同时其他图片剪辑的位置也发生改变。
比如在loadImages函数的结尾goTo(0)第一张图片将滑动到中间的位置。
那么这个中间位置是如何确定的呢?留意构造函数内有stageWidth = stage.width;即根据舞台宽度来确定的,这将在下面讲解。

  1. /**
  2.         *移动到指定图片
  3.         *@param imgId {Number} 图片id(这里的id指的是图片数组的索引值)
  4.         */
  5.         private function goTo(imgId : Number):void{
  6.             //方向,正为读取下一个图片,即滚动条滑块向右,图片向左;负与之相反
  7.             var direction:Number;
  8.             if(orgImgId != imgId){
  9.                 //判断方向
  10.                 if ( imgId > orgImgId  ) direction = 1;
  11.                 else direction = -1;
  12.                 //激活id为imgId及其其后图片剪辑(所要激活数,取决于imagesToShow)
  13.                 for ( var i : Number = - Math.floor(imagesToShow/2); i <= Math.floor(imagesToShow/2); i++ ){
  14.                     var _id = imgId + i;
  15.                     if(_id < images.length && _id >=0) images[_id].makeActive(i,direction);
  16.                 }
  17.                 //删除二端多余图片
  18.                 for(var j:Number = 0;j < imagesClip.numChildren ; j++){
  19.                     var tile:Img = imagesClip.getChildAt(j) as Img;
  20.                     if(tile.id < imgId - Math.floor(imagesToShow/2) || tile.id >  imgId + Math.floor(imagesToShow/2)){
  21.                         tile.deActive( direction );
  22.                     }
  23.                 }
  24.                
  25.                 //图片计数
  26.                 tt.text = imgId + 1 + "/" + images.length;
  27.                
  28.             }
  29.             orgImgId = imgId;
  30.            
  31.         }

以上是goTo的完整代码。
这里我对几个关键点进行下讲解
必须确定滑动方向
这点很重要,只有确定了滑动方向,才有办法确定图片画廊往哪个方向滑动。

  1. //判断方向
  2.                 if ( imgId > orgImgId  ) direction = 1;
  3.                                else direction = -1;

正为滚动条滑块向右,图片向左;负与之相反。
接下来明河来解释下为什么imagesToShow为4而实际上显示的是5张图片

  1. //激活id为imgId及其其后图片剪辑(所要激活数,取决于imagesToShow)
  2.                 for ( var i : Number = - Math.floor(imagesToShow/2); i <= Math.floor(imagesToShow/2); i++ ){
  3.                     var _id = imgId + i;
  4.                     if(_id < images.length && _id >=0) images[_id].makeActive(i,direction);
  5.                 }

留意这个循环体,之前明河误以为作者只是要激活中间的图片剪辑,实际上不是,而是激活显示在舞台的五个图片剪辑,即让五个一起移动,来看个图:

imagesToShow不仅表征图片显示数,更是表征图片剪辑的位置。imagesToShow = 4即是从-2循环到2,中间还有个索引值为0!
_id < images.length && _id >=0 当图片剪辑的id小于0时是不激活的,所以goTo(0),实际上第一个图片剪辑正好是位于中间的索引值0。
而imagesToShow = 3舞台显示的倒是3个图片剪辑,这是何故。留意Math.floor(imagesToShow/2)。当imagesToShow = 3时是从-1循环到1!
goTo(0)实际上移动的就是id为0、1、2的图片剪辑。

4、makeActive函数讲解

makeActive是lib.Img的公共方法,来看代码:

  1. /**
  2.         *将图片添加到舞台,同时移动图片
  3.         *@param position {Number} 位置
  4.         *@param direction {Number} 方向
  5.         */       
  6.         public function makeActive(position : Number, direction : Number):void{
  7.             //处于激活状态
  8.              deactivating = false;
  9.             //检测图片剪辑是否有父容器,没有的话,将图片剪辑加到图片集剪辑
  10.             if ( parent == null ) 
  11.             {
  12.                 //设置该图片剪辑的初始x轴坐标
  13.                 x = ( direction == 1 ? main.stageWidth + main.defaultWidth * 1 : - main.defaultWidth * 2 );
  14.                 //隐藏该该图片剪辑的
  15.                 alpha = 0;               
  16.                 //将此图片剪辑添加到图片集剪辑
  17.                 main.imagesClip.addChild(this);
  18.             }
  19.             //显示该图片剪辑
  20.             visible = true;
  21.             //读取图片
  22.             if ( numChildren < 3 ) loadImage();
  23.             //设置图片剪辑的索引值
  24.             parent.setChildIndex(this,(parent.numChildren - 1) - Math.abs(position));
  25.            
  26.             //设置图片剪辑距中间位置的偏移
  27.             var extra:Number = Math.round(position * (main.defaultWidth + main.spaceBetween));
  28.             //设置图片剪辑的新的x轴位置
  29.             var newX:Number = Math.round(main.stageWidth/2) + extra;
  30.             //将图片剪辑移动到指定位置
  31.             flyTo(newX,false,(position == 0 ? 1.2 : 1 ) );
  32.            
  33.         }

makeActive有二个重要参数:

  • position 图片剪辑位置
  • direction 移动方向

留意:只有激活图片剪辑的时候才开始加载图片触发loadImage方法同时将此图片剪辑加入到画廊剪辑中,也就是imagesClip中。
将图片剪辑加到画廊剪辑:

  1. //检测图片剪辑是否有父容器,没有的话,将图片剪辑加到图片集剪辑
  2.             if ( parent == null ) 
  3.             {
  4.                 //设置该图片剪辑的初始x轴坐标
  5.                 x = ( direction == 1 ? main.stageWidth + main.defaultWidth * 1 : - main.defaultWidth * 2 );
  6.                 //隐藏该该图片剪辑的
  7.                 alpha = 0;               
  8.                 //将此图片剪辑添加到图片集剪辑
  9.                 main.imagesClip.addChild(this);
  10.             }

加载图片:

  1. //读取图片
  2.             if ( numChildren < 3 ) loadImage();

这里还有个需要留意的点:

  1. //设置图片剪辑的索引值
  2.             parent.setChildIndex(this,(parent.numChildren - 1) - Math.abs(position));

必须修正下图片剪辑的索引值,防止中间的图片剪辑被其他图片剪辑遮住。
根据position参数确定激活的图片剪辑移动到的位置

  1. //设置图片剪辑距中间位置的偏移
  2.             var extra:Number = Math.round(position * (main.defaultWidth + main.spaceBetween));
  3.             //设置图片剪辑的新的x轴位置
  4.             var newX:Number = Math.round(main.stageWidth/2) + extra;

图片剪辑的移动到的位置是以舞台中心点为目标即main.stageWidth/2
extra用于确定图片剪辑距中间位置的偏移
举个例子:我们要让第10个图片剪辑居中,即goTo(10);那么要移动的五张图片为8、9、10、11、12,位置position为:-2、-1、0、1、2
那么第十个图片剪辑的偏移extra为0*(图片剪辑默认宽度+间隙),结果为0,那么第十个图片剪辑将要移动的位置为Math.round(main.stageWidth/2)。

5、flyTo函数讲解

  1. /**
  2.         *将图片剪辑移动到指定位置
  3.         *@param newX {Number} 新的x轴位置
  4.         *@param removeAfter {Boolean}
  5.         *@param scale {Number} 缩放
  6.         */               
  7.         private function flyTo(newX:Number,removeAfter:Boolean,scale:Number = 1):void{
  8.             //TweenLite缓动类参数
  9.             var tweeningOptions : Object = new Object;
  10.             tweeningOptions.x = newX;
  11.             if(removeAfter){
  12.                 //移除动画
  13.                 tweeningOptions.ease = Linear.easeIn;
  14.                 tweeningOptions.alpha = 0;
  15.                 tweeningOptions.scaleX = tweeningOptions.scaleY = 0.3;
  16.                 tweeningOptions.visible = false;               
  17.             }else{
  18.                 //比例缩放
  19.                 tweeningOptions.scaleX = tweeningOptions.scaleY = scale;
  20.                 //旋转
  21.                 tweeningOptions.rotation = (Math.random() * 20) - 10;
  22.                 //ease效果
  23.                 tweeningOptions.ease = Back.easeOut;
  24.                 //透明度
  25.                 tweeningOptions.alpha = 1;           
  26.             }
  27.             //图片剪辑移动动画开始
  28.             TweenLite.to(this,0.4,tweeningOptions);
  29.         }

flyTo既是图片剪辑激活时移动方法,也是图片剪辑移出时移动方法,根据第二个参数removeAfter来确定,如果为TRUE,触发的是移出效果。
这里有个非常关键的类: TweenLite
TweenLite是缓动效果类,非常有名气,网上教程非常多,这里明河就不详述,可以参考这篇文档
图片剪辑激活时的效果配置:

  1. //比例缩放
  2.                 tweeningOptions.scaleX = tweeningOptions.scaleY = scale;
  3.                 //旋转
  4.                 tweeningOptions.rotation = (Math.random() * 20) - 10;
  5.                 //ease效果
  6.                 tweeningOptions.ease = Back.easeOut;
  7.                 //透明度
  8.                 tweeningOptions.alpha = 1;

这个配置难度不大,留意旋转。

6、图片剪辑滑出

图片剪辑既然有滑入,就有滑出,多余图片剪辑的滑出紧随图片剪辑的激活。
滑出的代码与滑入类似

  1. for(var j:Number = 0;j < imagesClip.numChildren ; j++){
  2.                     var tile:Img = imagesClip.getChildAt(j) as Img;
  3.                     if(tile.id < imgId - Math.floor(imagesToShow/2) || tile.id >  imgId + Math.floor(imagesToShow/2)){
  4.                         tile.deActive( direction );
  5.                     }
  6.                 }

遍历图片画廊剪辑,将不在指定位置的多余图片剪辑滑出。

7、来看deActive方法

  1. /**
  2.         *将图片添加到舞台,同时移动图片
  3.         *@param direction {Number} 方向
  4.         */               
  5.         public function deActive(direction : Number):void{
  6.             //图片剪辑不处于移动状态
  7.             if ( ! deactivating ){
  8.                 active = false;
  9.                 var moveTo : Number = ( direction != 1 ? main.stageWidth + main.defaultWidth * 2 : parent.x - main.defaultWidth * 2 );
  10.                 flyTo( moveTo,true);
  11.                 deactivating = true;               
  12.             }
  13.         }

留意moveTo这里的算法跟激活不同。根据方向来确定到底是滑出到哪个位置。

8、滑动块滑动时触发goTo方法

  1. //监听滑动块滑动事件(sliding为自定义事件)
  2.             theHandle.addEventListener("sliding",slide);
  1. /**
  2.         *当滑动块滑动后触发的事件
  3.         */       
  4.         private function slide(_e:Event):void{
  5.             //确定滑动块滑动后,位置所在滑动条的百分比
  6.             var percent:Number = (theHandle.goToX - slider.x)/(slider.width - theHandle.width);
  7.             //确定要滑动哪张图片
  8.             var imgId:Number = Math.round(percent * ( images.length - 1 ));
  9.             goTo( imgId );
  10.         }

没有什么太难的地方,明河不再累述。
至此这个系列教程全部结束,明河敲这么多字不容易,捧场的朋友留个言提提意见,感激不尽!
预告下一期的系列教程:如何构建wordpress插件,也是实战性很强的文章,需要一些基础,敬请期待!

(如果您喜欢这篇教程,可以通过支付宝打赏我们1元哦,拜谢!)

跟作者说两句

:wink: :twisted: :roll: :oops: :mrgreen: :lol: :idea: :evil: :cry: :arrow: :?: :-| :-x :-o :-P :-? :) :( :!: 8-O 8)

3个座位已被强势霸占!

  1. 丕子

    学习

  2. tfwangbi

    连续两天一直在你这里看东西,谢谢了!

    明河共影回复于 2010年07月22日 8:04

    客气了,谢谢支持。