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.






