Apr 4, 2009

Flash 3D Carousel with XML and ActionScript 3

This tutorial is an interesting one. We’ll be creating a Flash 3D carousel using XML and ActionScript 3. You can easily change the number of images seen in the carousel to fit for your needs!


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


Making the XML file


Let’s start by creating the XML file. In the XML file we specify three important things,



  • how many images we are using in the 3D carousel menu,

  • the URLs where the images can be found and

  • the URLs where the images should link to.


1. In your favorite text editor, type the following.



<?xml version="1.0" encoding="utf-8"?> 
<carousel>
 
<number_of_images>10</number_of_images>
 
<images>
 
<image>
<url>http://flashmymind.com/3D_carousel/image1.png</url>
<link_to>http://tutorials.flashmymind.com</link_to>
</image>
 
<image>
<url>http://flashmymind.com/3D_carousel/image2.png</url>
<link_to>http://tutorials.flashmymind.com</link_to>
</image>
 
<image>
<url>http://flashmymind.com/3D_carousel/image3.png</url>
<link_to>http://tutorials.flashmymind.com</link_to>
</image>
 
<image>
<url>http://flashmymind.com/3D_carousel/image4.png</url>
<link_to>http://tutorials.flashmymind.com</link_to>
</image>
 
<image>
<url>http://flashmymind.com/3D_carousel/image5.png</url>
<link_to>http://tutorials.flashmymind.com</link_to>
</image>
 
<image>
<url>http://flashmymind.com/3D_carousel/image6.png</url>
<link_to>http://tutorials.flashmymind.com</link_to>
</image>
 
<image>
<url>http://flashmymind.com/3D_carousel/image7.png</url>
<link_to>http://tutorials.flashmymind.com</link_to>
</image>
 
<image>
<url>http://flashmymind.com/3D_carousel/image8.png</url>
<link_to>http://tutorials.flashmymind.com</link_to>
</image>
 
<image>
<url>http://flashmymind.com/3D_carousel/image9.png</url>
<link_to>http://tutorials.flashmymind.com</link_to>
</image>
 
<image>
<url>http://flashmymind.com/3D_carousel/image10.png</url>
<link_to>http://tutorials.flashmymind.com</link_to>
</image>
 
</images>
 
</carousel>


2. Save the file as “3D-carousel-settings.xml”.


Now we have our XML all ready! You are free to use your own images, just remember to make them all the same size and set the URLs to match your settings. I have used the following images (70×70).





Moving to Flash


3. Create a new Flash document of size 550×250.


4. In the first frame of your Flash movie, type the following.



//We use 70x70 sized images (change this if different for your images) 
const IMAGE_WIDTH:uint = 70;
const IMAGE_HEIGHT:uint = 70;
 
//Set the focal length
var focalLength:Number = 500;
 
//Set the vanishing point
var vanishingPointX:Number = stage.stageWidth / 2;
var vanishingPointY:Number = stage.stageHeight / 2;
 
//The 3D floor for the images
var floor:Number = 40;
 
//We calculate the angleSpeed in the ENTER_FRAME listener
var angleSpeed:Number = 0;
 
//Radius of the circle
var radius:Number = 200;
 
//Specify the path to the XML file.
//You can use my path or your own.
var xmlFilePath:String = "http://flashmymind.com/xml/3D-carousel-settings.xml";
 
//We save the loaded XML to a variable
var xml:XML;
 
//This array will contain all the imageHolders
var imageHolders:Array = new Array();
 
//We want to know how many images have been loaded
var numberOfLoadedImages:uint = 0;
 
//The total number of images according to XML file
var numberOfImages:uint = 0;
 
//Load the XML file.
var loader = new URLLoader();
loader.load(new URLRequest(xmlFilePath));
 
//We call the function xmlLoaded() when the loading is complete.
loader.addEventListener(Event.COMPLETE, xmlLoaded);
 
//This function is called when the XML file is loaded
function xmlLoaded(e:Event):void {
 
//Create a new XML object from the loaded XML data
xml = new XML(loader.data);
xml.ignoreWhitespace = true;
 
//Call the function that loads the images
loadImages();
}
 
//This function loads and creates holders for the images specified in the 3D-carousel-settings.xml
function loadImages():void {
 
//Get the total number of images from the XML file
numberOfImages = xml.number_of_images;
 
//Loop through the images found in the XML file
for each (var image:XML in xml.images.image) {
 
//Create a new image holder for an image
var imageHolder:MovieClip = new MovieClip();
 
//Create a loader that will load an image
var imageLoader = new Loader();
 
//Add the imageLoader to the imageHolder
imageHolder.addChild(imageLoader);
 
//We don't want to catch any mouse events from the loader
imageHolder.mouseChildren = false;
 
//Position the imageLoader so that the registration point of the holder is centered
imageLoader.x = - (IMAGE_WIDTH / 2);
imageLoader.y = - (IMAGE_HEIGHT / 2);
 
//Save where the imageHolder should link to
imageHolder.linkTo = image.link_to;
 
//Add the imageHolder to the imageHolders array
imageHolders.push(imageHolder);
 
//Load the image
imageLoader.load(new URLRequest(image.url));
 
//Listen when the image is loaded
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded);
}
}
 
//This function is called when an image is loaded
function imageLoaded(e:Event):void {
 
//Update the number of loaded images
numberOfLoadedImages++;
 
//Set the bitmap smoothing to true for the image (we know that the loader's content is a bitmap).
e.target.content.smoothing = true;
 
//Check to see if this is the last image loaded
if (numberOfLoadedImages == numberOfImages) {
 
//Set up the carousel
initializeCarousel();
}
}


As you can see we first create all the variables we are going to use in this Flash movie. Then we load the XML file. Once the XML file is loaded, we load all the images that are specified in the XML file. Finally, we call the function initializeCarousel(), which is responsible for creating the 3D carousel. Here is the function.



//This function is called when all the images have been loaded. 
//Now we are ready to create the 3D carousel.
function initializeCarousel():void {
 
//Calculate the angle difference between the images (in radians)
var angleDifference:Number = Math.PI * (360 / numberOfImages) / 180;
 
//Loop through the images
for (var i:uint = 0; i < imageHolders.length; i++) {
 
//Assign the imageHolder to a local variable
var imageHolder:MovieClip = (MovieClip)(imageHolders[i]);
 
//Get the angle for the image (we space the images evenly)
var startingAngle:Number = angleDifference * i;
 
//Position the imageHolder
imageHolder.xpos3D = radius * Math.cos(startingAngle);
imageHolder.zpos3D = radius * Math.sin(startingAngle);
imageHolder.ypos3D = floor;
 
//Set a "currentAngle" attribute for the imageHolder
imageHolder.currentAngle = startingAngle;
 
//Calculate the scale ratio for the imageHolder (the further the image -> the smaller the scale)
var scaleRatio = focalLength/(focalLength + imageHolder.zpos3D);
 
//Scale the imageHolder according to the scale ratio
imageHolder.scaleX = imageHolder.scaleY = scaleRatio;
 
//Set the alpha for the imageHolder
imageHolder.alpha = 0.3;
 
//We want to know when the mouse is over and out of the imageHolder
imageHolder.addEventListener(MouseEvent.MOUSE_OVER, mouseOverImage);
imageHolder.addEventListener(MouseEvent.MOUSE_OUT, mouseOutImage);
 
//We also want to listen for the clicks
imageHolder.addEventListener(MouseEvent.CLICK, imageClicked);
 
//Position the imageHolder to the stage (from 3D to 2D coordinates)
imageHolder.x = vanishingPointX + imageHolder.xpos3D * scaleRatio;
imageHolder.y = vanishingPointY + imageHolder.ypos3D * scaleRatio;
 
//Add the imageHolder to the stage
addChild(imageHolder);
}
 
//Add an ENTER_FRAME for the rotation
addEventListener(Event.ENTER_FRAME, rotateCarousel);
}


Now we have our carousel on the stage! You should have a similar looking Flash movie now.


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


Finally, let’s add the rotation function! Type the following.



function rotateCarousel(e:Event):void { 
 
//Calculate the angleSpeed according to mouse position
angleSpeed = (mouseX - vanishingPointX) / 4096;
 
//Loop through the images
for (var i:uint = 0; i < imageHolders.length; i++) {
 
//Assign the imageHolder to a local variable
var imageHolder:MovieClip = (MovieClip)(imageHolders[i]);
 
//Update the imageHolder's current angle
imageHolder.currentAngle += angleSpeed;
 
//Set a new 3D position for the imageHolder
imageHolder.xpos3D=radius*Math.cos(imageHolder.currentAngle);
imageHolder.zpos3D=radius*Math.sin(imageHolder.currentAngle);
 
//Calculate a scale ratio
var scaleRatio = focalLength/(focalLength + imageHolder.zpos3D);
 
//Scale the imageHolder according to the scale ratio
imageHolder.scaleX=imageHolder.scaleY=scaleRatio;
 
//Update the imageHolder's coordinates
imageHolder.x=vanishingPointX+imageHolder.xpos3D*scaleRatio;
imageHolder.y=vanishingPointY+imageHolder.ypos3D*scaleRatio;
}
 
//Call the function that sorts the images so they overlap each others correctly
sortZ();
}
 
//This function sorts the images so they overlap each others correctly
function sortZ():void {
 
//Sort the array so that the image which has the highest
//z position (= furthest away) is first in the array
imageHolders.sortOn("zpos3D", Array.NUMERIC | Array.DESCENDING);
 
//Set new child indexes for the images
for (var i:uint = 0; i < imageHolders.length; i++) {
setChildIndex(imageHolders[i], i);
}
}
 
//This function is called when the mouse is over an imageHolder
function mouseOverImage(e:Event):void {
 
//Set alpha to 1
e.target.alpha=1;
}
 
//This function is called when the mouse is out of an imageHolder
function mouseOutImage(e:Event):void {
 
//Set alpha to 0.3
e.target.alpha=0.3;
}
 
//This function is called when an imageHolder is clicked
function imageClicked(e:Event):void {
 
//Navigate to the URL that is in the "linkTo" variable
navigateToURL(new URLRequest(e.target.linkTo));
}


You are done, test your movie! Hope you enjoyed this Flash ActionScript 3 tutorial :)


Download fla.

No comments:

Post a Comment