Visit our archive

Yes, we know, there are a million different Flash Image Gallery tutorials out there ! So why are we writing this one so late in the game? Mostly because when we scour the Flash / Actionscript forums, there are still hundreds of questions about how to load images from XML, or how to build image galleries in general. What we are going to try to do here is break the process of creating an Image Gallery down into some concrete steps that can be broken out and used as needed in any photo application or otherwise.

This is what we are going to be building today, the source can be downloaded by clicking here:
get flash player Flash Image Gallery Tutorial

Step 1 – Decide what is needed
A lot of people think that an image gallery is super simple and they can just dive into building something, only to discover that there is something that they missed and they have to restart. Having done that countless times in the past, we start every project with a pen and paper and write out all the requirements. We sketch out basic interfaces, figure out the different modules that are going to be needed, and break the application down into as small pieces as possible before we start. Here is a simplified example:

Photo Gallery Application

  • need to load images dynamically
  • easily updatable.. the client is going to want to change or add? Should use XML
  • smooth transitions between images.. will the client want to control timing? What about different transition types?
  • What will the interface look like? Will there be multiple categories?
  • How will the user navigate through images? Will there be arrows on the left and right? Thumbnails at the bottom? Will the thumbnails need navigation arrows?
  • What version of flash should this be built in? Does the client want this on mobile devices too? Is Flash the best solution?
  • Are all the images going to be local? Will they all be in the same folder? If they aren’t local, will my application have access to the remote image files? Who do I have to contact about setting up a crossdomain.xml file on the remote server?
  • What happens if there is an error loading the image? Will an error message be displayed? *this is something that is often overlooked, but necessary.
  • What is the loader going to look like? Should the application preload images or just load on demand?

If you can answer most (if not all) of those questions, you are in good shape to start on the actual building of the image gallery.

Step 2 – What should it look like
We are going to build a very simple image gallery application with all local images located in the same folder in this tutorial, as such, the design is going to be quick and easy. If you take a look at the tutorial files you will find /src/ImageGallery_basic_interface.fla. We ordinarily use Flash Builder to make any application, but for simplicity sake, we are using the Flash IDE in this tutorial.

Step 3 – Setup the Data
A lot of times, when starting out with Flash, the data file would be an afterthought because it is something that is not REALLY needed. After years of development, we have discovered that it is actually quite important so there is no point in beating around the bush. Just create your XML file from the beginning and work with it throughout development. You can always go in and change the structure and data, but at the very least you will have the data tied in from the get-go.

Here is a sample of the XML file that we will be using for this Image Gallery:



	
		 Flash Image Gallery Tutorial
		 Flash Image Gallery Tutorial
		 Flash Image Gallery Tutorial
		 Flash Image Gallery Tutorial
		 Flash Image Gallery Tutorial
		 Flash Image Gallery Tutorial
		 Flash Image Gallery Tutorial
		 Flash Image Gallery Tutorial
		 Flash Image Gallery Tutorial
	

As you can see, it is very simple. It contains the image path and the thumbnail path, that is all. If you would like to get a little more complex, you could add a transition attribute that would eventually control the type of transition that is displayed between images. You could add a duration that would be used in a slideshow. The data container in the application, that we are building next, is where you can manage all of this within the Flash world.

Step 4 – Manage the data
Now that you have some basic information about the images and thumbnails, you need to get that into your application. We use a simple singleton class for most data management that loads the XML, and has methods setup to return any of the information you need from the XML. It is a good idea to setup something similar to this for your applications and just pop it into your new projects as you create them. Take a look at /src/com/cultcreative/core/model/DataModel.as to see what we are going to be using here. The bulk of the XML loading is done with the following:

public function loadXML(ARG_xmlFile:String):void {
	// initialize by getting the data from the XML
	var loader:URLLoader = new URLLoader();
	loader.addEventListener(Event.COMPLETE, loadXMLComplete);
	loader.addEventListener(IOErrorEvent.IO_ERROR, xmlLoadError);
	loader.load(new URLRequest(path + ARG_xmlFile));	
}

private function xmlLoadError(ARG_evt:IOErrorEvent):void {
	trace(this.toString(), ARG_evt);
	if (!local) {
		local = true;
	
		var loader:URLLoader = new URLLoader();
		loader.addEventListener(Event.COMPLETE, loadXMLComplete);
		loader.addEventListener(IOErrorEvent.IO_ERROR, xmlLoadError);
		loader.load(new URLRequest("xml/data.xml"));	
	}
}

private function loadXMLComplete(ARG_event:Event):void {

	_loaded = true;
	XML.ignoreWhitespace = true;

	// get the loaded xml
	_xmlData = new XML(ARG_event.target.data);
	
	// dispatch the loaded event
	var _evt:Event = new Event(Event.INIT);
	dispatchEvent(_evt);
	
}

The code above uses a URLLoader to load the XML data. If there is an error, it defaults to an xml file (you can change or remove this as required). If it is successful, it captures the xml to the xmlData variable in the class and dispatches an event to tell any listeners that the data has loaded correctly.

DataModel has 3 main calls for the Image Gallery that you can get data with:
getNumImages():Number – this function will return the number of images that are stored in the XML. You will find this used by the next button, the thumbnail next button and the thumbnail loader.
getImage(ARG_id):String – this function will return the image page for the specified image (ARG_id). This function is used every time an image is to be loaded.
getThumb(ARG_id):String – this function acts exactly like the getImage function, except it returns the thumSRC value from the XML. It is used at the beginning of the application when the thumbnails are being loaded.

Step 5 –Tell Flash What to Do
This is the big step. This is where the interactivity is setup, the thumbnails are loaded and the bulk of the coding is done.

a) load the XML using the DataModel
there are a couple of things that are built into the DataModel that we are going to be using: the path value, the loaded value and the loadXML function. People like to store XML files all over the place on their server, it is always a good idea to setup a flash var so that this path isn’t hardcoded in the Flash. We use the following:

var xmlPath:String = (root.loaderInfo.parameters['xmlPath'] != undefined) ?  root.loaderInfo.parameters['xmlPath'] : "xml/";

This checks to see if there is a parameter setup, it uses it if there is one but sets a default if there isn’t one. This is useful for testing because it means that you don’t need to pass a value until the file goes up on the server.

Now that you have the xmlPath setup, you are ready to load the XML file. To do so you will do as follows:

// get the XML path and use the DataModel to load the XML 
var xmlPath = (this.root.loaderInfo.parameters['xmlPath'] != undefined) ? this.root.loaderInfo.parameters['xmlPath'] : "xml/"; 
data.path = xmlPath; 
data.addEventListener(Event.INIT, onDataLoaded); 
data.loadXML("data.xml");

b) Setup the interface and interactivity
Once the data has been loaded into the application it is finally time to start actually building out the functionality. We recommend focusing on one bit of functionality at a time and adding features as required. This will allow you to keep all aspects separate, while never overcomplicating any part of the build. We are going to start with loading the image, since displaying an image is the ultimate goal of the image gallery.

If you haven’t loaded images with AS3 in the past, it is simple. You have to use the Loader to load the file. First, we are going to set a class-level variable called currentImage and set it to 0 because we are going to load the first image in the list. We now create a loadImage function that will handle the functionality involved with loading the image. It will look as follows:

private function loadImage():void {
	// load the new image 
	var loader:Loader = new Loader(); 
	var request:URLRequest = new URLRequest(data.getImage(currentImage));
	loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
	loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onImageLoadError);
	loader.load(request);
}

Now we have to create the listeners for that image, the complete and the error.

private function onImageLoaded(e:Event):void { 			 			var 	cli:LoaderInfo = e.target as LoaderInfo; 
	TweenLite.to(image_mc, 0.3, { alpha: 0, onComplete: showNextImage, onCompleteParams: [cli.content] }); 
}
private function showNextImage(obj:DisplayObject):void {
			
			while(image_mc.numChildren > 0) image_mc.removeChildAt(0);
			image_mc.addChild(obj);
	TweenLite.to(image_mc, 0.3, { alpha: 1 });
}

private function onImageLoadError(e:IOErrorEvent):void { 
	trace(this.toString(), "IMAGE NOT FOUND"); 
	error_mc.visible = true; 
}

What happens above is Event.COMPLETE fires when the image is done loading so onImageLoaded gets called. onImageLoaded gets the content from the loaded image, fades the current image (if there is on), removes any other images that might exist and finally fades in the new image.

We now have an XML based image loader, but we want to be able to change images and do a lot more. So we will add the next and previous buttons over the images so that we can navigate through the images.

In the init function we add:

// add interactivity to the buttons
			
next_mc.addEventListener(MouseEvent.CLICK, onNextImage);
prev_mc.addEventListener(MouseEvent.CLICK, onPrevImage);

Now add the two functions that those call

private function onNextImage(e:MouseEvent):void {
			
	if (currentImage < data.getNumImages() -1) {
		currentImage ++ ;
		loadImage();
	}
			
	prev_mc.visible = true;
}
		
private function onPrevImage(e:MouseEvent):void {
			
	if (currentImage > 0) {
		currentImage -- ;
		loadImage();
	}

	next_mc.visible = true;
}

You actually now have the basics for loading an XML file containing a list of images and being able to navigate through the images. We are just going to add a little bit more functionality to make it more of a useful photo gallery.

First we are going to call setupThumbs(); from the bottom of the init function. Then we add the following block of code that will control loading the thumbnails and assigning all the interactivity to them:

/**
* setupThumbs
* build the thumbnails along the bottom of the interface
**/
private function setupThumbs():void {
	
	// make the thumbs visible
	thumbs_mc.visible = true;
	
	// get the number of images in the application
	var numImages:Number = data.getNumImages();
	
	// iterate through all the thumbs in the XML
	for (var i:int = 0; i < numImages; ++i) {
		// create a container for the thumb... this is a movieclip so that it can store the id
		var thumb:MovieClip = new MovieClip();
		// set an id for the thumbnail
		thumb.id = i;
		thumb.active = (i == 0);
		thumb.alpha = (i==0) ? 1 : 0.5;
		
		// setup the loader for the thumbnail image
		var loader:Loader = new Loader();
		var request:URLRequest = new URLRequest(data.getThumb(i));
		// add listeners for complete and not found
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onThumbLoaded);
		loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onThumbNotFound);
		loader.load(request);
		thumb.addChild(loader);
		
		thumb.buttonMode = true;
		thumb.addEventListener(MouseEvent.CLICK, onThumbClick);
		thumb.addEventListener(MouseEvent.ROLL_OVER, onThumbOver);
		// add the thumb to the container
		thumbs_mc.container_mc.addChild(thumb);
		// the width of the thumbs we are using is 69, we want 5px of padding = 74px
		thumb.x = thumb.id * 74;
	}
	
	// if paging is required for the thumbnails
	if (numImages * 74 > thumbs_mc.mask_mc.width) {
		// move the container and its mask
		thumbs_mc.container_mc.x = thumbs_mc.mask_mc.x = 35;
		// shorten the mask
		thumbs_mc.mask_mc.width -= 70;
		// add functionality to the arrows
		thumbs_mc.next_mc.buttonMode = true;
		thumbs_mc.prev_mc.alpha = 0.3;
		thumbs_mc.prev_mc.addEventListener(MouseEvent.CLICK, onPreviousThumbs);
		thumbs_mc.next_mc.addEventListener(MouseEvent.CLICK, onNextThumbs);
		// set the number of thumb pages
		numThumbPages = Math.ceil((numImages * 74) / thumbs_mc.mask_mc.width);
	}
}

private function onPreviousThumbs(e:MouseEvent):void {
	if (currentThumbPage != 0) {
		currentThumbPage --;
		thumbs_mc.next_mc.alpha = 1;
		thumbs_mc.next_mc.buttonMode = true;
		TweenLite.to(thumbs_mc.container_mc, 0.4, { x: 35 + (-currentThumbPage * (6 * 74)) });
	}
	
	if (currentThumbPage == 0) {
		thumbs_mc.prev_mc.alpha = 0.5;
		thumbs_mc.prev_mc.buttonMode = false;
	}
}

private function onNextThumbs(e:MouseEvent):void {
	
	if (currentThumbPage + 1 != numThumbPages) {
		currentThumbPage ++;
		thumbs_mc.prev_mc.alpha = 1;
		thumbs_mc.prev_mc.buttonMode = true;
		TweenLite.to(thumbs_mc.container_mc, 0.4, { x: 35 + (-currentThumbPage * (6 * 74)) });
	}
	
	if (currentThumbPage == numThumbPages -1 ) {
		thumbs_mc.next_mc.alpha = 0.5;
		thumbs_mc.next_mc.buttonMode = false;
	}
	
}

private function onThumbOver(e:MouseEvent):void {
	var thumb:MovieClip = MovieClip(e.currentTarget);
	thumb.addEventListener(MouseEvent.ROLL_OUT, onThumbOut);
	TweenLite.to(thumb, 0.3, { alpha: 1 });
}

private function onThumbOut(e:MouseEvent):void {
	var thumb:MovieClip = MovieClip(e.currentTarget);
	thumb.removeEventListener(MouseEvent.ROLL_OUT, onThumbOut);
	if (!thumb.active) TweenLite.to(thumb, 0.3, { alpha: 0.5 });
}

private function onThumbClick(e:MouseEvent):void {
	
	var thumb:MovieClip = MovieClip(e.currentTarget);
	
	thumb.active = true;
	thumb.alpha = 1;
	currentImage = thumb.id;
	
	// load the image
	loadImage();
}

private function onThumbLoaded(e:Event):void {
	trace(this.toString(), "THUMB IMAGE LOADED");
}

private function onThumbNotFound(e:IOErrorEvent):void {
	trace(this.toString(), "THUMB IMAGE NOT FOUND");
}

That was a lot of code, what does it all do? In the setupThumbs function, we have to create all the thumbnails and add some interactivity to them. So we loop through the number of images, create a holder for the thumb and load the thumb. There are some extra properties that are assigned to the thumb, namely “id” and “active”. These properties are used to identify the thumb when it is interacted with. There is also a little toggle at the bottom of the function that controls whether or not to show the paging controls for the thumbnail area.

Next are the onPreviousThumbs and onNextThumbs functions that check to make sure the currentThumbPage is not at the start (for previous) or at the end (for next) . If it passes that test, the thumbnails are animated to the next or previous page, the controls are activated or deactivated as needed.

We then added a little interactivity to the thumbs themselves. There is a rollover that sets the alpha to 1 and a rollout that resets it back to 0.5 (if it is not the active thumbnail). When a user clicks on a thumb, the onThumbClick function adjusts the information attached to the current thumbnail and loads the appropriate image.

The final two functions are there and can be used if needed. OnThumbLoaded is called when the thumbnail image has completed loading and onThumbNotFound is called if there was an issue finding the thumbnail image file.

We also added the following bit to the loadImage function at the bottom in order to control which thumbnails are visible, active, highlighted and to switch thumbnail pages if needed when the images are changing.

// update the active thumbs
for (var i:int; i < thumbs_mc.container_mc.numChildren; ++i) {
	var temp:MovieClip = MovieClip(thumbs_mc.container_mc.getChildAt(i));
	if (temp.id != currentImage) {
		temp.alpha = 0.5;
		temp.active = false;
	} else {
		
		var topLeftStage:Point = temp.localToGlobal(new Point(0, 0));
		
		// make sure the active thumb is visible
		if (topLeftStage.x < 40) {
			// shift thumbs left
			currentThumbPage --;
			thumbs_mc.next_mc.alpha = 1;
			thumbs_mc.next_mc.buttonMode = true;
			TweenLite.to(thumbs_mc.container_mc, 0.4, { x: 35 + (-currentThumbPage * (6 * 74)) });
		} else if (topLeftStage.x > 410) {
			// shift thumbs right
			currentThumbPage ++;
			thumbs_mc.prev_mc.alpha = 1;
			thumbs_mc.prev_mc.buttonMode = true;
			TweenLite.to(thumbs_mc.container_mc, 0.4, { x: 35 + (-currentThumbPage * (6 * 74)) });
		}
		
		if (currentThumbPage == 0) {
			thumbs_mc.prev_mc.alpha = 0.5;
			thumbs_mc.prev_mc.buttonMode = false;
		} else if (currentThumbPage == numThumbPages -1 ) {
			thumbs_mc.next_mc.alpha = 0.5;
			thumbs_mc.next_mc.buttonMode = false;
		}
		
		temp.alpha = 1;
		temp.active = true;
		
		// adjust the page to the one the thumb is on
		
		
	}
}

That is basically it. We have tried to keep this fairly simple and high-level, but there is definitely some complexity to the final code. Take a look at the example and the provided source, play around a little bit. If you have any questions or comments, please let us know and we will get back to you. We hope that this is a helpful little guide for how to utilize XML and load images. Some of the code here could and probably should be re-arranged into other classes and broken down a little bit more for modularity, but for the purposes of this tutorial we did not do that.

share save 171 16 Flash Image Gallery Tutorial
  • [...] here: Flash Image Gallery Tutorial | Cult Creative :: A Digital Agency flash, game, image, image-gallery, million-different, the-game, [...]

  • Arun Feb 14, 2012

    thanks man.
    I dont have the cs5.5 Version. Please send me the cs5 version of source file. (mail-id: mail2arunkumar.m@gmail.com)
    Thanks in advance.

  • cultcreative Feb 14, 2012

    Hey, I just saved down to CS4 for anyone that is interested. It can be found at http://www.cultcreative.com/tuts/ImageGallery/img_tut_cs4.zip

  • Eko May 20, 2012

    Heey Nice tatoriul Heey Nice tatoriul I’m going to try it out.But I got this question does the javascript also work on cs4?And that script you used to play the slideshow is that the only one or is there more script to get this slide show?I hope to hear something from you =DKeep up the Good worl.

  • Erast Feb 5, 2013

    Hey, thanks a lot. Very good tutorial. But I have problems when I try to add a function to reload the xml file or a function to call another xml file. The images from the first xml file still appears after calling the next xml file. Do you have any clue to this problem?

  • Name (Required)

  • Email (Required, but not published)

  • Url (Optional)

  • Comment (Required)

*

Current month ye@r day *