今晚抽点时间记录一下coverFlow效果。前几天修改了一个coverFlow的效果的代码。看到coverFlow效果有一种比较有趣的思路去制作。
在创造这个特效过程当中,所涉及到一些类包含缓冲类,包括倒影类,同时也可以使用一种数据结构来实现左右移动的时候变化,思路可以借鉴一下。
在这里大概讲解一下制作过程。
制作原理:我们可以看到图片都在Y轴都偏移了一定的角度,并且每一张图片都保持一定的距离。在交互的时候,中间的图片会进行滑行放大,由原来的偏移角度从(angle-->0)进行变化,并且在位置上都移动到另外一个位置。(x1-->x2)所以在这个动画过程当中,有两个属性发生变化了。
(角度--->0)
(位置X-->变化到另外一个位置)
在每次点击一张图片,那么这张图片如果在目标图片的左边,那么左边所有图片(photo1,photo2....)会向右进行位置移动
如果在目标图片的右边,那么左边所有图片(photo5,photo6....)会向左进行位置移动
懂了这个我们可以尝试制作一下。
一。图形的线性分布
我们首先会依据这些图片按一定间距进行分布,这样看起来就像一条线。随后,我们将下面的图片按一定角度Y轴进行偏移,这样就能像coverflow的效果。看起来会有一点摸样了。
二 交互
在flash 交互过程当中,图片进行滑动并且将原先的偏移的角度变化到一个角度。在这个过程当中,我们使用缓冲的类产生这个过程。
一方面改变这种偏移角度变化,一方面改变位置变化,在这个过程当中你会发现你点击的图片,和其他图片都会发生改变移动,这也是这个交互比较有趣的地方,我们可以通过循环检测目标图片左边的图片和右边的图片。并让其发生改变。那么这个交互就已经可以把握到了。
如:
A1 A2 A3(目标图片)B1 B2 B3
package { import flash.display.*; import flash.net.*; import flash.events.*; import org.summerTree.effect.CoverFlow; import org.summerTree.effect.Image; import org.summerTree.effect.Reflection; public class Main extends Sprite { private var coverflow:CoverFlow=new CoverFlow();//创建coverFlow效果类 public function Main() { coverflow.SPACING=80;//设置间距 addChild(coverflow); coverflow.move(stage.stageWidth/2,stage.stageHeight/2); coverflow.addEventListener(Event.COMPLETE,onLoadCompleteHandler); coverflow.loadImage("image/0.jpg","image/1.jpg","image/2.jpg", "image/3.jpg","image/4.jpg", "image/5.jpg","image/6.jpg", "image/7.jpg","image/8.jpg", "image/9.jpg","image/10.jpg" ); //加载图片 } private function onLoadCompleteHandler(event:Event):void { coverflow.removeEventListener(Event.COMPLETE,onLoadCompleteHandler); creatSprite(coverflow.imageArray); coverflow.addListener();//添加左右按键 } //创建图形 private function creatSprite(array:Array):void { var n:int=array.length; for (var i:int=0; i<n; i++) { var image:Image=array[i]; var refect:Reflection=new Reflection(image,255,Reflection.CENTER,0.7,0.6);//对图片产生倒影效果 image.addEventListener(MouseEvent.CLICK,onClickHandler); coverflow.addImage(image);//添加图片 } coverflow.flow(array[int(n/2)]); } private function onClickHandler(event:MouseEvent):void { var image:Image = event.currentTarget as Image; coverflow.flow(image); } }}
CoverFlow.as
package org.summerTree.effect{ import flash.display.Sprite; import flash.events.*; import org.summerTree.datastruct.DLinkedList; import org.summerTree.datastruct.DLinkNode; import com.greensock.TweenLite; import flash.display.Loader; import flash.net.URLRequest; import flash.display.Bitmap; import flash.display.BitmapData; import flash.ui.*; public class CoverFlow extends Sprite { public var TIME:Number = 0.5;//移动响应时间 public var ROTATION_Y:Number = 60;//偏转角度 public var SPACING:Number = 100;//图片之间间隔 public var Z_FOCUS:int = -300;//z深度 private var targetImage:Image;//图片目标 private var plane:Image; private var image_size:int = 0; private var _imageArray:Array = []; private var planeList:DLinkedList = new DLinkedList(); public function CoverFlow() { } //添加图片 public function addImage(image:Image):void { planeList.appendNode(image); this.addChild(image); } //加载图片 public function loadImage(...args):void { var len:int = args.length; image_size = len; for (var i:int=0; i<len; i++) { var loader:Loader=new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadCompleteHandler); loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onErrorHandler); loader.load(new URLRequest(args[i])); } } private function onErrorHandler(event:IOErrorEvent):void { throw new Error("发生错误"); } private function onLoadCompleteHandler(event:Event):void { event.currentTarget.addEventListener(Event.COMPLETE,onLoadCompleteHandler); var image:Bitmap = event.currentTarget.content; _imageArray.push(new Image(image)); image.bitmapData.dispose(); image_size--; if (image_size == 0) { this.dispatchEvent(new Event(Event.COMPLETE)); } } public function get imageArray():Array { return _imageArray; } public function move(x:Number,y:Number):void { this.x = x; this.y = y; } //监听鼠标和键盘监听 public function addListener():void { stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDownHandler); stage.addEventListener(MouseEvent.MOUSE_WHEEL,onWheelHandler); } //跟随 public function flow(plane:Image):void { var xPosition:Number = 0; targetImage = plane; TweenLite.to(plane, TIME, {x:xPosition, z:Z_FOCUS, rotationY:0}); var current:DLinkNode = planeList.nodeOf(plane);//搜索当前节点 var walkLeft:DLinkNode = current.preNode; while (walkLeft) { plane = Image(walkLeft.data); xPosition -= SPACING; TweenLite.to(plane, TIME, {x:xPosition, z:0, rotationY:-ROTATION_Y}); walkLeft = walkLeft.preNode; this.setChildIndex(plane,0); } xPosition = 0; var walkRight:DLinkNode = current.nextNode; while (walkRight) { plane = Image(walkRight.data); xPosition += SPACING; TweenLite.to(plane, TIME, {x:xPosition, z:0, rotationY:ROTATION_Y}); this.setChildIndex(plane,0); walkRight = walkRight.nextNode; } } public function preview():void { if (planeList.nodeOf(targetImage).preNode != null) { plane = planeList.nodeOf(targetImage).preNode.data as Image; flow(plane); } } public function next():void { if (planeList.nodeOf(targetImage).nextNode != null) { plane = planeList.nodeOf(targetImage).nextNode.data as Image; flow(plane); } } // 左右键盘 private function onKeyDownHandler(event:KeyboardEvent):void { if (event.keyCode == Keyboard.RIGHT) { next(); } else if (event.keyCode==Keyboard.LEFT) { preview(); } } //鼠标滚动 private function onWheelHandler(event:MouseEvent):void { if (event.delta > 0) { preview(); } else { next(); } } }}
package org.summerTree.effect{ import flash.display.Sprite; import flash.display.Bitmap; import flash.display.BitmapData; public class Image extends Sprite { public var url:String; public function Image(source:*) { var bmpData:BitmapData=new BitmapData(source.width,source.height,false,0x0); bmpData.draw(source); var bitmap:Bitmap=new Bitmap(bmpData); bitmap.x-=bitmap.width/2; bitmap.y-=bitmap.height/2; addChild(bitmap); } }}
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.datastruct{ import org.summerTree.datastruct.DLinkNode; public class DLinkedList { private var _size:int = 0; public var head:DLinkNode = null;//头节点 public var tail:DLinkNode = null;//尾节点 private var NodeList:Array=[]; public function DLinkedList() { } //插入节点 public function appendNode(obj: * ):void { var newNode:DLinkNode = new DLinkNode(obj); if (this.isEmpty()) { head = newNode; } else { tail.nextNode = newNode; newNode.preNode = tail; } 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) { //break; return NodeList[i]; } } return null; } //判断是否空链表 public function isEmpty():Boolean { return size == 0; } //返回节点数 public function get size():int { return _size; } }}
package org.summerTree.effect{ //倒影类 import flash.display.*; import flash.geom.*; public class Reflection { private var reflectionContainer:DisplayObjectContainer; private var reflectionHeight:Number; private var reflectionalphaStrength:Number;//透明度 private var reflectionPercent:Number; private var offDistance:Number;//偏移距离 private var reflectionClip:Sprite; private var reflectionBMP:Bitmap;//倒影位图 private var reflectionMask:Sprite;//倒影遮罩 private var RegPointType:String;//注册点位置类型 //实现三种情况进行倒影 public static var LEFT_TOP:String="left_top"; public static var CENTER:String="center"; public static var CENTER_BOTTOM:String="center_bottom"; /* @ para reflectionContainer 倒影的容器 * @ para reflectionHeight 倒影高度 * @ para RegPointType 注册点类型,根据不同注册点位置做出相应的倒影 * @ para alphaStrength 透明度 (0-1) * @ para reflectionPercent 倒影映射的百分比 * @ para offDistance 偏移距离 */ public function Reflection(reflectionContainer:DisplayObjectContainer, reflectionHeight:Number = 255, RegPointType:String="left_top" ,alphaStrength:Number = 1, reflectionPercent:Number = -1 ,offDistance:Number=0) { this.reflectionContainer = reflectionContainer; this.reflectionHeight = reflectionHeight; this.reflectionalphaStrength = alphaStrength; this.reflectionPercent = reflectionPercent; this.RegPointType=RegPointType; this.offDistance=offDistance; CreatReflection(); addItem(); } //创建倒影 private function CreatReflection():void { reflectionClip = new Sprite();//倒影剪辑容器 reflectionMask = new Sprite();//遮罩 var bmd:BitmapData = new BitmapData(reflectionContainer.width,reflectionContainer.height,true,0xffffff); if(RegPointType==Reflection.LEFT_TOP) { bmd.draw(reflectionContainer); reflectionBMP = new Bitmap(bmd); reflectionBMP.scaleY= -1; reflectionBMP.x = 0; reflectionBMP.y = reflectionBMP.height*2+offDistance; reflectionMask.y = reflectionBMP.height+offDistance; reflectionMask.x = 0; } else if(RegPointType==Reflection.CENTER) { var matrix:Matrix=new Matrix(); matrix.tx=reflectionContainer.width/2; matrix.ty=reflectionContainer.height/2; bmd.draw( reflectionContainer,matrix); reflectionBMP = new Bitmap(bmd); reflectionBMP.scaleY= -1; reflectionBMP.x = -reflectionBMP.width/2; reflectionBMP.y = reflectionBMP.height+reflectionBMP.height/2+offDistance; reflectionMask.y = reflectionBMP.height/2+offDistance; reflectionMask.x = -reflectionBMP.width/2; } else if(RegPointType==Reflection.CENTER_BOTTOM) { var matrixB:Matrix=new Matrix(); matrixB.tx=reflectionContainer.width/2; matrixB.ty=reflectionContainer.height; bmd.draw( reflectionContainer,matrixB); reflectionBMP = new Bitmap(bmd); reflectionBMP.scaleY= -1; reflectionBMP.x = -reflectionBMP.width/2; reflectionBMP.y = reflectionBMP.height+offDistance; reflectionMask.y = 0+offDistance; reflectionMask.x = -reflectionBMP.width/2; } var fillType:String = GradientType.LINEAR; var colors:Array = [0xFFFFFF,0xFFFFFF]; var alphas:Array = [reflectionalphaStrength,0]; var ratios:Array = [0,reflectionHeight]; var matr:Matrix = new Matrix(); var matrixHeight:Number; if(reflectionPercent<=0) { matrixHeight=reflectionContainer.height; } else { matrixHeight=reflectionContainer.height*reflectionPercent; } var spreadMethod:String = SpreadMethod.PAD; matr.createGradientBox(reflectionContainer.width ,matrixHeight, 0.5*Math.PI,0, 0); reflectionMask.graphics.beginGradientFill(fillType, colors, alphas, ratios, matr, spreadMethod); reflectionMask.graphics.drawRect(0, 0, reflectionContainer.width, reflectionContainer.height); reflectionMask.graphics.endFill(); reflectionBMP.cacheAsBitmap = true; reflectionMask.cacheAsBitmap = true; reflectionBMP.mask = reflectionMask; } //添加项目 private function addItem():void { reflectionClip.addChild( reflectionBMP ); reflectionClip.addChild( reflectionMask ); reflectionContainer.addChild( reflectionClip ); } //清除倒影 public function clearAll():void { reflectionClip.removeChild( reflectionMask ); reflectionClip.removeChild( reflectionBMP ); reflectionContainer.removeChild( reflectionClip ); } }}
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.youkuaiyun.com/jiangjunshow