Vertical 3D Carousel with ActionScript 3 and XML

May 9, 2009 by: smonte
Flash vertical 3D carousel with ActionScript and XML

In this tutorial I’ll teach you how you can create an attractive vertical 3D carousel by using XML and ActionScript 3. We first set up everything ready on the Flash stage, then make the XML file and finally add some ActionScript 3. Check out the end result!

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Get TweenMax

We will use TweenMax for the animation of the menu items. Therefore, download TweenMax for AS3. TweenMax will save us a lot of time from coding the animations ourselves! Save the “gs” folder to the same location where your .fla file will be located.

New Document

Create a new Flash ActionScript 3 document with the following properties.

Flash document properties

Menu Item Shape

Draw a rounded rectangle on the stage with the following properties (the hex code for the fill color is #A3320C). I used a value 5 for the rounded corners.

Flash menu item shape

Menu Item Movie Clip

Convert the rectangle to a movie clip (select the rectangle and hit F8). Name it “Menu Item” and set the registration point to the center. Also link the rectangle to a class named “MenuRectangle”. We link the menu item to a class because we’ll be creating these menu items via ActionScript.

Flash menu item movie clip

Text Layer

Double click the menu item movie clip on the stage. You should now be “inside” the movie clip. Now create a new layer named “menu text”.

Flash text layer

Menu Item Text

In the “menu text” layer create a dynamic text field so that it’s on top of the rectangle shape. Type some text in it and set the following properties. Note that we give the text field an instance name of “menuText“.

Flash menu text properties

Embedding Characters

In order for the text to look smooth in the Flash movie we need to embed some characters. So while the “menuText” text field selected, click the “Character Embedding” button and embed uppercase and lowercase characters (embed more if you’ll use more characters).

Embedding characters in Flash

Final Touch to the Stage

Now go back to the main timeline and remove the menu item movie clip from the stage. Your stage should be completely empty now.

Creating the XML File

Now we’re ready to create the XML file from which we will load the menu item labels and URLs where they link to. With your favorite text editor type the following.

 
<menu>
 
    <items>
 
        <item>
            <label>Home</label>
            <linkTo>http://tutorials.flashmymind.com</linkTo>
        </item>
        <item>
            <label>Tutorials</label>
            <linkTo>http://tutorials.flashmymind.com/complete-list-of-flash-and-actionscript-3-tutorials/</linkTo>
        </item>
        <item>
            <label>Forum</label>
            <linkTo>http://tutorials.flashmymind.com/forum/</linkTo>
        </item>
        <item>
            <label>About</label>
            <linkTo>http://tutorials.flashmymind.com/about/</linkTo>
        </item>
        <item>
            <label>Home</label>
            <linkTo>http://tutorials.flashmymind.com</linkTo>
        </item>
        <item>
            <label>Tutorials</label>
            <linkTo>http://tutorials.flashmymind.com/complete-list-of-flash-and-actionscript-3-tutorials/</linkTo>
        </item>
        <item>
            <label>Forum</label>
            <linkTo>http://tutorials.flashmymind.com/forum/</linkTo>
        </item>
        <item>
            <label>XML</label>
            <linkTo>http://tutorials.flashmymind.com/about/</linkTo>
        </item>
        <item>
            <label>Home</label>
            <linkTo>http://tutorials.flashmymind.com</linkTo>
        </item>
        <item>
            <label>Tutorials</label>
            <linkTo>http://tutorials.flashmymind.com/complete-list-of-flash-and-actionscript-3-tutorials/</linkTo>
        </item>
        <item>
            <label>Forum</label>
            <linkTo>http://tutorials.flashmymind.com/forum/</linkTo>
        </item>
        <item>
            <label>About</label>
            <linkTo>http://tutorials.flashmymind.com/about/</linkTo>
        </item>
        <item>
            <label>Home</label>
            <linkTo>http://tutorials.flashmymind.com</linkTo>
        </item>
        <item>
            <label>Tutorials</label>
            <linkTo>http://tutorials.flashmymind.com/complete-list-of-flash-and-actionscript-3-tutorials/</linkTo>
        </item>
        <item>
            <label>Forum</label>
            <linkTo>http://tutorials.flashmymind.com/forum/</linkTo>
        </item>
        <item>
            <label>XML</label>
            <linkTo>http://tutorials.flashmymind.com/about/</linkTo>
        </item>
        <item>
            <label>Home</label>
            <linkTo>http://tutorials.flashmymind.com</linkTo>
        </item>
        <item>
            <label>Tutorials</label>
            <linkTo>http://tutorials.flashmymind.com/complete-list-of-flash-and-actionscript-3-tutorials/</linkTo>
        </item>
        <item>
            <label>Forum</label>
            <linkTo>http://tutorials.flashmymind.com/forum/</linkTo>
        </item>
        <item>
            <label>About</label>
            <linkTo>http://tutorials.flashmymind.com/about/</linkTo>
        </item>        <item>
            <label>Home</label>
            <linkTo>http://tutorials.flashmymind.com</linkTo>
        </item>
        <item>
            <label>XML</label>
            <linkTo>http://tutorials.flashmymind.com/complete-list-of-flash-and-actionscript-3-tutorials/</linkTo>
        </item>
 
    </items>
 
</menu>

The structure of the XML file is simple. For each item we specify the label and the URL where it should link to. Save this file to a location you’ll remember.

ActionScript – Loading the XML

On the main timeline type the following code in the first frame.

//Import TweenMax
import gs.*;
 
//The path to the XML file (use your own here)
var xmlPath:String = "http://tutorials.flashmymind.com/XML/carousel-menu.xml";
 
//We'll store the loaded XML to this variable
var xml:XML;
 
//Create a loader and load the XML. Call the function "xmlLoaded" when done.
var loader = new URLLoader();
loader.load(new URLRequest(xmlPath));
loader.addEventListener(Event.COMPLETE, xmlLoaded);
 
//This function is called when the XML file is loaded
function xmlLoaded(e:Event):void {
 
	//Make sure that we are not working with a null variable
	if ((e.target as URLLoader) != null ) {
 
		//Create a new XML object with the loaded XML data
		xml = new XML(loader.data);
 
		//Call the function that creates the menu
		createMenu();
	}
}

We first import TweenMax because we need it later on in the animation. Then we specify where the XML file is located, modify this to fit your settings. Then we load the XML file and call the xmlLoaded() function. In the xmlLoaded() function we create a new XML object from the loaded XML data. Finally we call the function createMenu() which we’ll look at next.

ActionScript – Creating the 3D Menu

Type the following code.

//We need to know how many items we have on the stage
var numberOfItems:uint = 0;
 
//This array will contain all the menu items
var menuItems:Array = new Array();
 
//Set the focal length
var focalLength:Number = 350;
 
//Set the vanishing point
var vanishingPointX:Number = stage.stageWidth / 2;
var vanishingPointY:Number = stage.stageHeight / 2;
 
//We calculate the angleSpeed in the ENTER_FRAME listener
var angleSpeed:Number = 0;
 
//Radius of the circle
var radius:Number = 128;
 
//This function creates the menu
function createMenu():void {
 
	//Get the number of menu items we will have
	numberOfItems = xml.items.item.length();
 
	//Calculate the angle difference between the menu items (in radians)
	var angleDifference:Number = Math.PI * (360 / numberOfItems) / 180;
 
	//We use a counter so we know how many menu items have been created
	var count:uint = 0;
 
	//Loop through all the <button></button> nodes in the XML
	for each (var item:XML in xml.items.item) {
 
		//Create a new menu item
		var menuItem:MenuItem = new MenuItem();
 
		//Calculate the starting angle for the menu item
		var startingAngle:Number = angleDifference * count;
 
		//Set a "currentAngle" attribute for the menu item
		menuItem.currentAngle = startingAngle;
 
		//Position the menu item
		menuItem.xpos3D = 0;
		menuItem.ypos3D = radius * Math.sin(startingAngle);
		menuItem.zpos3D = radius * Math.cos(startingAngle);
 
		//Calculate the scale ratio for the menu item (the further the item -> the smaller the scale ratio)
		var scaleRatio = focalLength/(focalLength + menuItem.zpos3D);
 
		//Scale the menu item according to the scale ratio
		menuItem.scaleX = menuItem.scaleY = scaleRatio;
 
		//Position the menu item to the stage (from 3D to 2D coordinates)
		menuItem.x = vanishingPointX + menuItem.xpos3D * scaleRatio;
		menuItem.y = vanishingPointY + menuItem.ypos3D * scaleRatio;
 
		//Add a text to the menu item
		menuItem.menuText.text = item.label;
 
		//Add a "linkTo" variable for the URL
		menuItem.linkTo = item.linkTo;
 
		//We don't want the text field to catch mouse events
		menuItem.mouseChildren = false;
 
		//Assign MOUSE_OVER, MOUSE_OUT and CLICK listeners for the menu item
		menuItem.addEventListener(MouseEvent.MOUSE_OVER, mouseOverItem);
		menuItem.addEventListener(MouseEvent.MOUSE_OUT, mouseOutItem);
		menuItem.addEventListener(MouseEvent.CLICK, itemClicked);
 
		//Add the menu item to the menu items array
		menuItems.push(menuItem);
 
		//Add the menu item to the stage
		addChild(menuItem);
 
		//Assign an initial alpha
		menuItem.alpha = 0.3;
 
		//Add some blur to the item
		TweenMax.to(menuItem,0, {blurFilter:{blurX:1, blurY:1}});
 
		//Update the count
		count++;
	}
}

There is quite a bit of code here, but it’s actually really straightforward. We first declare some more variables that we need. In the createMenu() function we loop through all the items found in the XML file. We position the items in a 3D circle and then convert the 3D coordinates into 2D coordinates.

We assign a label to each item and create a “linkTo” attribute which will save the URL for each menu item.

Next let’s look at the mouse event handlers.

ActionScript – Mouse Event Handlers

Type the following functions.

//This function is called when a mouse is over an item
function mouseOverItem(e:Event):void {
 
	//Tween the item's properties
	TweenMax.to(e.target, 0.1, {alpha: 1, glowFilter:{color:0xffffff, alpha:1, blurX:60, blurY:60},blurFilter:{blurX:0, blurY:0}});
}
 
//This function is called when a mouse is out of an item
function mouseOutItem(e:Event):void {
 
	//Tween the item's properties
	TweenMax.to(e.target, 1, {alpha: 0.3, glowFilter:{color:0xffffff, alpha:1, blurX:0, blurY:0},blurFilter:{blurX:1, blurY:1}});
}
 
//This function is called when an item is clicked
function itemClicked(e:Event):void {
 
	//Navigate to the URL that's assigned to the menu item
	var urlRequest:URLRequest=new URLRequest(e.target.linkTo);
	navigateToURL(urlRequest);
 
}

As you can see we animate an item when the mouse moves over or out of an item. We use TweenMax to make our lives a little easier! You can easily add more animations using TweenMax . Play around with the values to see how the menu will look like.

When an item is clicked we navigate to the URL that was assigned to the menu item.

ActionScript – Moving the Carousel

Type the following code to add the movement of the carousel.

//Add an ENTER_FRAME listener for the animation
addEventListener(Event.ENTER_FRAME, moveCarousel);
 
//This function is called in each frame
function moveCarousel(e:Event):void {
 
	//Calculate the angle speed according to mouseY position
	angleSpeed = (mouseY - stage.stageHeight / 2) * 0.0002;
 
	//Loop through the menu items
	for (var i:uint = 0; i < menuItems.length; i++) {
 
		//Store the menu item to a local variable
		var menuItem:MenuItem = menuItems[i] as MenuItem;
 
		//Update the current angle of the item
		menuItem.currentAngle += angleSpeed;
 
		//Calculate a scale ratio
		var scaleRatio = focalLength/(focalLength + menuItem.zpos3D);
 
		//Scale the item according to the scale ratio
		menuItem.scaleX=menuItem.scaleY=scaleRatio;
 
		//Set new 3D coordinates
		menuItem.xpos3D=0;
		menuItem.ypos3D=radius*Math.sin(menuItem.currentAngle);
		menuItem.zpos3D=radius*Math.cos(menuItem.currentAngle);
 
		//Update the item's coordinates.
		menuItem.x=vanishingPointX+menuItem.xpos3D*scaleRatio;
		menuItem.y=vanishingPointY+menuItem.ypos3D*scaleRatio;
 
	}
 
	//Call the function that sorts the items so they overlap each other correctly
	sortZ();
}
 
//This function sorts the items so they overlap each other correctly
function sortZ():void {
 
	//Sort the array so that the item which has the highest 
	//z position (= furthest away) is first in the array
	menuItems.sortOn("zpos3D", Array.NUMERIC | Array.DESCENDING);
 
	//Set new child indexes for the item
	for (var i:uint = 0; i < menuItems.length; i++) {
		setChildIndex(menuItems[i], i);
	}
}

Here is where all the magic happens. In each frame we rotate the carousel according to the mouse position. We calculate new 3D coordinates and then convert them into 2D coordinates. We’re actually only changing the y and z coordinates since this is a vertical carousel.

In the sortZ() function we assign new child indexes according to the z-coordinates of the items. This way the items overlap each others correctly giving us the effect of 3D.

Final Words

That’s the end of this tutorial, I hope you enjoyed it! Check out the .fla file if you want to take a closer look at the movie. And if you have any questions concerning the tutorial, please post them in the forum, not in the comments!

Download .fla

  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google

Related tutorials:

  1. Vertical 3D Carousel with ActionScript 3
  2. Vertical Menu with Actionscript 3 and XML
  3. Advanced XML Menu with ActionScript 3
  4. Colorful Menu with XML and ActionScript 3
  5. 3D Carousel with XML and ActionScript 3



Filed under: ActionScript 3 Advanced
Tags: , ,

Comments are closed.