flash特效原理 图片切换滚动

               

  

今天,我们来试玩一样东西,这个东西叫图片切换滚动,其实贴切一点应该叫图片轮播。时下图片轮播作为web方面在各大网站已经非常流行,这种图片轮播非常经典,前段时间花了两天写了像一个QQ视频网站看到的效果。

  参考效果地址:http://v.qq.com/music/index.html

 

  要想玩,但是我比较懒,所以在分解他们效果的时候,顺便查询网站里面一个xml里面的数据,只是为了演示作用,故此只是借用了他们的xml数据内容。

  查看:http://v.qq.com/music/pic.xml 里面的xml信息可以查看到里面图片和描述 以及一些视频地址链接。我们只是需要获取到里面数据并进行分析保存起来。

   <?xml version="1.0" encoding="UTF-8" ?> - <root>- <item>  <sid>0</sid>   <bpurl>/video/play.html?vid=s0090IljcFW</bpurl>   <url>http://imgcache.qq.com/qqlive/images/i1305516206_1.jpg</url>   <link>/video/play.html?vid=s0090IljcFW</link> - <title>- <!--[CDATA[ 刘惜君《怎么唱情歌》MV首播  ]]>   </title>- <subtitle>- <![CDATA[ “透明系女生”身陷两大型男无法自拔!  ]]>   </subtitle>  </item>- <item>  <sid>1</sid>   <bpurl>/video/play.html?vid=A0090V89apA</bpurl>   <url>http://imgcache.qq.com/qqlive/images/i1305195532_1.jpg</url>   <link>/video/play.html?vid=A0090V89apA</link> - <title>- <![CDATA[ 震撼有力!2NE1新MV《lonely》  ]]>   </title>- <subtitle>- <![CDATA[ 韩国女子天团回归,柔美单曲给炎炎夏日带来一丝清凉!  ]]>   </subtitle>  </item>- <item>  <sid>2</sid>   <bpurl>/video/play.html?vid=M0090YAejKV</bpurl>   <url>http://imgcache.qq.com/qqlive/images/i1305026066_1.jpg</url>   <link>/video/play.html?vid=M0090YAejKV</link> - <title>- <![CDATA[ 谢娜自导自演最新MV震撼出炉  ]]>   </title>- <subtitle>- <![CDATA[ 青春动力、活泼立志,最新MV《蓝色巧克力》俏皮来袭!  ]]>   </subtitle>  </item>- <item>  <sid>3</sid>   <bpurl>/video/play.html?vid=X0090zlLq5P</bpurl>   <url>http://imgcache.qq.com/qqlive/images/i1305006822_1.jpg</url>   <link>/video/play.html?vid=X0090zlLq5P</link> - <title>- <![CDATA[ 终极挑逗!辣妹蕾哈娜最新MV  ]]>   </title>- <subtitle>- <![CDATA[ 全新时尚大片,带你领略加州绝美风光…  ]]>   </subtitle>  </item>- <item>  <sid>4</sid>   <bpurl>/video/play.html?vid=p0090sSzkSC</bpurl>   <url>http://imgcache.qq.com/qqlive/images/i1305014875_1.jpg</url>   <link>/video/play.html?vid=p0090sSzkSC</link> - <title>- <![CDATA[ 郭富城章子怡:《最爱》主题曲  ]]>   </title>- <subtitle>- <![CDATA[ 顾长卫新片主题曲《一直都在》首度曝光,感动上映!  ]]-->   </subtitle>  </item>  </root>

主类执行:

调用URLLoader 类对其xml 进行读取,读取完毕后,把数据转至photoItem 类,把需要的数据设置一下,如链接,图片地址,和文字描述。 在设置图片位置的时候,记录他们位置,以便在时间间隔调用的时候,进行切换下一个位置。

轮播当中需要工作:使用时间调度方式让图片进行轮播,

                           点击图片的时候可以进行轮播

                           点击中间图片的时候跳转到相应的链接处

                           切换图片时候 需要对图片进行暗处理,并隐藏主要文字

                           切换位置的时候,使用TweenLite进行轮播到下一个位置,

                           判断左右切换的方向。

                           深度排序

                           初始化图片的时候记录初始位置

                           

                                          

流程:

         加载xml数据-->实例化效果-->实例化图片元件,并赋予数据--->进行时间调度切换

当中交互里面,经常涉及到左右两只切换的方式,这两种方式使用频率比较高,在coverFlow 和一些轮播当中使用制作需要解决这两种交互的做法。

  制作这个效果之前,当时参考了双链表的方式来制作,但是在制作的时候,双链表并没有完全满足个人需求,于是采用循环链表来替代制作,这种结构对付这种效果十分有意思,借助队列思想 和链表当中思维结合, 可以帮助我们解决实际上一些交互的难题。

 

package { import flash.display.Sprite; import flash.events.*; import flash.net.URLLoader; import flash.net.URLRequest; import flash.display.StageAlign; import flash.display.StageScaleMode;  import org.summerTree.utils.XMLManager; import org.summerTree.effect.FollowEffect; import org.summerTree.model.Photoparam; public class Main extends Sprite {  private var dataPath:String = "http://v.qq.com/music/pic.xml";  private var effect:FollowEffect;  public function Main()  {   if (stage)   {    initData();   }   else   {    addEventListener(Event.ADDED_TO_STAGE,initData);   }  }  private function initData(event:Event=null):void  {   stage.align = StageAlign.TOP_LEFT;   stage.scaleMode = StageScaleMode.NO_SCALE;   //加载xml    var loader:URLLoader=new URLLoader();   loader.addEventListener(Event.COMPLETE,onLoadDataCompleteHandler);   loader.addEventListener(IOErrorEvent.IO_ERROR,onLoadDataErrorHandler);   loader.load(new URLRequest(dataPath));  }  private function onLoadDataCompleteHandler(event:Event):void  {   event.currentTarget.removeEventListener(Event.COMPLETE,onLoadDataCompleteHandler);   event.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR,onLoadDataErrorHandler);   var xmlData:* = event.currentTarget.data;      effect=new FollowEffect();   effect.targetPointNumber = 2;   effect.initData(XMLManager.getXMLData(xmlData));   effect.addEventListener(Event.COMPLETE,onLoadCompleteHandler);  }    private function onLoadDataErrorHandler(event:IOErrorEvent):void  {   trace("数据加载失败了");  }    private function onLoadCompleteHandler(event:Event):void  {   effect.removeEventListener(Event.COMPLETE,onLoadCompleteHandler);   var n:int = 0;   var len:int = effect.photoLength;   //设置好队列顺序。   for (var i:int=0; i<len; i++)   {    effect.getPhotoItem(i).x = stage.stageWidth / 2 - (2 - i) * effect.getPhotoItem(i).width / 2;    effect.getPhotoItem(i).y = stage.stageHeight / 2;    effect.getPhotoItem(i).scaleX=effect.getPhotoItem(i).scaleY=1-Math.abs(2-i)*0.2;    if (i!=2)    {     effect.photoList[i].data.isTextVisible = false;    }    effect.setParameters(new Photoparam(effect.getPhotoItem(i).x,effect.getPhotoItem(i).scaleX));   }   effect.sortZ();   addChild(effect);   effect.startMotion();  } }}

图片元件:记录xml 当中描述,设置图片地址,和图片显示。id是图片标记

package org.summerTree.display{ import flash.display.Sprite; import flash.display.Loader; import flash.events.Event; import flash.events.IOErrorEvent; import flash.net.URLRequest; import flash.system.LoaderContext; import flash.display.Bitmap; import flash.display.Shape; import flash.filters.GlowFilter; import flash.text.TextField; import flash.text.TextFormat; import flash.text.TextFieldAutoSize; import flash.geom.Point; public class PhotoItem extends Sprite {  private var loader:Loader;  private var title:String;  private var bitmap:Bitmap;  private var link:String; //点击链接  private var _isTextVisible:Boolean;  private var photoContain:Sprite=new Sprite();//图片容器  private var bigTitle:TextField;  private var blackMask:Shape; //黑色背景  public var id:int;   public var level:int;//深度  public var isClick:Boolean = false;//是否允许点击  public var positionXY:Point;//记录开始的默认位置值  public function PhotoItem(url:String)  {   this.buttonMode = true;   loader=new Loader();   loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadImageCompleteHandler);   loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onIOErrorHandler);   loader.load(new URLRequest(url),new LoaderContext(true));  }  private function onLoadImageCompleteHandler(event:Event):void  {   loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,onLoadImageCompleteHandler);   loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,onIOErrorHandler);   bitmap = Bitmap(event.currentTarget.content);   addChild(photoContain);   photoContain.x =  -  bitmap.width / 2;   photoContain.y =  -  bitmap.height / 2;   photoContain.addChild(bitmap);   drawBaseBottom(bitmap.width,bitmap.height);   blackMask=new Shape();   setTextDescription();   photoContain.addChild(blackMask);   this.dispatchEvent(new Event(Event.COMPLETE));  }  private function onIOErrorHandler(event:IOErrorEvent):void  {   trace("错误了");  }  private function drawBaseBottom(width:Number,height:Number):void  {   var shape:Shape=new Shape();   shape.graphics.beginFill(0xCCCCCC);   shape.graphics.drawRect(-5,-5,width+10,height+10);   shape.graphics.endFill();   shape.filters = [new GlowFilter(0x999999,0.3)];   photoContain.addChildAt(shape,0);  }  //设置文本信息  public function setText(info:String):void  {   title = info;   addEventListener(Event.ENTER_FRAME,render);  }  //设置图片链接  public function set imageUrl(value:String):void  {   this.link = value;  }  public function get imageUrl():String  {   return this.link;  }  //设置文本是否可见  public function set isTextVisible(value:Boolean):void  {   this._isTextVisible = value;   photoContain.getChildAt(2).visible = value;   blackMask.graphics.clear();   if (value)   {    blackMask.graphics.clear();   }   else   {    blackMask.graphics.beginFill(0x333333,0.5);    blackMask.graphics.drawRect(0,0,bitmap.width,bitmap.height);    blackMask.graphics.endFill();   }  }  public function get isTextVisible():Boolean  {   return this._isTextVisible;  }  private function render(event:Event):void  {   if (bitmap)   {    removeEventListener(Event.ENTER_FRAME,render);    bigTitle.text = title;   }  }  private function setTextDescription():void  {   var contain:Sprite=new Sprite();   contain.graphics.beginFill(0x000000,0.5);   contain.graphics.drawRect(0,0,bitmap.width,bitmap.height/4);   contain.graphics.endFill();   photoContain.addChild(contain);   var button:PlayButton = new PlayButton(40,40);   contain.addChild(button);   button.x = 8;   button.y = 10;   contain.y = bitmap.height - contain.height;   bigTitle=new TextField();   bigTitle.defaultTextFormat = new TextFormat("黑体",12,0xffffff);   bigTitle.multiline = true;   bigTitle.autoSize = TextFieldAutoSize.LEFT;   bigTitle.mouseEnabled = false;   bigTitle.text = title;   bigTitle.x = 60;   bigTitle.y = contain.height - bigTitle.textHeight - 15;   contain.addChild(bigTitle);   blackMask.graphics.clear();  } }}

播放按钮图标:使用绘图api绘制

package org.summerTree.display{ import flash.display.Sprite;   public class PlayButton extends Sprite {    public function PlayButton(width:Number,height:Number)  {   this.graphics.beginFill(0x333333,0.5);   this.graphics.drawRoundRect(0,0,width,height,5,5);   this.graphics.endFill();      this.graphics.lineStyle(2,0xffffff,0.5);   this.graphics.drawRoundRect(-1,-1,width+2,height+2,5,5);     this.graphics.beginFill(0xffffff,0.5);   this.graphics.moveTo(width/3,height/3);   this.graphics.lineTo(width/3,height*0.7);   this.graphics.lineTo(width-width/3,height/2);   this.graphics.lineTo(width/3,height/3);   this.graphics.endFill();        }     }  }

交互当中常用接口:

package org.summerTree.effect{  //常见左右交互当中的使用的接口 public interface IEffect {  function next():void;  function preview():void;   }  }

轮播效果主实现方法:当中使用了循环链表。

让其实现左右切换的交互。

package org.summerTree.effect{ import flash.display.Sprite; import flash.utils.Timer; import flash.events.TimerEvent; import flash.events.MouseEvent; import flash.net.navigateToURL; import flash.net.URLRequest; import flash.events.*; import org.summerTree.display.PhotoItem; import org.summerTree.datastruct.CLinkedList; import org.summerTree.datastruct.DLinkNode; import org.summerTree.model.Photoparam; import org.summerTree.utils.Config; import com.greensock.TweenLite; import flash.geom.Point; public class FollowEffect extends Sprite implements IEffect {    public  var  timeInterval:Number = 5000;//每隔一段时间播放j间隔  private var  timer:Timer;  private var  currentTargetPhoto:PhotoItem;//当前的图片  private var  isCurrentPage:Boolean = false;  private var  nodeList:CLinkedList=new CLinkedList();  private var  photoNums:int = 0;//图片数目    public  var targetPointNumber:int;//目标放大点  private var parameters:Array = [];//保存路径  public  var motionDirection:String="right";//运动方向    public static const RIGHT:String="right";  public static const LEFT:String="left";    public function FollowEffect()  {  }  public function initData(data:Array):void  {   if (data.length == 0)   {    return;   }   var len:int = data.length;   photoNums = len;   for (var i:int=0; i<len; i++)   {    var photoItem:PhotoItem = new PhotoItem(data[i].url);    photoItem.addEventListener(Event.COMPLETE,onLoadImageCompleteHandler);    photoItem.addEventListener(MouseEvent.CLICK,onGotoPage);        if (data[i].link.indexOf(Config.domain) == -1)    {     data[i].link = "http://"+Config.domain+ data[i].link;    }        photoItem.setText(data[i].title);    photoItem.imageUrl = data[i].link;    photoItem.id = i;    addChild(photoItem);    nodeList.appendNode(photoItem);   }   currentTargetPhoto = nodeList.nodeList[1].data;   addEventListener(MouseEvent.ROLL_OVER,onMotionHandler);   addEventListener(MouseEvent.ROLL_OUT, onMotionHandler);  }  private function onLoadImageCompleteHandler(event:Event):void  {   event.currentTarget.removeEventListener(Event.COMPLETE,onLoadImageCompleteHandler);   photoNums--;   if (photoNums==0)   {    this.dispatchEvent(new Event(Event.COMPLETE));   }  }  private function onGotoPage(event:MouseEvent):void  {   if (PhotoItem(event.currentTarget).isClick)   {    navigateToURL(new URLRequest(event.currentTarget.imageUrl));   }   else   {    flow(PhotoItem(event.currentTarget));   }  }        private function onMotionHandler(event:MouseEvent):void  {   if(event.type==MouseEvent.ROLL_OVER)   {    stopMotion();   }   else   {    startMotion();   }     }        //开始运动  public function startMotion():void  {   if(timer==null)   {    timer = new Timer(timeInterval);    timer.addEventListener(TimerEvent.TIMER,onTimerHandler);    timer.start();   }   else   {      timer.start();   }     }  //停止运动  public function stopMotion():void  {   timer.stop();  }  private function onTimerHandler(event:TimerEvent):void  {   if(motionDirection=="right")   {    next();   }   else if(motionDirection=="left")    {     preview();    }  }           //获取图片列表  public function get photoList():Array  {   return nodeList.nodeList;  }    //获取图片列表长度  public function get photoLength():int  {   return nodeList.nodeList.length;  }    //获取图片单项  public function getPhotoItem(index:int):PhotoItem  {   return nodeList.nodeList[index].data;  }    //添加基本图片参数  public function setParameters(value:Photoparam):void  {   parameters.push(value);  }        //设置时间间隔        public function setTimeInterval(value:Number):void  {   timeInterval=value;  }    //设置运动方向  public function setMotionDirection(value:String):void  {   motionDirection=value;  }      //左右的交互切换过程  public function flow(target:PhotoItem):void  {   currentTargetPhoto = target;   //判断左右   if (target.id > targetPointNumber)   {    walkLeft();   }   else if (target.id<targetPointNumber && target.id!=targetPointNumber)   {       walkRight();   }   sortZ();  }  //左方向交互  public function preview():void  {   if (nodeList.nodeOf(currentTargetPhoto).nextNode != null)   {    currentTargetPhoto = nodeList.nodeOf(currentTargetPhoto).nextNode.data as PhotoItem;    flow(currentTargetPhoto);   }  }  //右方向交互  public function next():void  {   if (nodeList.nodeOf(currentTargetPhoto).preNode != null)   {    currentTargetPhoto = nodeList.nodeOf(currentTargetPhoto).preNode.data as PhotoItem;    flow(currentTargetPhoto);   }  }    private function walkLeft():void  {   var len:int = nodeList.nodeList.length;   var n:int = 0;   var temp:int = 0;   var index:int = 0;   for (var i:int=len-1; i>-1; i--)   {    if (i==len-1)    {     temp = nodeList.nodeList[i].data.id;    }    if (i==0)    {     n = len - 1;     nodeList.nodeList[i].data.id = temp;         }    else    {     n = i - 1;     nodeList.nodeList[i].data.id = nodeList.nodeList[n].data.id;    }    index = nodeList.nodeList[i].data.id;        if (currentTargetPhoto!=nodeList.nodeList[i].data)    {     nodeList.nodeList[i].data.isClick = false;    }    if (nodeList.nodeList[i].data.id != targetPointNumber)    {     nodeList.nodeList[i].data.isTextVisible = false;     nodeList.nodeList[i].data.isClick = false;    }    else    {     nodeList.nodeList[i].data.isTextVisible = true;     nodeList.nodeList[i].data.isClick = true;    }    TweenLite.to(nodeList.nodeList[i].data,0.5,{x:parameters[index].x,scaleX:parameters[index].scale,scaleY:parameters[index].scale});   }  }  private function walkRight():void  {   var len:int = nodeList.nodeList.length;   var n:int = 0;   var temp:int = 0;   var index:int = 0;   for (var i:int=0; i<len; i++)   {    if (i==0)    {     temp = nodeList.nodeList[i].data.id;    }    if (i==len-1)    {     n = 0;     nodeList.nodeList[i].data.id = temp;    }    else    {     n = i + 1;     nodeList.nodeList[i].data.id = nodeList.nodeList[n].data.id;    }    index = nodeList.nodeList[i].data.id;    if (currentTargetPhoto!=nodeList.nodeList[i].data)    {     nodeList.nodeList[i].data.isClick = false;    }    if (nodeList.nodeList[i].data.id != targetPointNumber)    {     nodeList.nodeList[i].data.isTextVisible = false;     nodeList.nodeList[i].data.isClick = false;    }    else    {     nodeList.nodeList[i].data.isTextVisible = true;     nodeList.nodeList[i].data.isClick = true;    }    TweenLite.to(nodeList.nodeList[i].data,0.5,{x:parameters[index].x,scaleX:parameters[index].scale,scaleY:parameters[index].scale});   }  }  //深度排序()  public function sortZ():void  {   var n:int = 0;   while (n<this.numChildren)   {    var index:int = nodeList.nodeList[n].data.id;    if (index<targetPointNumber)    {     this.setChildIndex(nodeList.nodeList[n].data,index);    }    else if (index==targetPointNumber)    {     this.setChildIndex(nodeList.nodeList[n].data,this.numChildren-1);    }    else if (index>targetPointNumber && index!=this.numChildren-1)    {     this.setChildIndex(nodeList.nodeList[n].data,index);    }    else if (index==this.numChildren-1)    {     this.setChildIndex(nodeList.nodeList[n].data,targetPointNumber);    }    n++;   }  }     }}

获取xml 数据:

package org.summerTree.utils{ public class XMLManager {      //获取xml ,返回xml的数据  public static function  getXMLData(data:String):Array  {   var array:Array=[];   var xml:XML=null;      try{      xml=new XML(data);     }     catch(e:Error)    {    trace("数据发生了错误了");    }      if(xml==null) return array;      xml.ignoreWhitespace = true;        var itemList:XMLList = xml..item;            var len:int= itemList.length();      for(var i:int=0;i<len;i++)   {    var sonXML:XMLList=itemList[i].children();        var dataObject:Object={};    var nodeLen:int=sonXML.length();//节点长度        for(var j:int=0;j<nodeLen;j++)    {     var name:String = itemList[i].children()[j].name().toString();                         var value:* = itemList[i].children()[j].toString();       dataObject[name]=value;        }    array.push(dataObject);   }        return array;  } } }

配置文件

package org.summerTree.utils{  public class Config {  public static var domain:String="v.qq.com";   } }

循环链表使用:

package org.summerTree.datastruct{ import org.summerTree.datastruct.DLinkNode; public class CLinkedList {  private var _size:int = 0;  public var head:DLinkNode = null;//头节点  public var tail:DLinkNode = null;//尾节点  private var first:DLinkNode=null;  private var last:DLinkNode=null;  private var NodeList:Array=[];  public function CLinkedList()  {  }  //插入节点  public function appendNode(obj: * ):void  {   var newNode:DLinkNode = new DLinkNode(obj);   if (this.isEmpty())   {    head = newNode;   }   else   {    tail.nextNode = newNode;    newNode.preNode = tail;        newNode.nextNode=head;    head.preNode=newNode;       }   tail = newNode;   _size++;   NodeList.push(newNode);  }  //搜索当前节点  public function nodeOf(obj: * ):DLinkNode  {         var len:int=NodeList.length;   for(var i:int=0;i<len;i++)      {    if(NodeList[i].data==obj)    {     return NodeList[i];    }       }      return null;  }  //判断是否空链表  public function isEmpty():Boolean  {   return size == 0;  }          //返回节点数   public function get size():int  {   return _size;  }    public function get nodeList():Array  {   return NodeList;  }   }}

节点:

package org.summerTree.datastruct{ public class DLinkNode {  public var data:*;  public var preNode:DLinkNode;  public var nextNode:DLinkNode;  public function DLinkNode(obj:*)  {   preNode = nextNode = null;   data = obj;  } }}

 记录他们参数

 package org.summerTree.model{ //记录图片的位置和缩放信息 public class Photoparam {  public  var x:Number;  public  var scale:Number;  public function Photoparam(x:Number,scale:Number)  {   this.x=x;   this.scale=scale;  }   }}

除了这个之后,我们可以观看到百度视频当中的,也有这种flash制作,他们的特点是实用,替换数据方便,显示效果也比较有意思。

不妨去参考他们的swf 来尝试制作一个属于自己轮播效果。

 http://video.baidu.com/hd/index/

 

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

猜你喜欢

转载自blog.csdn.net/truhfcg/article/details/86592225
今日推荐