A Simple Papervision Carousel

Papervision 3D Carousel

download-source

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

Actionscript:
  1. for (var i:int = 0; i <planes.length; i++)
  2. {
  3.     var angle:Number    = Math.PI * 2 / numItems * i;
  4.     var plane:Plane     = planes[i];
  5.     plane.x             = Math.cos(angle) * radius;
  6.     plane.z             = Math.sin(angle) * radius;
  7.     plane.rotationY     = -360 / numItems * i - 90;
  8. }

Then to rotate our carousel we apply some similar math

Actionscript:
  1. var rotateTo:Number = (-360 / numItems) * currentItem + 90;
  2. 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.

Actionscript:
  1. protected var numItems:Number = 20;
  2. protected var radius:Number = 500;

Here is the full code.

Actionscript:
  1. package
  2. {
  3.     import flash.display.DisplayObject;
  4.     import flash.display.MovieClip;
  5.     import flash.display.Sprite;
  6.     import flash.events.Event;
  7.     import flash.events.MouseEvent;
  8.     import gs.easing.Quint;
  9.     import gs.TweenLite;
  10.     import org.papervision3d.materials.BitmapFileMaterial;
  11.     import org.papervision3d.objects.DisplayObject3D;
  12.     import org.papervision3d.objects.primitives.Plane;
  13.     import org.papervision3d.view.BasicView;
  14.    
  15.     /**
  16.      * ...
  17.      * @author Charlie Schulze, charlie[at]woveninteractive[dot]com
  18.      */
  19.    
  20.     public class Main extends BasicView
  21.     {
  22.         protected var planes:Array = [];
  23.         protected var numItems:Number = 20;
  24.         protected var radius:Number = 500;
  25.         protected var currentItem:Number = 0;
  26.        
  27.         protected var mat:BitmapFileMaterial;
  28.         protected var planesHolder:DisplayObject3D;
  29.         protected var rightBtn:Sprite;
  30.         protected var leftBtn:Sprite;
  31.        
  32.         public function Main():void
  33.         {
  34.             super();
  35.             init();
  36.         }
  37.         protected function init():void
  38.         {
  39.             createChildren();
  40.             createButtons();
  41.             commitProperties();
  42.             startRendering();
  43.         }
  44.         protected function createChildren():void
  45.         {
  46.            
  47.             planesHolder = new DisplayObject3D();
  48.            
  49.             //Create Material
  50.             mat             = new BitmapFileMaterial("images/queen.gif");
  51.             mat.smooth   = true;
  52.             mat.doubleSided = true;
  53.            
  54.             for (var i:int = 0; i <numItems; i++)
  55.             {
  56.                 var plane:Plane = new Plane(mat, 150, 234);
  57.                 planes.push(plane);
  58.                
  59.                 //Add plane to the scene
  60.                 planesHolder.addChild(plane);
  61.             }
  62.             scene.addChild(planesHolder);
  63.         }
  64.        
  65.         protected function commitProperties():void
  66.         {
  67.             //Set properties of our planes
  68.             for (var i:int = 0; i <planes.length; i++)
  69.             {
  70.                 var angle:Number    = Math.PI * 2 / numItems * i;
  71.                 var plane:Plane     = planes[i];
  72.                 plane.x             = Math.cos(angle) * radius;
  73.                 plane.z             = Math.sin(angle) * radius;
  74.                 plane.rotationY     = -360 / numItems * i - 90;
  75.             }
  76.            
  77.             //Adjust camera
  78.             camera.y = 200;
  79.            
  80.             //Rotate once
  81.             rotate();
  82.         }
  83.  
  84.         //Rotates the carousel
  85.         protected function rotate():void
  86.         {
  87.             var rotateTo:Number = (-360 / numItems) * currentItem + 90;
  88.             TweenLite.to(planesHolder, 1, { rotationY:rotateTo, ease:Quint.easeInOut } );
  89.         }
  90.        
  91.         /*
  92.          * Everything below this point is just for creating the buttons and
  93.          * setting button events for controlling the carousel.
  94.          */
  95.  
  96.         protected function createButtons():void
  97.         {
  98.             //Create Buttons
  99.             rightBtn = createButton();
  100.             leftBtn = createButton();
  101.                
  102.             addChild(leftBtn);
  103.             addChild(rightBtn);
  104.            
  105.             //Add button listeners
  106.             rightBtn.buttonMode = true;
  107.             leftBtn.buttonMode = true;
  108.             rightBtn.addEventListener(MouseEvent.CLICK, buttonClick);
  109.             leftBtn.addEventListener(MouseEvent.CLICK, buttonClick);
  110.                        
  111.             //Place buttons on stage
  112.             rightBtn.x    = stage.stageWidth - 120;
  113.             leftBtn.x       = 100;
  114.             rightBtn.y    =  stage.stageHeight / 2;
  115.             leftBtn.y       =  (stage.stageHeight / 2) + 20;
  116.             leftBtn.rotation    = 180;
  117.         }
  118.        
  119.         //Button actions
  120.         protected function buttonClick(evt:MouseEvent):void
  121.         {
  122.             switch (evt.target)
  123.             {
  124.                 case rightBtn:
  125.                 currentItem --;
  126.                 break;
  127.                
  128.                 case leftBtn:
  129.                 currentItem ++;
  130.                 break;
  131.             }
  132.             rotate();
  133.         }
  134.        
  135.         //Creates a simple arrow shape / returns the sprite
  136.         protected function createButton():Sprite
  137.         {
  138.             var btn:Sprite = new Sprite();
  139.            
  140.             btn.graphics.beginFill(0x333333);
  141.             btn.graphics.moveTo(0, 0);
  142.             btn.graphics.lineTo(0, 20);
  143.             btn.graphics.lineTo(10, 10);
  144.             btn.graphics.lineTo(0, 0);
  145.             btn.graphics.endFill();
  146.             return btn;
  147.         }
  148.     }
  149. }

Feel free to post links to ways you expand upon this file.

download-source

Post to Twitter Post to Delicious Delicious Post to Digg Digg This Post Post to Facebook Facebook Post to StumbleUpon Stumble This Post

9 Responses to “A Simple Papervision Carousel”


  • 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.

Leave a Reply


Follow WovenCharlie on Twitter

Flash and the City banner
2010 Flash And The City Speaker

RSS Feed