This week I set out to create a Papervision Carousel in it's simplest form. At the heart of this carousel is a simple "for" loop / math which places the items in a circle in 3D space
-
for (var i:int = 0; i <planes.length; i++)
-
{
-
var angle:Number = Math.PI * 2 / numItems * i;
-
var plane:Plane = planes[i];
-
plane.x = Math.cos(angle) * radius;
-
plane.z = Math.sin(angle) * radius;
-
plane.rotationY = -360 / numItems * i - 90;
-
}
Then to rotate our carousel we apply some similar math
-
var rotateTo:Number = (-360 / numItems) * currentItem + 90;
-
TweenLite.to(planesHolder, 1, { rotationY:rotateTo, ease:Quint.easeInOut } );
This code allows us to just increment currentItem and rotate our carousel. Another easy add-on would be to setup a navigation along the bottom where you could control and change the currentItem to a specific number to rotate right to that section of the carousel.
It's also very easy to customize the number of items and radius of the carousel by adjusting these numbers.
-
protected var numItems:Number = 20;
-
protected var radius:Number = 500;
Here is the full code.
-
package
-
{
-
import flash.display.DisplayObject;
-
import flash.display.MovieClip;
-
import flash.display.Sprite;
-
import flash.events.Event;
-
import flash.events.MouseEvent;
-
import gs.easing.Quint;
-
import gs.TweenLite;
-
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
-
*/
-
-
public class Main extends BasicView
-
{
-
protected var planes:Array = [];
-
protected var numItems:Number = 20;
-
protected var radius:Number = 500;
-
protected var currentItem:Number = 0;
-
-
protected var mat:BitmapFileMaterial;
-
protected var planesHolder:DisplayObject3D;
-
protected var rightBtn:Sprite;
-
protected var leftBtn:Sprite;
-
-
public function Main():void
-
{
-
super();
-
init();
-
}
-
protected function init():void
-
{
-
createChildren();
-
createButtons();
-
commitProperties();
-
startRendering();
-
}
-
protected function createChildren():void
-
{
-
-
planesHolder = new DisplayObject3D();
-
-
//Create Material
-
mat = new BitmapFileMaterial("images/queen.gif");
-
mat.smooth = true;
-
mat.doubleSided = true;
-
-
for (var i:int = 0; i <numItems; i++)
-
{
-
var plane:Plane = new Plane(mat, 150, 234);
-
planes.push(plane);
-
-
//Add plane to the scene
-
planesHolder.addChild(plane);
-
}
-
scene.addChild(planesHolder);
-
}
-
-
protected function commitProperties():void
-
{
-
//Set properties of our planes
-
for (var i:int = 0; i <planes.length; i++)
-
{
-
var angle:Number = Math.PI * 2 / numItems * i;
-
var plane:Plane = planes[i];
-
plane.x = Math.cos(angle) * radius;
-
plane.z = Math.sin(angle) * radius;
-
plane.rotationY = -360 / numItems * i - 90;
-
}
-
-
//Adjust camera
-
camera.y = 200;
-
-
//Rotate once
-
rotate();
-
}
-
-
//Rotates the carousel
-
protected function rotate():void
-
{
-
var rotateTo:Number = (-360 / numItems) * currentItem + 90;
-
TweenLite.to(planesHolder, 1, { rotationY:rotateTo, ease:Quint.easeInOut } );
-
}
-
-
/*
-
* Everything below this point is just for creating the buttons and
-
* setting button events for controlling the carousel.
-
*/
-
-
protected function createButtons():void
-
{
-
//Create 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 - 120;
-
leftBtn.x = 100;
-
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;
-
}
-
rotate();
-
}
-
-
//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();
-
return btn;
-
}
-
}
-
}
Feel free to post links to ways you expand upon this file.



Hi,
the tutorial and view is great, but after one more desperate day with as, I still worry about this:
HOW TO MAKE THE IMAGES CLICK-ABLE.
I tried already any kind of AddEventListener… and also
mat.interactive = true;
mat.addEventListener(MouseEvent.CLICK, ClickFunction123);
But it looks like this event is not implemented :-(
Please help
You’re on the right track. Yes the material “mat.interactive = true;” needs to be set. When you are doing mouse events you do not apply them to the material but to the object. so instead of mat.addEventListener you will do plane.addEventListener and instead of using a MouseEvent you need to use an InteractiveScene3DEvent as follows:
plane.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS, onPlaneClick);
The other thing to keep in mind is that you need to make sure that your viewport is set to interactive as well.
viewport.interactive = true;
Do that and you should have success.
Charlie
Heho,
Had to deal with the same issue last year. It was a bit confusing because the mat.interactive must be true and the plane gets the eventlistener.
Next confusion came with the event which can not be the standard events, but has to be InteractiveScene3DEvent and took lots of hours of reading through the source :-)
After that, it took some more minutes to find out the viewport.interactive which is not directly addressed anywhere in this sample, but played with viewport in another papervision test already.
Now it’s working properly.
Congratulation, papervision is a really cool “library”.
Best regards,
rabby
Thanks for the tutorial. I am new to flash and as3, and am having a hard time. I can’t seem to figure out how to make this carousel rotate relative to the position of the mouse (similar to your cow example). I also would like to set a min and max speed. Can someone help me please : )
Thanks
Ok so I figured out if I add this to the render camera code it rotates the carousel to the mouse:
var dist2:Number = ((stage.mouseX) – stage.stageWidth * 0.5) * 0.0002;
angle += dist2;
cam.x = Math.cos(angle) * 1000;
cam.z = Math.sin(angle) * 1000;
But I still would like to add a max speed. It also seems to go faster if the mouse if on the left and pretty slow if mouse is on the right Does anyone know why that is doing it and how to fix it? Also how could I insert an image into the center of the carousel that does not move/rotate? Thanks for the help!
Hello!
Thank you so much for the tutorial, but I have a question, I need to incorporate more images in the carousel. I try to do with XML such as in other example that you have but a can´t.
PD: Sorry for my english I don´t speak so good.
I wonder if it can be modified so it looks like what iAds Toy Story 3 HTML5 menu? Without the arrows to control the movement, but just drag the items to make it move, then when click link to other pages. I really want to see such can be done in papervision – vertical draggable 3D carousel using XML to define the photos and links~~~~I am too greedy, hahaha
To add images in the carousel:
4 steps:
add images to the “.fla”
declare variables at the beginning
add images to the “.as”
add images to the array “planes”
1. add images to the “.fla”
It is the most difficult step to achieve without video demonstration.
In scenario,
Create a folder “faces” in which there are four layers named “face1, face2, face3, face4″.
Select the layer “face1″, drag and drop the first image of the library next to the scene (thus it is not visible but present).
Right click on the image -> convert to symbol -> named “face1″ and the symbols’s property named “face1″ too.
If you have succeeded for the first image, it is the same for all other images.
//in the “.as”:
2. variable declaration at the beginning to a question of speed:
don’t forget “protected var numItems:Number = 4;” otherwise it doesn’t work.
protected var material1:MovieMaterial;
protected var material2:MovieMaterial;
protected var material3:MovieMaterial;
protected var material4:MovieMaterial;
protected var plane1:Plane;
protected var plane2:Plane;
protected var plane3:Plane;
protected var plane4:Plane;
3. add images to the “.as”
//I added the 4 images in the function “createChildren()” :
//Create Material
material1 = new MovieMaterial (face1);
material1.interactive = true;
material1.animated =true;
material1.smooth =true;
material1.doubleSided = true;
material2 = new MovieMaterial (face2);
material2.interactive = true;
material2.animated =true;
material2.smooth =true;
material2.doubleSided = true;
material3 = new MovieMaterial (face3);
material3.interactive = true;
material3.animated =true;
material3.smooth =true;
material3.doubleSided = true;
material4 = new MovieMaterial (face4);
material4.interactive = true;
material4.animated =true;
material4.smooth =true;
material4.doubleSided = true;
4. add images to the array “planes”
//”planes” is an array so add the images inside:
for (var i:int = 0; i < numItems; i++)
{
plane1 = new Plane(material1, 250, 250);
planes.push(plane1);
//Add plane1 to the scene
planesHolder.addChild(plane1);
plane2 = new Plane(material2, 250, 250);
planes.push(plane2);
//Add plane2 to the scene
planesHolder.addChild(plane2);
plane3 = new Plane(material3, 250, 250);
planes.push(plane3);
//Add plane3 to the scene
planesHolder.addChild(plane3);
plane4 = new Plane(material4, 250, 250);
planes.push(plane4);
//Add plane4 to the scene
planesHolder.addChild(plane4);
}
//you must know that: Plane(material:MovieMaterial, 250:width, 250:height);
So you can add lots of images but you must add some codes to do that.
To add images in the carousel:
4 steps:
add images to the “.fla”
declare variables at the beginning
add images to the “.as”
add images to the array “planes”
1. add images to the “.fla”
It is the most difficult step to achieve without video demonstration.
In scenario,
Create a folder “faces” in which there are four layers named “face1, face2, face3, face4″.
Select the layer “face1″, drag and drop the first image of the library next to the scene (thus it is not visible but present).
Right click on the image – convert to symbol – named “face1″ and the symbols’s property named “face1″ too.
If you have succeeded for the first image, it is the same for all other images.
//in the “.as”:
2. variable declaration at the beginning to a question of speed:
don’t forget “protected var numItems:Number = 4;” otherwise it doesn’t work.
protected var material1:MovieMaterial;
protected var material2:MovieMaterial;
protected var material3:MovieMaterial;
protected var material4:MovieMaterial;
protected var plane1:Plane;
protected var plane2:Plane;
protected var plane3:Plane;
protected var plane4:Plane;
3. add images to the “.as”
//I added the 4 images in the function “createChildren()” :
//Create Material
material1 = new MovieMaterial (face1);
material1.interactive = true;
material1.animated =true;
material1.smooth =true;
material1.doubleSided = true;
material2 = new MovieMaterial (face2);
material2.interactive = true;
material2.animated =true;
material2.smooth =true;
material2.doubleSided = true;
material3 = new MovieMaterial (face3);
material3.interactive = true;
material3.animated =true;
material3.smooth =true;
material3.doubleSided = true;
material4 = new MovieMaterial (face4);
material4.interactive = true;
material4.animated =true;
material4.smooth =true;
material4.doubleSided = true;
4. add images to the array “planes”
//”planes” is an array so add the images inside:
for (var i:int = 0; i < numItems; i++)
{
plane1 = new Plane(material1, 250, 250);
planes.push(plane1);
//Add plane1 to the scene
planesHolder.addChild(plane1);
plane2 = new Plane(material2, 250, 250);
planes.push(plane2);
//Add plane2 to the scene
planesHolder.addChild(plane2);
plane3 = new Plane(material3, 250, 250);
planes.push(plane3);
//Add plane3 to the scene
planesHolder.addChild(plane3);
plane4 = new Plane(material4, 250, 250);
planes.push(plane4);
//Add plane4 to the scene
planesHolder.addChild(plane4);
}
//you must know that: Plane(material:MovieMaterial, 250:width, 250:height);
So you can add lots of images but you must add some codes to do that.