Creating an XML Gallery with ActionScript 3.0
For any dynamic Flash project, XML will be a powerful tool. One of the most common examples (and one of the simplest) is a picture gallery like the one I have here:
Images came from http://www.stockvault.net/
I will be talking about how to use Flash and XML to make a simple, yet superfly, gallery.
So, let us start off by looking at my XML file’s structure:
<img id=‘0′ file="photo_7030_20070301.jpg" width=‘500′ height=‘375′>
Cute Puppy! Who couldn’t love that face?
</img>
<img id=‘1′ file="photo_4095_20070301.jpg" width=‘500′ height=‘375′>
Three Friendly Cats.
</img>
<img id=‘2′ file="photo_4281_20070301.jpg" width=‘500′ height=‘375′>
The Terror of the UnderSofa!
</img>
<img id=‘3′ file="photo_6257_20070301.jpg" width=‘500′ height=‘375′>
Bored? Let’s play catch!
</img>
<img id=‘4′ file="photo_6882_20070301.jpg" width=‘500′ height=‘377′>
It may be natural, but this picture still feels weird to me.
</img>
<img id=‘5′ file="photo_7241_20070301.jpg" width=‘500′ height=‘375′>
My cats hate the snow.
</img>
<img id=‘6′ file="photo_7538_20070507.jpg" width=‘500′ height=‘622′>
<![CDATA[<I>LOOK</I> IT'S <B>HTML</B>!!!]]>
</img>
<img id=‘7′ file="photo_7915_20070609.jpg" width=‘500′ height=‘371′>
Skinny cats are OK too.
</img>
</gallery>
XML is very simple to understand if you know anything about HTML’s tag structure. The XML document has a root tag <gallery> that has an attribute dir=”//url/Photos/”. Every tag has to be closed within it’s own level of the tree. Our gallery tag is closed at the bottom of the document with </gallery>. This means that all the <img> tags are elements inside the gallery element (both open and close tags combined make up an element).
Our <img> tags have several attributes, such as the images file name and it’s pixel demensions. Inside each <img> element we have a short comment about the image that will be displayed in a TextField in our Flash movie.
One important thing to notice here is that if you want to have HTML in your TextField then you need to tell the code that something is a string containing HTML and not more elements. We do this with a special bracket <![CDATA[ HTML GOES HERE ]]> Isn’t that GREAT! That right there probably made this whole tutorial worth while (that was a problem that took me a long time to solve).
OK, now that we’ve looked at the XML we need to make it work with ActionScript 3. In Adobe Flash CS3 I created a new AS3 FLA doc and a new AS doc. In the FLA I simply created some very basic MovieClips for my left and right arrows and I placed a TextField at the bottom of my stage (which I set to 600 X 700 with a black background). After naming my instances and setting up the Document Class linkage I was done with the FLA side of thing and the rest is ActionScript.
Our Document Class has to extend MovieClip so we take our first steps thusly:
public var currentImg:Number;
public var lastImg:Number;
public var xml:XML;
public var loader:Loader;
public var xmlLoader:URLLoader;
public function Main() {
loader = new Loader();
addChild(loader);
xmlLoader = new URLLoader(new URLRequest("//url/gallery.xml"));
xmlLoader.addEventListener(Event.COMPLETE, parseXML);
left_mc.stop(); //Need to stop the arrows from flickering
right_mc.stop();
}
}
In our constructor we are initializing our Loader which will contain the loaded images and we are loading our XML document. When the XML doc is done loading, the function parseXML will handle the content.
left_mc.addEventListener(MouseEvent.MOUSE_UP, nextImg);
left_mc.addEventListener(MouseEvent.MOUSE_OUT, arrowOut);
left_mc.addEventListener(MouseEvent.MOUSE_OVER, arrowOver);
right_mc.addEventListener(MouseEvent.MOUSE_UP, prevImg);
right_mc.addEventListener(MouseEvent.MOUSE_OUT, arrowOut);
right_mc.addEventListener(MouseEvent.MOUSE_OVER, arrowOver);
xml = new XML(event.currentTarget.data);
lastImg = xml.img.length() – 1;
currentImg = 0;
loadImg();
}
I’ve recently gotten into the habit of using protected functions rather then private functions. There is only one difference between the two and that’s that private anything won’t be inherited by child classes.
In this function I set the MouseEvents for the arrows because if the XML failed to load, there would be no reason for the arrows to work.
Alright, so I saved my XML tree in the var xml for ease of use later. I also saved the number of images in my XML doc using the length() method. Something to know about the length method is it will only tell you how many elements there are of that tag type at that level. For example, if I were to have child elements inside my img elements that would not affect the return value of xml.img.length(); It’s only telling you how many img elements are children of gallery (gallery is accessed with the var xml directly).
loader.x = (stage.width – Number(xml.img[currentImg].@width))/2;
loader.y = (stage.height – 50 – Number(xml.img[currentImg].@height))/2;
loader.load(new URLRequest(xml.@dir + xml.img[currentImg].@file));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadFin);
}
protected function loadFin(event:Event):void {
textDisp_TF.htmlText = xml.img[currentImg];
}
In that first function I’m just going to focus on the one line with the URLRequest. In order to traverse an XML tree you need start with the base. Your XML var (in our case it’s called xml) points to that base (in this case the base is gallery). So when we want to access the attribute dir in the tag gallery, we need to type xml.@dir and this will return “//url/Photos/”. The ‘@’ symbol denotes that it’s an attribute and not an element (tag).
Getting the file name is just one step further. currentImg is a Number variable that stores which image we are on. Thinking of our XML var as something similar to a bunch of nested arrays we can see how you might access a specific file name with xml.img[currentImg].@file This says we want the file attribute in the [currentImg] (first second so forth) img element which is in our base element. There are quite a few ways of finding what you need in an XML doc and you can learn more about them here.
In the second function we are displaying the text from within our XML img element. Here we aren’t accessing any attributes or anything, this is where we get the content between the open <img> and close </img> tags.
Finally we have the arrow MouseEvent handlers:
MovieClip(event.currentTarget).gotoAndStop(1);
}
protected function arrowOver(event:MouseEvent):void {
MovieClip(event.currentTarget).gotoAndStop(2);
}
protected function nextImg(event:MouseEvent):void {
loader.unload();
currentImg = (currentImg < lastImg)? currentImg + 1 : 0;
loadImg();
}
protected function prevImg(event:MouseEvent):void {
loader.unload();
currentImg = (currentImg > 0)? currentImg – 1 : lastImg;
loadImg();
}
Once again I’m using the less obvious form of the if..else statement.
num = 5;
}else {
num = 0;
}
//OR, THIS NEXT PART DOES THE SAME THING
num = (num>5)? 5 : 0;
Well that’s about it for this level of a gallery. You can make galleries look really nice with fade transitions between images, small loading animations for larger images, scrollable thumbnail selection menu… etc.
Here is a downloadable source of my example file (images not included… get them here): XMLGallery.zip









Great tips.
Nice tutorial, except for the xml example you have on the webpage… it ain’t no XML!
The file in zip is ok tho.
DANG IT! Every time I edit this post, that bit of code gets messed up by the auto formating in WordPress. I think I fixed it -AGAIN- but I can’t guarantee that it will be like that forever.
Please refer to the XML document in the Downloadable source files if it is screwy again in the future.
Hi this is pretty cool!!
do you know how to make the gallery running on its own lets say the slides will change automatically every 3 sec.
thanks
Sure, ActionScript 3.0 has a Timer class. All you have to do is create a timer object with the interval settings that you want and then it will give you an event to handle at that set interval.
Timers are great and I would recommend using them in place of the ENTER_FRAME event for most games. I say that because the frame rate might change while the game is running (too many graphics) but with a timer, things will still proceed at the same rate.
Nice tutorial. Is there any way to add a progress bar to images loaded from XML?
Nice work, I want to overlay an image on top of the loader how do I arrange this?
I set up layers in my fla (stage) with my frame image above the main layer but I still have the loader poping on top ov everything else.
I figure there is probably a really simple explanation for this …
Cheers :)
Mike, you just have to add the loader as a child at a lower index. addChild(mc); will add the child at the top automaticaly and thus your frame image is being covered.
Try using addChildAt(loader, 1); to place the loader at a lower index then the frame image.
You might need to experiment with the index value a little to get it right.
This is a smart trick to gets the pictures from outside flash, but if i use this way, i still need to use, dreawaver to publish the site in flash?
What is Xml realy in this toturial ?
How can i gets pictures from a file in my pc?
cumps…
hi,
I’m having a little problem, i gues it is in the xml becaus when i try to run it, i get an error that he cant find my url…
I have the fla and xml file then a map images …
I have tried multiple urls also made my own xml but i wont work…
Help? :)
I’m VERY new to xml & flash. Can you show me how I might use the timer class with your code above? Would the timer obj replace your AddEventListener’s for the l & r mouse mc’s?
hi,
got the same problem. I get Error #2044 when i test swf. flash can’t find any xml.
I’ve got xml in the root and images in /Photos folder.
Same problem:
Error #2044: Unhandled ioError:. text=Error #2032: Stream Error. URL: file:////url/gallery.xml
at Main()
… I’m glad to see people still read my tutorials, but seriously, //url/gallery.xml is NOT a real location. It’s just a placeholder that you are supposed to replace yourself with a correct URL to your own XML file. That’s why you guys are getting #2044 errors.
Wow thanks mate!
Was searching for this :D
Maybe if you still read this, you can anwser 2 questions about it. I used your script and stuff. But is it possible to use an effect between each picture? like fade in and fade out?
And my second question is if it is possible to arrange the pictures one step to the background? Because it is now going over my other pictures :P
thx in advance :D
Possible? Of course it’s possible, Flash is awesome. Check out this tutorial for a cool carousel effect.
Of course, for a simple fade effect. You just need to load the second image behind the first and then fade the first out after load completes.
Nicee! thanks man :D
Going to check some things out, and hope it works!
Bye,
Jtbfolio.nl
o after my website is done i will give a link to your website!
hey,
I was just wondering how you fix the url error. I know gallery
“//url/gallery.xml” isn’t a real location ..however when i change that to a real location I still get the error.
Any suggestions ???
Oh and fantastic tut buddy …thanks for the help :)
hooooo exelent
What about the puppy? No one says anything about him!
He may bite you one day you know?
:D
My images are not showing up and I can’t seem to figure out why. I have put the correct extensions in and the correct URLs, any thoughts?
M
Thakns for the tutorial, I am new to Flash and XML and have a little problem finding the right things but I think I get it.
Is there a way to have the image load into a movie clip? How would i give a class specification to that instead of the stage alone? Or would I have to do it differently?
Also, how could I display a ‘picture 1 of 10′ somewhere?
Thanks a lot!