Cover Flow Effect supported by Keyboard in Flex

music-family-win If you like Apple/iPod, I think you will like the iTunes styled "cover flow".We can do it in Flex/Flash by the Flex CoverFlow component(http://dougmccune.com/blog/2007/11/19/flex-coverflow-performance-improvement-flex-carousel-component-and-vertical-coverflow/) or isplayShelf Component (http://www.quietlyscheming.com/blog/components/tutorial-displayshelf-component/) or Flash iTunes Cover Flow (http://www.weberdesignlabs.com/blog/?p=10) etc. Following is another to do the same, keyboard support.

Search-256x256 Demo | DownloadDownload Full Project


Following is mxml source code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" creationCompleteEffect="fadeOut" viewSourceURL="srcview/index.html">
	<mx:Script>
		<![CDATA[
			import mx.states.AddChild;
			import mx.controls.Image;
			import mx.controls.Alert;
			import mx.events.*;
			import keymet.effect.SleekMove;
			import mx.effects.easing.*;

			public var img:Array;
			public var sm:SleekMove;
			function init():void
			{
				var i:int;
				var tmp:Image;
				img = new Array();
				foc.setFocus();
				for (i= 0; i<= 9 ;i++)
				{
					tmp = new Image();
					tmp.source= "pic/p"+(i+1).toString()+".jpg";
					img[i] = tmp;
					addChild(img[i]);
				}
				addEventListener(KeyboardEvent.KEY_UP,keyup);
				/* create cover flow effect object */
				sm = new SleekMove();
				/* init object:
				function init(img:Array,imgW:int,imgH:int,imgSpace:int=50,offsetX:int=0,offsetY:int=0,zoomInPer:Number=.6):void
				img Image object array
				imgH image's height
				imgW image's width
				imgSpace
				offsetX
				offsetY
				zoomInPer
				*/
				sm.init(img,160,200,30,100,200,0.7);
			}
			function keyup(event:KeyboardEvent):void{
				if (event.keyCode == 37)
					sm.pressLeft();
				if (event.keyCode == 39)
					sm.pressRight();
			}

			function keysel():void
			{
				Alert.show(sm.getSelected().toString());
			}
		]]>
	</mx:Script>
	<mx:Fade id="fadeOut" duration="1000" alphaFrom="0" alphaTo="1"/>

	<mx:Button id="foc" x="232" y="495" label="GetSelected" click="keysel()"/>

</mx:Application>

Following is as source code:

package keymet.effect
{
	import mx.controls.Image;
	import mx.events.EffectEvent;
	import mx.effects.easing.*;

	public class SleekMove
	{
		import mx.controls.Alert;
		import mx.effects.*;

		private var imgW:int;
		private var imgH:int;
		private var imgSpace:int;
		private var offsetX:int;
		private var offsetY:int;
		private var zoomInPer:Number;
		private var img:Array;
		private var total:int;
		private var cur5:Array;
		private var x5:Array;
		private var y5:Array;
		private var yOffsetDiv:int;
		private var curIndex:int = 0;
		public function SleekMove()
		{

		}

		public function init(img:Array,imgW:int,imgH:int,imgSpace:int=50,offsetX:int=0,offsetY:int=0,zoomInPer:Number=.6):void
		{
			this.img = img;
			this.imgW = imgW;
			this.imgH = imgH;
			this.imgSpace = imgSpace;
			this.offsetX = offsetX;
			this.offsetY = offsetY;
			this.zoomInPer = zoomInPer;
			total = img.length;
			cur5 = new Array(5);
			//Alert.show(img.length.toString());
			caleXY();
			putImgArray();
			createEffect();
		}
		private function caleXY():void
		{
			yOffsetDiv = int((imgH - int(imgH*zoomInPer))/2);

			x5 = new Array(5);
			y5 = new Array(5);
			x5[0] = offsetX;
			x5[1] = x5[0] + int(imgW*zoomInPer) + imgSpace;
			x5[2] = x5[1] + int(imgW*zoomInPer) + imgSpace;
			x5[3] = x5[2] + imgW + imgSpace;
			x5[4] = x5[3] + int(imgW*zoomInPer) + imgSpace;

			y5[0] = offsetY;
			y5[1] = offsetY;
			y5[2] = offsetY - yOffsetDiv;
			y5[3] = offsetY;
			y5[4] = offsetY;
		}

		private function putImgArray():void
		{
			var i:int;
			var tmp:Image;
			for (i =0 ;i < total;i++)
			{
				tmp = img[i] as Image;
				tmp.width = imgW;
				tmp.height = imgH;
				tmp.scaleX = zoomInPer;
				tmp.scaleY = zoomInPer;
				tmp.visible = false;
			}

			for (i =0 ;i < 5;i++)
			{
				cur5[i] = img[i];
				tmp = cur5[i] as Image;
				tmp.x = x5[i];
				tmp.y = y5[i];
				if (i == 2)
				{
					tmp.scaleX = 1;
					tmp.scaleY = 1;
				}
				tmp.visible = true;
			}

		}
		private var duration:int = 1000;
		private var par_left:Parallel;
		private var move_left1:Move;
		private var move_left2:Move;
		private var move_left3:Move;
		private var par_right:Parallel;
		private var move_right1:Move;
		private var move_right2:Move;
		private var move_right3:Move;
		private var fadein:Fade;
		private var fadeout:Fade;
		private var apinX:AnimateProperty;
		private var apinY:AnimateProperty;
		private var apoutX:AnimateProperty;
		private var apoutY:AnimateProperty;
		private var stateInEffect:Boolean = false;
		public function createEffect():void
		{
			move_left1 = new Move();
			move_left1.xBy = -1 * (imgSpace + imgW * zoomInPer);
			move_left1.duration = duration;
			move_left2 = new Move();
			move_left2.xBy = -1 * (imgSpace + imgW * zoomInPer);
			move_left2.yBy = yOffsetDiv;
			move_left2.duration = duration;
			move_left3 = new Move();
			move_left3.xBy = -1 * (imgSpace + imgW);
			move_left3.yBy = -1 * yOffsetDiv;
			move_left3.duration = duration;

			fadein = new Fade();
			fadein.alphaFrom = 0.0;
			fadein.alphaTo = 1.0;
			fadein.duration = duration;

			fadeout = new Fade();
			fadeout.alphaFrom = 1.0;
			fadeout.alphaTo = 0.0;
			fadeout.duration = duration;

			apinX = new AnimateProperty();
			apinX.property = "scaleX";
			apinX.fromValue = 1.0;
			apinX.toValue = zoomInPer;

			apinY = new AnimateProperty();
			apinY.property = "scaleY";
			apinY.fromValue = 1.0;
			apinY.toValue = zoomInPer;

			apoutX = new AnimateProperty();
			apoutX.property = "scaleX";
			apoutX.fromValue = zoomInPer;
			apoutX.toValue = 1.0;

			apoutY = new AnimateProperty();
			apoutY.property = "scaleY";
			apoutY.fromValue = zoomInPer;
			apoutY.toValue = 1.0;

			par_left = new Parallel();
			par_left.addChild(move_left1);
			par_left.addChild(move_left2);
			par_left.addChild(move_left3);
			par_left.addChild(fadeout);
			par_left.addChild(fadein);
			par_left.addChild(apinX);
			par_left.addChild(apinY);
			par_left.addChild(apoutX);
			par_left.addChild(apoutY);

			move_right1 = new Move();
			move_right1.xBy = imgSpace + imgW * zoomInPer;
			move_right1.duration = duration;
			move_right2 = new Move();
			move_right2.xBy = imgSpace + imgW;
			move_right2.yBy = yOffsetDiv;
			move_right2.duration = duration;
			move_right3 = new Move();
			move_right3.xBy = imgSpace + imgW * zoomInPer;
			move_right3.yBy = -1 * yOffsetDiv;
			move_right3.duration = duration;

			par_right = new Parallel();
			par_right.addChild(move_right1);
			par_right.addChild(move_right2);
			par_right.addChild(move_right3);
			par_right.addChild(fadeout);
			par_right.addChild(fadein);
			par_right.addChild(apinX);
			par_right.addChild(apinY);
			par_right.addChild(apoutX);
			par_right.addChild(apoutY);

			par_left.addEventListener(EffectEvent.EFFECT_START,effect_start);
			par_left.addEventListener(EffectEvent.EFFECT_END,effect_end);
			par_right.addEventListener(EffectEvent.EFFECT_START,effect_start);
			par_right.addEventListener(EffectEvent.EFFECT_END,effect_end);
		}

		private function effect_start(event:EffectEvent):void
		{
			stateInEffect = true;
		}
		private function effect_end(event:EffectEvent):void
		{
			stateInEffect = false;
		}

		private function getCycIndex(indexadd:int):int
		{
			var tmp:int;
			if (indexadd >= total)
				return indexadd%total;
			tmp = indexadd;
			while(tmp < 0)
				tmp += total;
			return tmp;
		}

		private function updateCur5():void
		{
			var i:int;
			for (i = 0; i < 5; i++)
			{
				cur5[i] = img[getCycIndex(curIndex + i)];
			}
		}
		private function putLeftEffectBeforeAction():void
		{
			var newimg:Image = img[getCycIndex(curIndex + 5)];
			newimg.visible = true;
			//Alert.show(getCycIndex(curIndex + 5).toString());
			fadeout.target = cur5[0];
			move_left1.targets = new Array(cur5[1],cur5[4]);
			move_left2.target = cur5[2];
			move_left3.target = cur5[3];
			fadein.target = newimg;
			newimg.x = x5[4];
			newimg.y = y5[4];
			apinX.target = cur5[2];
			apinY.target = cur5[2];
			apoutX.target = cur5[3];
			apoutY.target = cur5[3];
		}

		private function putRightEffectBeforeAction():void
		{
			var newimg:Image = img[getCycIndex(curIndex - 1)];
			newimg.visible = true;
			fadeout.target = cur5[4];
			move_right1.targets = new Array(cur5[0],cur5[3]);
			move_right2.target = cur5[2];
			move_right3.target = cur5[1];
			fadein.target = newimg;
			newimg.x = x5[0];
			newimg.y = y5[0];
			apinX.target = cur5[2];
			apinY.target = cur5[2];
			apoutX.target = cur5[1];
			apoutY.target = cur5[1];
		}

		public function pressLeft():void
		{
			if (stateInEffect)
				return;
			putLeftEffectBeforeAction();
			curIndex = getCycIndex(curIndex + 1);
			par_left.play();
			updateCur5();
		}
		public function pressRight():void
		{
			if (stateInEffect)
				return;
			putRightEffectBeforeAction();
			curIndex = getCycIndex(curIndex - 1);
			par_right.play();
			updateCur5();
		}

		public function getSelected():int
		{
			return getCycIndex(curIndex + 2);
		}

		public function setEasingFun(val:Function):void
		{
			move_left1.easingFunction = val;
			move_left2.easingFunction = val;
			move_left3.easingFunction = val;
			move_right1.easingFunction = val;
			move_right2.easingFunction = val;
			move_right3.easingFunction = val;
		}
	}
}
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • Reddit
  • Technorati
  • StumbleUpon
  • Twitter
RSS Enjoy this Post? Subscribe to Ntt.cc

RSS Feed   RSS Feed     Email Feed  Email Feed Follow us Follow us
You can leave a response, or trackback from your own site.

9 Responses to “Cover Flow Effect supported by Keyboard in Flex”

  1. hi… you have dead links on Demo and Download Project..

    just to inform! :)

    Congrats to the blog, it’s my mandatory stop on ria’s subject !

  2. Ntt.cc says:

    Thanks, Mário Santos
    It seems some data were lost when Godaddy update my hosting account.
    I will fixed it later.
    Thanks again, Mário Santos. :)

  3. [...] 在Cover Flow Effect supported by Keyboard in Flex中介绍过翻转效果的实现,lemlinh.com发布了一款更加Cool的Flash模板,非常实用。有兴趣地可以看看。 [...]

  4. [...] “FishEye”和“cover flow”貌似会搅和在一起,让人头晕。。。当然,还有时候我们称之为“Dock Menu”……反正不管怎么称呼,就是这么一种效果。在Cover Flow Effect supported by Keyboard in Flex中我们可以看到如何用键盘来实现这种移动的效果。而在利用ComponentOne组件快速实现鱼眼菜单(Dock Menu)中,我们也可以看到利用ComponentOne来实现。下面是另外一款类似的组件,不同的是它还可以实现1D,2D的效果。让人感觉有立体感。 [...]

  5. [...] Flow” or “Dock Menu”. Ok, no matter what you call it, it is just a effect. In Cover Flow Effect supported by Keyboard in Flex we knew how to realize the move effect by keyboard. In Create Fish Eye Menu Fastly by ComponentOne [...]

  6. [...] 所谓的Crousel效果,其实就是控制图片在图片集中旋转。和我们前面介绍的Cover Flow Effect supported by Keyboard in Flex,一款很Cool的Fisheye组件以及利用ComponentOne组件快速实现鱼眼菜单(Dock Menu)都比较类似。不过下面的代码,不仅可以横向转动,还可以是竖直方向的。下面是Demo和代码: [...]

  7. [...] This function maybe is similar with these which have been introduced in following articles  Cover Flow Effect supported by Keyboard in Flex, A So Cool Fisheye Component,Create Fish Eye Menu Fastly by ComponentOne. But it could rotate not [...]

  8. runbao says:

    This is good!
    Thanks to share!

  9. amosta says:

    Hi, very nice effect – and unobtrusive – and I recommend a photoeffect application with cool features.

Leave a Reply