Create a Shuffle Gallery in Flash Using XML and ActionScript 3.0

In this tutorial I’ll explain how to access and use the Display List whilst creating an XML based image gallery with ActionScript 3.0.

Step 1: Overview

Using XML we’ll dynamically load and obtain information about the images, give them a random center position, add a frame, add drag functionality, and lastly, we’ll use a tween to handle the zoom animation.

Step 2: Let’s Get Started

Open Flash and create a new Flash File (ActionScript 3).

We’re going to add a preloading animation to tell the user when the content is loading. In this case I used the Apple inspired preloader that we created before. Since we’re going to use only the animation, there’s no need to import the class or use an Export Identifier.

Place the preloader on the stage and center it.

Step 4: Embedding a Font

We’re going to embed a font, a super easy task when adding a TextField to the Stage in the Flash IDE, but a little different using ActionScript.

Open the Library Panel and right-click in the items area without selecting one, a contextual menu will appear.

Click on "New Font" to open a dialog window, give a name to your font and select the one you want to use as shown in the following image.

This will create a class of the font you selected, we’ll instantiate this in Step 9.

Step 5: XML

Let’s create the XML file.

Open your prefered XML or Text editor and write:

<?xml version="1.0" encoding="UTF-8"?>

<images>
<image src="images/image.jpg" title="This is image 1"/>
<image src="images/image2.jpg" title="This is image 2"/>
<image src="images/image3.jpg" title="This is image 3"/>
<image src="images/image4.jpg" title="This is image 4"/>
<image src="images/image5.jpg" title="This is image 5"/>
</images>


When you’re done, save it as "images.xml" in your xml folder.

Step 6: ActionScript

The code that we’ll use will be written in a single class that will be used as the Document Class in the FLA file.

Create a new ActionScript File (File > New)

Save it as "Main.as".

Step 7: Package

We’ll begin with:

package classes
{

The package keyword allows you to organize your code into groups that can be imported by other scripts, it’s recommended to name them starting with a lowercase letter and use intercaps for subsequent words for example: galleryClasses.

If you don’t want to group your files in a package or you have only one class, you can use it right from your source folder, but the idea is to be organized.

Step 8: Required Classes

import flash.display.Sprite;
import flash.display.MovieClip;
import flash.net.URLRequest;
import flash.events.Event;
import flash.filters.BitmapFilter;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.text.AntiAliasType;
import flash.events.MouseEvent;
import fl.transitions.Tween;
import fl.transitions.easing.Strong;
import fl.transitions.TweenEvent;

These are the classes that we’ll need to make this gallery. If you need help with a specific class please use the Flash Help (F1).

Step 9: Extending the Class

public class Main extends MovieClip
{

The extends keyword defines a class that is a subclass of another class. The subclass inherits all the methods, properties and functions, that way we can use them in our class.

We’re going to use MovieClip specific methods and properties so we extend using the MovieClip Class.

Step 10: Variables

var xml:XML; // The XML Object that will parse the XML File
var images:Array = new Array(); //This array will store the images loaded
var imagesTitle:Array = new Array(); //The title properties of the XML File
var tween:Tween; //Handles the animation
var zoomed:Boolean = false; //Checks if a picture is zoomed, false by default
var canClick:Boolean = true; //Checks if the user can click a picture to zoom it, true by default
var lastX:int; //Stores the x property of the last picture that was clicked
var lastY:int; //Stores the y property of the last picture that was clicked
var textformat:TextFormat = new TextFormat(); //A TextFormat Object
var screen:Sprite = new Sprite(); //A black screen to focus on the active picture

var formatFont:Avenir = new Avenir(); //This is the embedded font

Step 11: Constructor

The constructor is a function that runs when an object is created from a class. This code is the first to execute when you make an instance of an object or when using the Document Class.

In this function we’ll set the properties of the TextFormat object that we’ll use to display a title or a description of each image. Create the black screen that appears when the user clicks on a picture and call the function which loads the desired XML file.

public function Main():void
{
textformat.color = 0xFFFFFF;
textformat.font = formatFont.fontName;
textformat.size = 17; //Use the same size you used when embedding the font from the Library

screen.graphics.beginFill(0x111111, .75);
screen.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
screen.graphics.endFill();

}

This function loads the XML file provided by the "file" parameter. We also add a listener to handle when the load is complete.

private function loadXML(file:String):void
{
var urlReq:URLRequest = new URLRequest(file);

}

Step 13: Parse XML

Here we convert the loaded XML file to a valid XML object using the parameter "data" of the URLLoader. Then we use a "for" statement to create a Loader for every image in the XML. Additional information is found in the commentary.

private function handleXML(e:Event):void
{
xml = new XML(e.target.data);

for (var i:int = 0; i < xml.children().length(); i++)
{

imagesTitle.push(xml.children()[i].@title); //Adds the title attribute content to the array to use it outside this function

}
}

When a Loader has loaded an image from the XML, the following code is executed:

private function loaded(e:Event):void
{

{
prepareImages(); //This function is explained in the next step
}
} 

Step 15: Prepare Images

This function will add the frame, the TextField to display the title or description, the black background used for that and a Shadow Filter. Let’s take it in parts.

private function prepareImages():void
{
for (var i:int = 0; i < images.length; i++) //These actions will be applied to all the images loaded so we use a "for" and the "images" array to do that
{
var container:Sprite = new Sprite(); //A container that will store the image, frame, TextField, TextField background and shadow
var frame:Sprite = new Sprite(); //The Frame Sprite
var infoArea:Sprite = new Sprite(); //The TextField background
var infoField:TextField = new TextField(); //The TextField

Step 16: Image Frame

This creates a white frame around the image.

frame.graphics.beginFill(0xFFFFFF);
frame.graphics.drawRect(-20, -20, images[i].width + 40, images[i].height + 80);
frame.graphics.endFill();

The rectangle will be positioned under the image to be used as a frame.

Step 17: Information Background

This creates a black rectangle in the bottom part of the image, where the TextField will be.

infoArea.graphics.beginFill(0x111111, 0.75);
infoArea.graphics.drawRect(0, 0, images[i].width, 60);
infoArea.graphics.endFill();
infoArea.y = images[i].height - 60;

Step 18: Image Information

The following code sets the TextField properties and adds its contents.

infoField.defaultTextFormat = textformat;
infoField.embedFonts = true; //You have to add this to use the embedded font
infoField.antiAliasType = AntiAliasType.ADVANCED; //This property will display the text more clearly
infoField.width = images[i].width - 5;
infoField.height = 20;

infoField.text = imagesTitle[i]; //The content, obtained from the XML and stored in the Array

Step 19: Resizing the Images

Here we set the desired scale of the images. Since everything will be inside the Container Sprite, we only need to resize it.

container.scaleX = 0.3;
container.scaleY = 0.3;

Step 20: Position

The images will have a random position based on the center of the Stage area. We use Math for that.

container.x = stage.stageWidth / 4 + Math.floor(Math.random() * (stage.stageWidth / 4));
container.y = stage.stageHeight / 5 + Math.floor(Math.random() * (stage.stageHeight / 5));

This will create a Shadow Filter.

var shadowFilter:BitmapFilter = new DropShadowFilter(3, 90, 0x252525, 1, 2, 2, 1, 15); //Distance, angle, color, alpha, blur, strength, quality

container.filters = filterArray; //Apply the filter

Time to add the Children, the order in which we add them is the order they will take in the Display List, so be sure to add them in this way.

infoArea.addChild(infoField); //Adds the TextField to the TextField Background

container.addChild(images[i]); //Adds the Image on top of the Frame in the Container

infoArea.visible = false; //We set the image information to invisible by default

container.addChild(infoArea); //Adds the information area in top of everything

Step 23: Listeners

Although we could add the Listeners to every Sprite before, I’m going to add them now that they are inside the Container to show you how the Display List works.

container.getChildAt(1).addEventListener(MouseEvent.MOUSE_UP, zoomHandler); //This is the Image loaded by the XML, this is the Loader object
container.getChildAt(0).addEventListener(MouseEvent.MOUSE_DOWN, dragImage); //This is the Frame



Step 24: Drag Functions

In the previous step we added two listeners to the Frame of the images. These functions will take care of the drag.

We use "parent" beacuse we want to drag all the objects, since the "target" is the Frame Sprite, the parent object is the Container.

private function dragImage(e:MouseEvent):void
{
e.target.parent.startDrag();
}

private function stopDragImage(e:MouseEvent):void
{
e.target.parent.stopDrag();
}

Step 25: Zoom

This function is in charge of zooming in and out. Its Listener is in the actual image, so clicking in the Frame will not call this function.

Editor’s Note: For some reason, the else if () statement within this zoomHandler function was making our syntax highlighter crash. As it doesn’t want to display on the page, I’ve made the function available for download. Sorry for any inconvenience, Ian.

Step 26: Motion Finish

Some actions need to be executed when the Tweens are finished, these are those actions.

private function zoomInFinished(e:TweenEvent):void
{
zoomed = true; //Modify the variables according to the event
canClick = true;
tween.obj.getChildAt(2).visible = true; //Sets the Information area to visible
}

private function zoomOutFinished(e:TweenEvent):void
{
zoomed = false;
removeChild(screen); //Removes the black screen

}

Step 27: Document Class

Go back to the FLA and add Main as the Document Class in the Properties Panel. If you save your class in a package you have to add the name of the package too, something like: yourpackage.Main

Conclusion

As always, try different things in your code to make the gallery just as you want.

I hope you enjoyed this tut, thanks for reading!

• André

Nice work, congratulations!!

It would be better if you created Objects extending the Sprite class to use as the Objects container, but this is also great work, thanks for sharing.

• Florian

swapChildren(getChildAt(this.numChildren-1),e.currentTarget.parent);

in the MOUSE_DOWN handler, making it appear to the top instead of having the user move the covering photos to see what’s below :)

• André

I agree!! nice observation.

Also works:
setChildIndex(e.currentTarget,numChildren-1);

• estranged

cute….. but dude change your picture, is horrible!

• http://republik9.com Erick

I agree. Nice Work. Get Some Porsche Design Shades.

• http://www.karlmacklin.com Karl Macklin

I agree, clicking on a picture should bring it to the front. Several ways to do it, some already mentioned.

• http://flashden.net/user/msfx?ref=MSFX MSFX

You’ve got a bug :(

If you click and drag an image and release it over another image the dragged image keeps moving to the mouse position… you need to attach your mouse up listener to the stage, not to the object being clicked…

• Tyson Stecklein

I would change this line from this:

to this:

and move this line of code into the “dragImage” function.

If you are dragging something beyond the edge of the stage it won’t “hear” your mouse up unless it’s over the dragable object, but if you add it to the stage, it’ll hear the mouse up from anywhere on the stage (even outside the stage area). This way the image won’t stick to your cursor if -while dragging a pic – your mouse goes outside the stage area, mouse up and then return to the stage area.

inside the “stopDragImage” you may want to remove your listeners as well (a good habit to better manage memory)

nice tut!

• André

function mouseDown(e:MouseEvent):void{
e.currentTarget.startDrag();
setChildIndex(e.currentTarget as DisplayObject,numChildren-1);
}
function mouseUp(e:MouseEvent):void{
stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_UP,mouseUp);
}

• http://labs.dariux.com Dario Gutierrez

Cool animation effect dude!!! And your code is awesome. Good tut!

• Robert West

Cool look for sure, the color background changes as the image is opened, to a darker gray? Interesting. Only other thing is I can’t seem to see all the other images, its like a game to find a pattern that will work to view them all. -Cheers!

Keep up the flash!

• royal

Terrible interaction design. Won’t work in many cases for many reasons

• yalor

Can you exlain this a bit more? (Strange to say its terrible without any explainations)

• http://www.dsaportfolio.com.br/ Diego SA

Interesting gallery. Could be improved adding some angle changing when dragging a photo to somewhere. Would be a little more realistic.

• Andy

can’t open the source .fla. Was it done with CS4?

• http://republik9.com Erick

yea i don’t think CS3 does not open CS4 files

• http://snaptin.com Ian Yates
Staff

Carlos has since provided CS3 compatible source files – try the download again and it should be OK.

• darren

hi.. im a beginner at flash.. but i seem to have some problems downloading the file.. when i open the source file, the ShuffledGallery.fla with my Adobe Flash CS3, it gives me an unexpected file format error.. anyone could help?

• Dig

Hey, someone can tell me what should i do if i wish to set the photos like it was threw in the stage? I mean some rotated photos, almost the same as Diego SA said before.

• Martijn

Nice looking tutorial!
Pretty easy to follow, although I got mine version not working and even with the downloaded source files I had to puzzle.
Also the CS3file contains as code, is that needed to set in the external as file?
And when I thought I had everything correct, I get this error?
TypeError: Error #1085: The element type “meta” must be terminated by the matching end-tag “”.
at classes::Main/::handleXML()
at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()

I don’t understand it.
Thanks

• Martijn

You can delete the message above.
I downloaded it again and replaced the fla with the cs3 version. And now it works.
Now reading the tutorial to find out how it works.
Thanks again!

• frank

this was a horrible idea, come on man do you really thing this is worth making? add 10 minutes to it and its great otherwise its rubbish, really man?

• Andy

Works good. My issue is this: I want to use this as an external file to load within a shell file. But I’m running into problems loading it. I’m using an empty movie clip as my target to load the external swf into. I’ve tried this with a simple swf with a box in it and it works fine but trying to load this image gallery gives me an output message that reads:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at classes::Main()

It’s been suggested that there needs to be a way for the Main.as to know that there’s a shell file…I guess kind of like informing it that there’s life outside of it’s little world. Anyone any any insight?

• TonyMO

Time consuming to load data…Need to enhance the profiency

• btamayo

Is there a way to use an image as a frame container? I want to use an actual poloroid image?

• Andy

has anyone else had problems using any of the Greensock classes with this? I know that’s a long shot question but I’d like to know if any one has and how they resolved it.

Hit me up.

• Dean

Hey, this is really great! Thanks for sharing!!!

• Rich

I am trying to integrate this code into another flash file and can not for the life of me do it, anyone offer any help?

• http://spacemultimedia.com krishnakore

U people r doing an excellent job….. keep help each other…………….

• Justin

Hey I’m getting a #2032 error and I’m not sure what’s causing it. My file structure is exactly the same as the source code.

• http://www.autodvd.net jameslin

It doesnt support Firefox?
It shows the loader all the time when you open it in Firefox.

• http://snaptin.com Ian Yates
Staff

Your browser shouldn’t have anything to do with it (I don’t see any problem in Firefox..) Try again?

• http://fabien-dupuis.com Fabien

Hi, I’am getting an “TypeError: Error #1009: Cannot access a property or method of a null object reference.
at classes::Main()”
when i try to load the external swf…. What can i do ?

• Pingback: BEST AJAX EXAMPLES - Nagpur

• Josefina

Hi,
I’m newbie, so i developed and tried too this example it doesn’t make any error but doesn’t load the images, so i try to open the downloaded source but cannot open cause it says the format is inexpected i appreciated if some body could help me. sorry!!

thanks

• http://123doing.com 123doing

It’s very good.
I like this.
Thanks for share.
And I wrote something to introduce this project for my readers.
If something is wrong,pls figure it out.thanks.

• http://www.g2.com.co Xavier serrano

Hola,

estoy necesitando esta galeria con la siguiente modificacion….”La Galeria Utiliza las fotos del profile del facebook del navegante. ”

Un ejemplo es http://www.5react.com

Si alguien la tiene, mi email es xserrano@g2.com.co

un saludo para todos

• sergio_f

Hi.
Great tutorial.

I was just wondering if anyone could tell me how can I after zooming an image, navigate to other images linked to the one opened. See this case:

- zoom to image 1 which is a car.
- when zooming you can click an arrow and it will show another image linked to image 1, for instance the engine of the car.
- you click again and the following image is a photo of the interior of the car.
- imagine doing this with maybe 6 or 8 photos or linked to the first one.

Would really appreciate some help with this.
Thank you and keep up the good work ;)

• Andrew Obahor

Just finished this lovely tutorial but, got this “Error #2044: Unhandled IOErrorEvent:. text=Error #2035: URL Not Found.” Please can someone advise me what to do, I have tried all I could but nothings work…I’m using CS5

Thanks