A Simple Papervision Coverflow

There are several great AS3 / Papervision Coverflows out there but today I set out to create one in it’s simplest form. There are no bells and whistles, just a stripped down coverflow with it’s core functionality. It’s up to you to add an XML feed, Flickr feed, or setup your images in an array and load them the way you want to. This is only meant to be a clean jumping off point.

In the download I have included 2 versions. One with left / right buttons and one without. Both versions you can select the items in the coverflow to navigate.

The heart of this coverflow app is a lot like some of the others. We need to calculate the x and rotation of the center item, left items, and right items are, then animate accordingly. This is the same way that John Dyer animates his coverflow.

for (var i:int = 0; i < planes.length; i++) 
{
	var plane:Plane = planes[i];
 
	//Each if statement will adjust these numbers as needed
	var planeX:Number = 0;
	var planeZ:Number = 20;
	var planeRotationY:Number = 0
 
	//Place  & Animate Center Item
	if (i == currentItem) 
	{
		planeZ 				= -300
 
		TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
	} 
 
	//Place & Animate Right Items
	if(i > currentItem)  
	{
		planeX 				= (i - currentItem + 1) * 120;
		planeRotationY 		= angle + 10 * (i - currentItem);
 
		TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
	}
 
	//Place & Animate Left Items
	if (i < currentItem) 
	{
		planeX 				= (currentItem - i + 1) * -120;
		planeRotationY 		= -angle - 10 * (currentItem - i);
 
		TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
	} 
}

For this simple version of coverflow you have two ways of navigating to items.

Selecting a plane to jump right to that item

plane.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, onPlaneClick);
 
protected function onPlaneClick(evt:InteractiveScene3DEvent):void 
{
	currentItem = evt.target.id;
	animate();
}

Or using left / right buttons to navigate one item at a time:

rightBtn.addEventListener(MouseEvent.CLICK, buttonClick);
leftBtn.addEventListener(MouseEvent.CLICK, buttonClick);
 
protected function buttonClick(evt:MouseEvent):void 
{
	switch (evt.target)
	{
		case rightBtn:
		currentItem ++
		break;
 
		case leftBtn:
		currentItem --;
		break;
	}
 
	//Don't allow any number lower than 0 or past max so there
	//is always a center item
 
	if (currentItem < 0)
	{
		currentItem = 0;
	}
	if (currentItem > (planes.length - 1))
	{
		currentItem = planes.length - 1;
	}
 
	//Call animation
	animate();
}

On to the full source code. This version includes the left / right buttons.

package 
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import gs.easing.Quint;
	import gs.TweenLite;
	import org.papervision3d.events.InteractiveScene3DEvent;
	import org.papervision3d.materials.BitmapFileMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.view.BasicView;
 
	/**
	 * ...
	 * @author Charlie Schulze, charlie[at]woveninteractive[dot]com
	 * Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
	 */
 
	public class Main extends BasicView 
	{
		protected var planes:Array = [];
		protected var numItems:Number = 7;
		protected var currentItem:Number = 3;
		protected var angle:Number = 25;
 
		protected var mat:BitmapFileMaterial;
		protected var rightBtn:Sprite;
		protected var leftBtn:Sprite;
 
		public function Main():void 
		{
			//Make sure that your scene is set to interactive
			super(640, 480, true, true);
 
			init();
		}
		protected function init():void 
		{
			createChildren();
			createNavigation();
			animate();
			startRendering();
		}
		protected function createChildren():void 
		{
			//Create Material
			mat 			= new BitmapFileMaterial("images/iPhone-back2.png");
			mat.smooth 		= true;
			mat.interactive = true;
			for (var i:int = 0; i < numItems; i++) 
			{
				var plane:Plane = new Plane(mat, 177, 334, 4, 4);
				planes.push(plane);
 
				//Click straight to any plane
				plane.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, onPlaneClick);
 
				//Set an id to target current item
				plane.id = i;
 
				//Add plane to the scene
				scene.addChild(plane);
			}
 
			camera.zoom = 60;
		}
 
		protected function onPlaneClick(evt:InteractiveScene3DEvent):void 
		{
			currentItem = evt.target.id;
			animate();
		}
 
		//Animate the coverflow left / right based off of currentItems
		protected function animate():void 
		{
			for (var i:int = 0; i < planes.length; i++) 
			{
				var plane:Plane = planes[i];
 
				//Each if statement will adjust these numbers as needed
				var planeX:Number = 0;
				var planeZ:Number = -50;
				var planeRotationY:Number = 0
 
				//Place  & Animate Center Item
				if (i == currentItem) 
				{
					planeZ 				= -300
 
					TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
				} 
 
				//Place & Animate Right Items
				if(i > currentItem)  
				{
					planeX 				= (i - currentItem + 1) * 120;
					planeRotationY 		= angle + 10 * (i - currentItem);
 
					TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
				}
 
				//Place & Animate Left Items
				if (i < currentItem) 
				{
					planeX 				= (currentItem - i + 1) * -120;
					planeRotationY 		= -angle - 10 * (currentItem - i);
 
					TweenLite.to(plane, 1, { rotationY:planeRotationY,x:planeX,z:planeZ, ease:Quint.easeInOut } );
				}
			}
		}
 
		/*
		 * Everything below this point is just for creating the buttons and
		 * setting button events for controlling the coverflow. 
		 */
 
		protected function createNavigation():void 
		{
			//Create / Add Buttons
			rightBtn = createButton();
			leftBtn = createButton();
 
			addChild(leftBtn);
			addChild(rightBtn);
 
			//Add button listeners
			rightBtn.buttonMode = true;
			leftBtn.buttonMode = true;
			rightBtn.addEventListener(MouseEvent.CLICK, buttonClick);
			leftBtn.addEventListener(MouseEvent.CLICK, buttonClick);
 
			//Place buttons on stage
			rightBtn.x 			= stage.stageWidth - 20;
			leftBtn.x 			= 20;
			rightBtn.y 			=  stage.stageHeight / 2;
			leftBtn.y 			=  (stage.stageHeight / 2) + 20;
			leftBtn.rotation 	= 180;
		}
 
		//Button actions
		protected function buttonClick(evt:MouseEvent):void 
		{
			switch (evt.target)
			{
				case rightBtn:
				currentItem ++
				break;
 
				case leftBtn:
				currentItem --;
				break;
			}
 
			//Don't allow any number lower than 0 or past max so there
			//is always a center item
 
			if (currentItem < 0)
			{
				currentItem = 0;
			}
			if (currentItem > (planes.length - 1))
			{
				currentItem = planes.length - 1;
			}
 
			//Call animation
			animate();
		}
 
		//Creates a simple arrow shape / returns the sprite
		protected function createButton():Sprite
		{
			var btn:Sprite = new Sprite();
 
			btn.graphics.beginFill(0x333333);
			btn.graphics.moveTo(0, 0);
			btn.graphics.lineTo(0, 20);
			btn.graphics.lineTo(10, 10);
			btn.graphics.lineTo(0, 0);
			btn.graphics.endFill();
			btn.filters = [new GlowFilter(0xFFFFFF,1,10,10,3)]
			return btn;
		}
	}
}

That’s it. This should provide a good base for you to build out your own unique coverflow.

This entry was posted in Actionscript 3 Papervision, Actionscript 3.0, Examples, Papervision 3D, Papervision Coverflow, Tutorials, TweenLite and tagged , , , , , , , . Bookmark the permalink.

9 Responses to A Simple Papervision Coverflow

  1. Zeb says:

    Nice tutorial but how do I reposition the Coverflow?

    For example my flash has a button and some text that needs to go underneath, but I can’t work out how to move the Coverflow Y location up.

    Help :)

  2. am says:

    thanks, great tutorial!

  3. Hee-Sun Kim says:

    When I use large size pictures, it shows a z-sorting problem. I tried to find out the solution but couldn’t.

  4. Rainbow says:

    Hi,

    great tutorial, thx.

    How can i add a mirror reflect of all the planes??

  5. Pingback: Anonymous

  6. Jes says:

    Thanks for the tutorial! I’ve been looking around for a good coverflow script that was straightforward enough for me to customize and to actually understand what it was doing–and this was it! I added some tweaks using mod (%) to make an endless/circular coverflow with an autoplay function. Though for some reason the onPlaneClick function stopped working when I put movieclips in the image planes instead of bitmaps… so still working out a few kinks. But you can see how it’s looking here: A Fresh Web Design

  7. Pingback: A Simple Away3D Coverflow | Flash 3D

  8. Pingback: Ryan Liu | Flash ActionScript

  9. Tristan says:

    Hey this is a great tutorial. Any idea how you could integrate a scroll bar into this? I’d like to work with this script as its only one file unlike all the other tutorials I’ve found.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>