XML is a data format that's well-suited to dynamic image galleries. It's also really easy to process in Flash with AS3. With the help of XML and ActionScript, we're going to create an image gallery that's dynamic and categorized into different themes.
We're also going to learn how to use a very practical tweening class, called Tweener, to move the different theme icons and the thumbnails. In this tutorial I'm going to concentrate on the effective processing of the data retrieved from XML; all the fancy image animation is up to you ;)
Step 1: Setting Up the Stage
First I'll share how I set up my stage. These are not fixed options, so if you want to change things, that's perfectly fine. Just make sure you change the code in this tutorial to fit with your settings (particularly regarding the size of the stage).
My stage is 900 x 600 px; I set the background color to black and the frame rate to 25fps. Although the SWF movie is only one frame long, setting the fps is important because it will affect the tweening we're going to perform.

As you can see we're going to use a document class, but before getting to that, we need to set up the layers, and place the objects that we're going to use.
Step 2: The Main Image's MovieClip
All of our non-moving content will be on a layer called 'BigPic+Title+Arrows' (create this now). The first one is an empty MovieClip called Img (instance name: img); this is the Mc in which we're going to load each big picture. Create this, and place it at (x: 450, y:220).
Step 3: Creating the Navigation Arrows
The simplest way to create these is to use a big '<' character. Create a new static text field, choose whatever font and size you want, type '<', and then use the 'Break apart' command: select the character and press CTRL+B or Modify > Break Apart.
Then, convert this shape into a MovieClip, name it 'Arrow', and change the registration point to the center of the left-hand side (where the arrow points).

Step 4: Placing the Navigation Arrows
We will need two of these on the stage, so drag one more from the Library. Flip one of them horizontally (Modify > Transform > Flip Horizontal). Position the left one at (x:0, y:220), and give it an instance name of 'prevArrow'. The right one should go at (x:900, y:220), and have an instance name of 'nextArrow'.
Step 5: The Title Text Field
Create a 900px wide dynamic text field (so that you can use titles as long as you wish). Place it at (x:0, y:440), and give it an instance name of 'txtField'. I used Arial font at 16pt, aligned to the center; don't forget to embed it!

Step 6: Drawing the Covering Plate
These are just little design elements for the theme icons and the thumbnails to make them fade out at the borders of the stage. Create a 30px wide, 130px high rectangle (without a stroke - just the fill), and with the rectangle still selected, go to the Color panel and change the Fill style from solid to linear. Set both colors to black, but set one of them to 0% alpha.

Step 7: Converting and Placing the Covering Plate
Now, convert the rectangle to a MovieClip (reg. point: top left corner, name:Cover). Do the same as you did with the arrows: drag two instances onto the stage, and flip one of them. In each case, the 0% alpha-side should be closest to the center of the stage.
Place them at the sides of the stage: (left one: (x:0, y:470); right one: (x:900, y:470)).
All right - we're done with this layer.
Step 8: The "themes+thumbs" Layer
Under our existing layer, create a new one called 'themes+thumbs'. On this layer, create an empty MovieClip for the theme icons (name: 'Themes', reg. point: top left corner, instance name: 'themes', x: 0, y: 470) and another for the thumbnails (name: 'smallPics', reg. point: top left corner, instance name: 'smallPicsMc', x: 0, y: 510).
We'll need to create some more symbols which don't start out on the stage, but we will create these in ActionScript later.
Step 9: The Thumbnail Symbol
Create an empty MovieClip (name: 'SmallPicButton', reg. point: top left corner). This MC will contain one thumbnail; we're going to have a lot of instances of this symbol, so we'll create each of these at runtime.
In order to do that, we have to export this symbol for ActionScript: in the Library panel, right-click on this symbol, then select Properties. Tick the 'Export for ActionScript' box, then set the Class to SmallPicButton. Base Class stays as it is.

After you click OK, double-click on this symbol in the library to enter edit mode, then go to the Actions panel - we're going to write some code now. We're going to make sure that this MovieClip behaves like a proper button.
Step 10: Action for the SmallPicButton
Copy and paste this code into the Actions panel:
//if the cursor is over the symbol we change its alpha to 1 function rollOver(e:MouseEvent):void{ alpha = 1; } //if the cursor just moved off the symbol, we change its alpha to 0.5 function rollOut(e:MouseEvent):void{ alpha = 0.5; } //register the event listeners to run the above functions addEventListener(MouseEvent.ROLL_OVER, rollOver); addEventListener(MouseEvent.ROLL_OUT, rollOut); //this guarantees that the cursor changes to the little pointing hand over the symbol buttonMode = true; useHandCursor = true; //set its initial alpha to 0.5 alpha = 0.5;
Step 11: The ThemeButton
This Symbol will be used for the icons you can click on to select a different themed category - what a surprise :). This is similar to the SmallPicButton, so in order to create it repeat Steps 8-10 - only, change the name and the Class to ThemeButton instead of SmallPicButton. You don't have to change anything in the code.
Step 12: What We Have So Far
So, we created two layers: the top one is the BigPic+Title+Arrows, the bottom one is themes+thumbs.
On the BigPic+Title+Arrows layer we have the img, the prevArrow, the nextArrow, the txtField and the two covering plates at the sides on the bottom.
On the themes+thumbs layer we have two empty MovieClips: Themes, which will contain all the theme icons, and smallPicsMc, which will contain all the thumbnails.
In the library, we have SmallPicButton and ThemeButton symbols with properly set linkage options.
I hope you're with me so far. It's crucial to have the symbols named properly, because otherwise the upcoming code won't work.
Step 13: Setting Up the Folder Structure
All right - so we're done with the Flash part. We have two things to do before we start coding: put all the pictures in a usable folder structure and create our XML file.
In the same folder as your FLA file, create a folder called 'pics'. In that folder create two others: one of them called 'small' (to contain the thumbnails) and another called 'big' (to contain the big images). In both folders you'll have the same folder structure: one folder for each theme.

Step 14: The Image Files
Each of your thumbnails should have the same name as its corresponding big picture. It's important that in the 'small' folder all the pictures should be 80px high to fit our UI. The size of the big images is not important, because we're going to resize them before adding them to the stage, but bear in mind that the maximum image size we will be able to show is 840px by 420px.

Step 15: Creating the XML File
Create a new text file in any file manager program and name it 'pics.xml'.
You can edit this file with any text editors like Notepad, but it's much easier to edit it with Flash.
Step 16: Editing the XML File
I will only tell you the things we need for XML to work properly, if you are interested in learning more about XML you can find plenty of tutorials here at Activetuts+ (like this one by Dru Kepple) or other pages on the web - and don't forget: Google is your friend ;)
In this XML file we're going to describe the folder structure (and the pictures within it), so that Flash can read and interpret it.
<pics> <theme name="The name of the theme"> <pic title="The title of the picture" filename="FilenameOfThePicture.jpg" /> </theme> </pics>
So, pics is the root element, and everything goes between the pics tags. If you want to add a new theme, you just copy and paste an existing theme element and change its attributes. If you want to add a new picture to one of the themes you just copy and paste a pic tag inside the right them, and change its attributes. The name attribute of the theme tag must be the same as the folder name, because that's where we're going to tell Flash to look for the file. Both name and filename are case-sensitive.
Step 17: Creating the Document Class
Click File > New and select ActionScript File. Copy and paste the following code.
package { public class Gallery extends MovieClip { } }
Basically this code doesn't do anything, but it says that this class is in the global package, and it's a public class called Gallery.
Step 18: The Constructor
The first function we start to write is the constructor. It's the basic function of the whole program, and will be the first code run when the SWF is started.
Copy and paste this code between the curly braces that go with the "public class Gallery extends MovieClip" line:
public function Gallery():void { }
Step 19: The URLLoader
The first thing we need to do is to load the XML file we created. We will do this with the help of the URLLoader class, which is in the flash.net package.
In order to use it, we need to import that package. Actually, let's just import every package we will need. Copy and the following code and paste it above the "public class Gallery extends MovieClip" line:
import flash.display.*; import flash.events.*; import flash.net.*; import flash.text.*; import flash.xml.*; import caurina.transitions.*;
Remember, imports will be always at the beginning of the code (after the 'package{ ' part), the declaration of the non-local variables will be before the constructor, and all the functions will be after the constructor.
In order for Flash to import that "caurina.transitions" package, you'll need to have this package in the same folder as your FLA and your document class. So, open up my Source zip file, and copy the \caurina\ folder into your project's folder.
After we've imported the packages we're going to need, we can declare - and create a new instance of - our URLLoader variable:
var urlLoader:URLLoader = new URLLoader();
(Put that code in the constructor function.)
Now we can tell Flash to load our XML file, and add an event listener to urlLoader:
public function Gallery():void { urlLoader.load(new URLRequest("pics.xml")); urlLoader.addEventListener(Event.COMPLETE, urlLoadComplete); }
So when urlLoader finishes loading pics.xml, Flash will run the urlLoadComplete function, which is our next thing to write...
Step 20: The urlLoadComplete Function
When the XML file is loaded we're going to have to put all the info it contains into an XML object. Then, in order to use that, we're going to need an XMLList object too:
//these are non-local variables var xml:XML; var list:XMLList;
After the constructor paste this:
protected function urlLoadComplete(e:Event):void { xml = new XML(urlLoader.data); list = new XMLList(xml.children()); }
Now, all the child nodes of the pics element - that is, all the theme tags - are in the list variable. If you want to see what's in there, paste 'trace(list);' after the second line of the urlLoadComplete function.
Step 21: Creating the Theme Buttons
In order to do this we'll need a for loop. So first we need to declare a loop-variable for the loop to work properly and an array for the themeButton objects:
//these are non-local variables var themeButtons:Array = new Array(); var i:int;
After the two existing lines of the urlLoadComplete function we'll have to start writing our loop:
for(i = 0; i< list.length(); i++) { //we create a new instance of the ThemeButton symbol var themeButton:MovieClip = new ThemeButton(); //we set the content of the textfield to the name of the theme themeButton.txt.text = list[i].@name; //we set the name of the textfield instance to be the same as its content themeButton.name = list[i].@name; //we add the click eventListener themeButton.addEventListener(MouseEvent.CLICK, themeClick); //we place the clips in a row with 10px padding themeButton.x = i*(themeButton.width+10); //we put the movieclip in the themes MC themes.addChild(themeButton); //...and in the themeButtons array also themeButtons[i] = themeButton; }
After this, we put all the buttons in the themes MC, then we align it to the center of the stage:
//change 450 to match the width of your stage themes.x = 450-themes.width/2;
You can test your movie now and see if it works. You should see your theme buttons (working like buttons) in a line...
Step 22: Moving the themeButtons
In order to have the themeButtons moving, we add a mouseMove eventListener to the stage; paste this in the constructor:
stage.addEventListener(MouseEvent.MOUSE_MOVE, slideTheme);
Before we write the slideTheme function, we declare another non-local variable:
//this will help calculate the position to which the themes should slide var ratio:Number;
In the slideTheme function we'll use the Tweener class - specifically, one function of that class, called addTween(). (You can read all about this class here.)
protected function slideTheme(e:MouseEvent):void { if(mouseY>470 && mouseY< 600)//we move the themeButtons if the cursor is the themeButtons-thumbs area { ratio = themes.width/850; //we move the themes MC if it is longer then the stage if(themes.width > 900) { //if it is longer, the position depends on the cursor's X position Tweener.addTween(themes, {x: (450-themes.width/2)-(mouseX-450)*ratio, time: 1}); } else { //otherwise, we align it to the center of the stage Tweener.addTween(themes, {x: (450-themes.width/2), time: 1}); } } }
Test your movie; the themes MC should move now (if it's longer than the stage).
Step 23: Variables for the themeClick Function
Before we begin to write the function, we need to declare some more non-local variables:
var j:int; //another loop-variable //if we click on one of the theme icons, it will be contained in this variable var themeClicked:MovieClip = new ThemeButton(); //the list of the pictures in a particular theme var picsList:XMLList; var smallPicSource:Array; //the thumb's source var bigPicSource:Array; //the big picture's source //this will contain all the thumbs var smallPics:Array; //this will contain the titles of the pictures in the selected theme var picTitles:Array;
Step 24: themeClick() Reset State
The beginning of this function takes care of resetting things when you click one of the themeButtons.
protected function themeClick(e:MouseEvent):void { //the whole function shall be executed only if the theme you selected is not the same as you selected just before if (themeClicked != e.currentTarget) { //makes the smallPicsMc invisible - it's on the stage, but it contains nothing yet smallPicsMc.visible = false; //removes the mouseMove eventListener - added afterwards stage.removeEventListener(MouseEvent.MOUSE_MOVE, slideSmallPics); j = 0; //resets the loop counter to zero
Step 25: themeClick() Clear Image and Text
If there was a picture on the stage (in the img Mc), it will be removed, and the title text field will be cleared:
if(img.numChildren > 0) { img.removeChildAt(0); } titleTxt.text = "";
Step 26: themeClick() Remember Clicked Theme
This part guarantees that the program will be able to 'remember' which theme you clicked on, by storing a reference in the themeClicked variable.
if (themeClicked != null){ //if it's not the first time you click on a theme themeClicked.alpha = 0.5; //the previous themeButton's alpha is set to 50% themeClicked.addEventListener(MouseEvent.ROLL_OUT, themeClicked.rollOut); //its rollOut eventListener is re-added } themeClicked = MovieClip(e.currentTarget); //the content of the themeClicked MC is changed to the themeButton you've just clicked on themeClicked.alpha = 1; //its alpha is set to 100% themeClicked.removeEventListener(MouseEvent.ROLL_OUT, themeClicked.rollOut); //...and its rollOut eventListener is removed
Step 27: themeClick() Filter XML
The next part of this function will filter the content of the list to just the elements from the theme you selected:
//loop goes through the themeButtons array for (i=0; i< themeButtons.length; i++) { //if the name of the themeButton you clicked on matches the current item in the array if (e.currentTarget.name == themeButtons[i].name) { //we make picsList contain all the <pic> elements from that theme picsList = new XMLList(list[i].pic); } }
Step 28: themeClick() Removal
If the smallPicsMc contains any items (that is, you've already clicked on some theme), we remove them all.
if (smallPicsMc.numChildren != 0) { for(i=smallPicsMc.numChildren; i>0; i--) { smallPicsMc.removeChildAt(i-1); } }
Step 29: themeClick() Filling the Arrays
If the selected theme has at least one picture, we fill the source arrays and the titles array and load the thumbs.
if (picsList.length() > 0)// if the picsList XMLList has at least 1 element in it { //we create new arrays //(if they have already been created, we clear their contents) smallPicSource = new Array(); bigPicSource = new Array(); smallPics = new Array(); picTitles = new Array(); //loop through picsList for(i=0; i< picsList.length(); i++) { //now we create the source path of the images smallPicSource[i] = "pics/small/" + e.currentTarget.name +"/" + picsList.@filename[i]; bigPicSource[i] = "pics/big/" + e.currentTarget.name +"/" + picsList.@filename[i]; //put the titles in the picTitles array picTitles[i] = picsList.@title[i]; } j = -1; //this will eventually load the small pics smallPicLoad(null);
Step 30: themeClick() Dealing With Empty Themes
If the selected theme doesn't have any pictures in it, we tell the user that it's coming soon.
else { //if img had a picture in it... if(img.numChildren > 0) { img.removeChildAt(0); //...we remove it } //then we write, instead of the title, that this theme is coming soon titleTxt.text = "Coming soon..."; }
Step 31: The slideSmallPics Function
This function does the same as the slideTheme function, but with smallPicsMc instead of the themes MC.
protected function slideSmallPics(e:MouseEvent):void { if(mouseY>470 && mouseY< 600){ ratio = smallPicsMc.width/850; if(smallPicsMc.width > 900) { Tweener.addTween(smallPicsMc, {x: (450-smallPicsMc.width/2)-(mouseX-450)*ratio, time: 1}); } else { Tweener.addTween(smallPicsMc, {x: (450-smallPicsMc.width/2), time: 1}); } } }
Step 32: The smallPicLoad function
This function loads the thumbs in the smallPics array and displays the loading process.
protected function smallPicLoad(e:Event):void { if (j < smallPicSource.length-1) { j++; //it tells the user which thumbs are loading now loadTxt.text = "Loading thumbs: " + (j+1).toString() +" / " + (smallPicSource.length).toString(); //creates a Loader object in the array smallPics[j] = new Loader(); //loads the next element of the smallPicSource array smallPics[j].load(new URLRequest(smallPicSource[j])); //if it's loaded, call this function again smallPics[j].contentLoaderInfo.addEventListener(Event.COMPLETE, smallPicLoad); } else { //if all of the elements of the array are loaded, call the smallPicComplete function smallPicComplete(); } }
This is kind of tricky so I'll give a more detailed explanation. It loads the thumbnails one by one; it's like a loop but I do the looping 'manually', almost recursively. This solution was needed because I wanted the thumbnails to appear at the same time. Recall that we set the visibility of the smallPicsMc to false, previously, so that we could reveal the thumbnails together.
[/sourcecode]
Step 33: smallPicComplete() Loading Pictures
First we have two other non-local variables to declare:
var bigClicked:String;//the source of the big picture var cpi:uint;//it stands for CurrentPictureIndex: it's the index of the picture which is shown
This is the first part of the function in which we load the first big picture, then fill the smallPicButtons array and the smallPicsMc.
protected function smallPicComplete(e: Event = null):void { bigClicked = bigPicSource[0];//sets the source of the big picture to the first one in the array loadPic(bigPicSource[0]);//calls the loadPic function with the same parameter cpi = 0; var smallPicButtons:Array = new Array();//this will store the created smallPicButtons for(i=0; i< smallPics.length; i++) { smallPicButtons[i] = new SmallPicButton();//we create a new instance of the SmallPicButton object in the smallPicButtons array smallPicButtons[i].addChild(smallPics[i]);//we put the matching element of the smallPics array to the smallPicButtons array if (i>0) { smallPicButtons[i].x = smallPicButtons[i-1].x+smallPicButtons[i-1].width+20;//beginning with the second element, we place them in a line as we did it with the themeButtons } smallPicButtons[i].data = bigPicSource[i]; //we set its data property to the source of the big image (so that we can use it as a link) smallPicsMc.addChild(smallPicButtons[i]); //we add the button to the smallPicsMc smallPicButtons[i].addEventListener(MouseEvent.CLICK, click);// we add a click eventListener to that button }
Step 34: smallPicComplete() Revealing Thumbs and Arrows
This is the second half of this function. Here we reveal the thumbnails and the navigation arrows (and set them to ready to be navigate).
smallPicsMc.visible = true; //we set the visibility back to true smallPicsMc.alpha = 0; //...but we set its alpha to 0%, so that we can do a little fade-in animation Tweener.addTween(smallPicsMc, {alpha:1, time:1}); //we fade in the smallPicsMc stage.addEventListener(MouseEvent.MOUSE_MOVE, slideSmallPics); //...then add the mouseMove event listener to it nextArrow.addEventListener(MouseEvent.CLICK, nextPic); //add a click event listener to the navigation arrows (nextPic, prevPic functions will be explained later) prevArrow.addEventListener(MouseEvent.CLICK, prevPic); prevArrow.visible = false; //since we're about to reveal the first picture there won't be a previous one, so we don't need the prevArrow yet nextArrow.visible = true; //we do need the nextArrow though prevArrow.buttonMode = true; nextArrow.buttonMode = true;
After commenting the lines where we call a function we haven't written yet, you will be able to test your movie, click on the theme buttons and have the thumbnails show up and sliding.
Step 35: The nextPic Function
This function loads the next picture in the row. It's triggered by clicking the nextArrow.
protected function nextPic(e:Event = null):void { if (cpi < bigPicSource.length-1)//if there is one more picture in the bigPicSource array { cpi++; loadPic(bigPicSource[cpi]); //load next pic } }
Step 36: The prevPic Function
This function loads the previous picture in the row. It's the reverse of the nextPic function, and triggered by clicking the prevArrow.
protected function nextPic(e:Event = null):void { if (cpi > 0)//if it's not the first picture we want to load { cpi--; loadPic(bigPicSource[cpi]); //load previous pic } }
Step 37: The click Function
Another non-local variable to declare:
var bigPic:String; //this will store the source path of the big image
This is the function called by clicking on a thumbnail:
protected function click(e:MouseEvent):void { //if this picture is not the same as shown already if (bigClicked != e.currentTarget.data) { if(img.numChildren > 0) //if there is already something in the img MC { img.removeChildAt(0); //we remove it } titleTxt.text = ""; //we set the title text field to empty //we store the source path of the big picture of the thumbnail bigClicked = e.currentTarget.data; bigPic = e.currentTarget.data; loadPic(bigPic); //pass the source path of the big pic to loadPic() } }
Step 38: loadPic() Clearing the Old
This function loads a big picture and takes care of the navigation arrows.
First we need to declare a Loader that will load the picture...
var bigLoader:Loader; //this will load the big picture
...and now, the actual function:
protected function loadPic(bigPic):void { if(img.numChildren > 0) //if this is not the first picture we load { img.removeChildAt(0); //we clear the previous one } titleTxt.text = ""; //and clear the title too
Step 39: loadPic() Loading the Image
Then we create the Loader object, start the loading, and add some listeners.
bigLoader = new Loader(); //we create the Loader object bigLoader.load(new URLRequest(bigPic)); //we start to load the big picture -- remember bigPic contains the source path of the big image bigLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progress); //call progress() whenever a bit more is loaded bigLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, bigLoadComplete); //and if the big picture is loaded we call the bigLoadComplete function
Step 40: loadPic() Figure Out Image's Index
Here we select the right index of the image we loaded. This is important because cpi tells us what picture we're at, and what title to show.
for (i=0; i< bigPicSource.length; i++) { if (bigPic == bigPicSource[i]) //if the source path of the images match { cpi = i; //we set the cpi to that index } }
Step 41: loadPic() Display or Hide Nav Arrows
Whether the navigation arrows are hidden or revealed depends on the value of cpi.
if (cpi > 0) //if this is not the first picture prevArrow.visible = true; //we show the prevArrow if (cpi == 0) //if this is the first picture prevArrow.visible = false; //we hide it if (cpi == bigPicSource.length-1) //if this is the last one nextArrow.visible = false; //we hide the nextArrow if (cpi < bigPicSource.length-1) //if this is not the last one nextArrow.visible = true; //we reveal it
Step 42: The Load Progress Handler
This function is executed whenever a new chunk of the picture is loaded.
protected function progress(e: ProgressEvent): void { //we write the percentage of the loading progress into the loadTxt dynamic textfield loadTxt.text = "Loading picture: " + Math.floor((e.bytesLoaded / e.bytesTotal) * 100) + "%"; }
Step 43: bigLoadComplete() Setup
The first thing this function does is set the contents of the text fields, and then set and get some properties of the loaded image.
protected function bigLoadComplete(e:Event):void { //the loading has ended and we don't need this text till the next loading loadTxt.text = ""; //we use cpi to get the title that belongs to this picture titleTxt.text = picTitles[cpi]; //we create a new bitmap object, and we put the picture in it var bitmap:Bitmap = e.target.content; bitmap.smoothing = true; var origWidth:Number = bitmap.width; var origHeight:Number = bitmap.height;
Step 44: bigLoadComplete() More Variables
We create some new variables so that we can resize the picture properly. They should go inside the bigLoadComplete() function.
var maxWidth = 840; //the width var maxHeight = 420; //and the height of the space where we want to place the picture // -- it depends on your layout //these will store the new size of the image var newWidth:Number; var newHeight:Number; //this variable is the ratio of the sides of the image //we will do the resizing with the help of this ratio var ratio:Number = origWidth / origHeight;
Step 45: bigLoadComplete() Set Picture Size
This part will set the new size of the picture.
//if one of the sides of the picture is longer than the space if (origWidth > maxWidth || origHeight > maxHeight) { //if the width-difference is bigger then the height-difference (portrait) if (maxWidth - origWidth > maxHeight - origHeight) { newHeight = maxHeight; //we set the height to the maximum newWidth = Math.round (newHeight * ratio); //then we set the length of the other side accordingly } else //if the orientation is landscape or shaped like a square { newWidth = maxWidth; //we set the width to the maximum newHeight = Math.round(newWidth / ratio); //then we set the length of the other side } } else //if the picture is smaller then the space { //the new size will be the same as the original newHeight = origHeight; newWidth = origWidth; }
Step 46: bigLoadComplete() Reveal the Image
We set the properties of the bitmap, then reveal it on the stage.
bitmap.width = newWidth; //set the resized width bitmap.height = newHeight; //and height of the image bitmap.x = -bitmap.width/2; //we set the x bitmap.y = -bitmap.height/2; //and y coordinates //(since the img MC is in the center we should align the bitmap to the center of the MC) img.addChild(bitmap); //we put the bitmap in the MC img.alpha = 0; //we set the alpha of the img MC to 0% so that we can fade it in Tweener.addTween(img, {alpha:1, time:1}); //we fade in the img MC
Conclusion
All right! We're done now! I hope you could understand the ideas in this tut (and enjoyed it too).
Thank you for reading!
Finally here comes the entire code:
package { import flash.display.*; import flash.events.*; import flash.net.*; import flash.text.*; import flash.xml.*; import caurina.transitions.*; public class Gallery extends MovieClip { var urlLoader:URLLoader = new URLLoader(); var xml:XML; var list:XMLList; var picsList:XMLList; var themeButtons:Array = new Array(); var themeClicked:MovieClip = new ThemeButton(); var i:int; var j:int; var smallPicSource:Array; var bigPicSource:Array; var smallPics:Array; var picTitles:Array; var bigLoader:Loader; var bigPic:String; var bigClicked:String; var cpi:uint; var ratio:Number public function Gallery():void { urlLoader.load(new URLRequest("pics.xml")); urlLoader.addEventListener(Event.COMPLETE, urlLoadComplete); stage.addEventListener(MouseEvent.MOUSE_MOVE, slideTheme); } protected function urlLoadComplete(e:Event):void{ xml = new XML(urlLoader.data); list = new XMLList(xml.children()); for(i = 0; i 0) img.removeChildAt(0); titleTxt.text = ""; if (themeClicked != null){ themeClicked.alpha = 0.5; themeClicked.addEventListener(MouseEvent.ROLL_OUT, themeClicked.rollOut); } themeClicked = MovieClip(e.currentTarget); themeClicked.alpha = 1; themeClicked.removeEventListener(MouseEvent.ROLL_OUT, themeClicked.rollOut); for (i=0; i0; i--) smallPicsMc.removeChildAt(i-1); } if (picsList.length() > 0) { smallPicSource = new Array(); bigPicSource = new Array(); smallPics = new Array(); picTitles = new Array(); for(i=0; i 0) img.removeChildAt(0); titleTxt.text = "Coming soon..."; } } } protected function smallPicLoad(e:Event):void { if (j < smallPicSource.length-1) { j++; loadTxt.text = "Loading thumbs: " + (j+1).toString() +" / " + (smallPicSource.length).toString(); smallPics[j] = new Loader(); smallPics[j].load(new URLRequest(smallPicSource[j])); smallPics[j].contentLoaderInfo.addEventListener(Event.COMPLETE, smallPicLoad); }else { smallPicComplete(); } } protected function smallPicComplete(e: Event = null):void{ bigClicked = bigPicSource[0]; loadPic(bigPicSource[0]); cpi = 0; var smallPicButtons:Array = new Array(); for(i=0; i0) smallPicButtons[i].x = smallPicButtons[i-1].x+smallPicButtons[i-1].width+20; smallPicButtons[i].data = bigPicSource[i]; smallPicsMc.addChild(smallPicButtons[i]); smallPicButtons[i].addEventListener(MouseEvent.CLICK, click); } smallPicsMc.visible = true; smallPicsMc.alpha = 0; Tweener.addTween(smallPicsMc, {alpha:1, time:1}); stage.addEventListener(MouseEvent.MOUSE_MOVE, slideSmallPics); nextArrow.addEventListener(MouseEvent.CLICK, nextPic); prevArrow.addEventListener(MouseEvent.CLICK, prevPic); prevArrow.visible = false; nextArrow.visible = true; prevArrow.buttonMode = true; nextArrow.buttonMode = true; } protected function nextPic(e:Event = null):void { if (cpi < bigPicSource.length-1) { cpi++; loadPic(bigPicSource[cpi]); } } protected function prevPic(e:Event = null):void { if (cpi > 0) { cpi--; loadPic(bigPicSource[cpi]); } } protected function loadPic(bigPic):void { if(img.numChildren > 0) img.removeChildAt(0); titleTxt.text = ""; bigLoader = new Loader(); bigLoader.load(new URLRequest(bigPic)); bigLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progress); bigLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, bigLoadComplete); for (i=0; i 0) prevArrow.visible = true; if (cpi == 0) prevArrow.visible = false; if (cpi == bigPicSource.length-1) nextArrow.visible = false; if (cpi < bigPicSource.length-1) nextArrow.visible = true; } protected function progress(e: ProgressEvent): void { loadTxt.text = "Loading picture: " + Math.floor((e.bytesLoaded / e.bytesTotal) * 100) + "%"; } protected function bigLoadComplete(e:Event):void{ loadTxt.text = ""; titleTxt.text = picTitles[cpi]; var bitmap:Bitmap = e.target.content; bitmap.smoothing = true; var origWidth:Number = bitmap.width; var origHeight:Number = bitmap.height; var maxWidth = 840; var maxHeight = 420; var newWidth:Number; var newHeight:Number; var ratio:Number = origWidth / origHeight; if (origWidth > maxWidth || origHeight > maxHeight) { if (maxWidth - origWidth > maxHeight - origHeight) { newHeight = maxHeight; newWidth = Math.round(newHeight * ratio); }else { newWidth = maxWidth; newHeight = Math.round(newWidth / ratio); } }else { newHeight = origHeight; newWidth = origWidth; } bitmap.width = newWidth; bitmap.height = newHeight; bitmap.x = -bitmap.width/2; bitmap.y = -bitmap.height/2; img.addChild(bitmap); img.alpha = 0; Tweener.addTween(img, {alpha:1, time:1}); } protected function click(e:MouseEvent):void { if (bigClicked != e.currentTarget.data){ if(img.numChildren > 0) img.removeChildAt(0); titleTxt.text = ""; bigClicked = e.currentTarget.data; bigPic = e.currentTarget.data; loadPic(bigPic); } } protected function slideSmallPics(e:MouseEvent):void { if(mouseY>470 && mouseY< 600){ ratio = smallPicsMc.width/850; if(smallPicsMc.width > 900) { Tweener.addTween(smallPicsMc, {x: (450-smallPicsMc.width/2)-(mouseX-450)*ratio, time: 1}); } else { Tweener.addTween(smallPicsMc, {x: (450-smallPicsMc.width/2), time: 1}); } } } protected function slideTheme(e:MouseEvent):void { if(mouseY>470 && mouseY< 600){ ratio = themes.width/850; if(themes.width > 900) { Tweener.addTween(themes, {x: (450-themes.width/2)-(mouseX-450)*ratio, time: 1}); } else { Tweener.addTween(themes, {x: (450-themes.width/2), time: 1}); } } } } }
Envato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post