Build a Dynamic Flash Gallery with Slider Control

Apr 27th in XML by Ben Merckx

In this tutorial, we'll create a gallery which displays all image files in a given directory. A slider is used to browse easily through the images.

PG

Author: Ben Merckx

I am a Belgian multimedia designer. At the moment I'm finishing my study of interactive multimedia design. I hope to share some of my some Flash knowledge this way.

Step 1

Set up a new Flash AS3 document and a blank ActionScript file. We'll create the main class first; name it "Gallery" and save it as "Gallery.as". Below is the code to set up the first class:

package
{
	public class Gallery
	{
		public function Gallery() : void
		{
		}
	}
}

In Flash we can now set this as the base class by entering the name in the input box under the Publish settings of the document. You can try a "trace('hello world')" in the Gallery function to test if it's working.

Step 2

Before we continue with the main class, it's best to start off with the slider. The code is fairly easy to understand and might shine some light on how things are done in AS3.

Create two new movieclips: a slider and a handle for the slider. The slider or seeker doesn't need to be exported for ActionScript as we only need to apply some functions to the handle. Set the class for the handle as "Handle". We can now create a new class called "Handle" and, if saved in the same directory, Flash will automatically use this class for the handle. Give both an instance name such as "slider" and "theHandle".

Step 3

The following is the full code for the handle which I will explain in steps. It should be saved as "Handle.as" in the same directory as your .fla. This way, Flash will execute the code once an instance with a class name "Handle" is used.

package  
{
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.events.Event;
	
	public class Handle extends MovieClip
	{	
		public var goToX : Number = x;
		private var slider : MovieClip = MovieClip(parent).slider;
		private var mousePos : Number = 0;
		
		public function Handle() : void
		{
			buttonMode = true;
			addEventListener( MouseEvent.MOUSE_DOWN, moveHandle );
			stage.addEventListener( MouseEvent.MOUSE_UP, stopHandle );
		}
		
		private function moveHandle( _e : MouseEvent ) : void
		{
			mousePos = mouseX;
			stage.addEventListener( MouseEvent.MOUSE_MOVE, followHandle );
		}
		
		private function stopHandle( _e : MouseEvent ) : void
		{
			stage.removeEventListener( MouseEvent.MOUSE_MOVE, followHandle );
		}		

		private function followHandle( _e : MouseEvent ) : void
		{
			var newPos : Number = stage.mouseX - mousePos;
			var orgX : Number = x;
			if ( newPos < slider.x )
				goToX = slider.x;
			else if ( newPos > (slider.x + slider.width) - width )
				goToX = (slider.x + slider.width) - width;
			else
				goToX = newPos;
			x = goToX;
			if( goToX != orgX ) dispatchEvent( new Event( "sliding", true ) );
		}		
		
	}
	
}

In the first few lines we create a few variables to hold data we can use in every function in this class. The slider variable holds a reference to the instance called "slider" on the parent. We need it to correctly calculate the x position to which the handle should be moved. In the constructor we set "buttonMode" to true so a hand cursor shows up when hovering over the handle. Additionally, we add two eventlisteners to listen for mouse events.

public class Handle extends MovieClip
{	
	public var goToX : Number = x;
	private var slider : MovieClip = MovieClip(parent).slider;
	private var mousePos : Number = 0;
	
	public function Handle() : void
	{
		buttonMode = true;
		addEventListener( MouseEvent.MOUSE_DOWN, moveHandle );
		stage.addEventListener( MouseEvent.MOUSE_UP, stopHandle );
	}

Once a mouse down event occurs, an extra listener is added. This listener stays active as long as the drag movement isn't stopped and calls the "followHandle" function. It's removed again when the mouse click is over.

private function moveHandle( _e : MouseEvent ) : void
{
	mousePos = mouseX;
	stage.addEventListener( MouseEvent.MOUSE_MOVE, followHandle );
}

private function stopHandle( _e : MouseEvent ) : void
{
	stage.removeEventListener( MouseEvent.MOUSE_MOVE, followHandle );
}

This last function actually moves the handle around. The variable "newPos" stores the new position to which the handle should move. If, however, this position is further than the far left or right of the slider, the position should be set to the maximum possible value. If the handle is moved, we dispatch a new custom event called "sliding", which we can later use to move around the images.

private function followHandle( _e : MouseEvent ) : void
{
	var newPos : Number = stage.mouseX - mousePos;
	var orgX : Number = x;
	if ( newPos < slider.x )
		goToX = slider.x;
	else if ( newPos > (slider.x + slider.width) - width )
		goToX = (slider.x + slider.width) - width;
	else
		goToX = newPos;
	x = goToX;
	if( goToX != orgX ) dispatchEvent( new Event( "sliding", true ) );
}

Step 4

If everything's gone well until now, you should have a nice functional slider like the one below. Add a dynamic textfield underneath it which will hold the image number. Give it an instance name like "countTxt" so we can address it later in ActionScript. Because there's nothing to display yet I filled it with the text "Loading" which will also display while the script loads the first image.

Step 5

Next we'll create the php backend script. Flash can't read the contents of a local directory, so we need to pass the information from php to Flash. We'll use XML since it's easy to output with php and even easier to read again in AS3.

The following is the php backend code, save it as "backend.php". The code loops through the directory "img" and writes a line of XML for each file in there. Before printing we need to filter out the "." and ".." directories. As the directory only contains images there's no further checking necessary.

<xml>
<?php
$od  = opendir('img'); 
while ( $filename = readdir($od) ) 
    if( $filename != "." && $filename != ".." ) echo "<img>" . $filename . "</img>\n"; 
?>
</xml>

This will output for example:

<xml>
	<img>file1.jpg</img>
	<img>file2.jpg</img>
	<img>file3.jpg</img>
</xml>

Step 6

Before we load this into Flash, let's create a class to hold our images individually. In the same way we created the Handle class we can now create an Img class. Start off with creating a movieclip about the size you want your images to be displayed. Give it a margin of a few pixels and save some space on the bottom for the description text. Add a dynamic text field for the description and give it an instance name of "descr". Make sure to set the registration point of the movieclip to the center so we can easily scale it later. Export it for ActionScript under the class name "Img". Now delete the instance from the stage as we'll call it directly from the library.

Step 7

Next we'll load the information the php file returns into our Flash project using ActionScript. Open up the Gallery class again. The following code adds two functionalities to our project. First off, it creates "imagesClip", an empty movieclip in which we'll store the actual images later. Using "addChild" here adds the movieclip to the stage. Anything added to imagesClip later will also appear on the stage. To actually load the xml data, we create a "URLLoader". This class can fetch the results and run a function when the results are in.

package
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	
	public class Gallery extends MovieClip
	{
		private var backend : String = 'http://localhost/.../backend.php';
		
		private var xmlLoader : URLLoader = new URLLoader;
		private var xdata : XML;
		public var images : Array = new Array();
		
		public var imagesClip : MovieClip = new MovieClip;
		
		public function Gallery() : void
		{		
			imagesClip.y = 180;
			addChild( imagesClip );

			xmlLoader.load( new URLRequest( backend + "?" + new Date().valueOf() ) );
			xmlLoader.addEventListener( Event.COMPLETE, loadImages );
			
		}
			  
		private function loadImages( _e : Event ) : void
		{
			xdata = new XML( _e.target.data );
			var i : Number = 0;
			for each( var img:XML in xdata.img )
			{
				images[i] = new Img();
				i++;
				imagesClip.addChild( images[i] );
			}
		}
	}
}

Here we use the load function of the URLLoader class. To prevent caching of the results we can add a simple date to the end of the url. The eventlistener checks when the URLLoader is finished and then runs the loadImages function.

xmlLoader.load( new URLRequest( backend + "?" + new Date().valueOf() ) );
xmlLoader.addEventListener( Event.COMPLETE, loadImages );

This next function loops through all the <img> instances in the xml. For each of these it creates a new instance of the Img class. Next we add it to the imagesClip (this is just for testing as later on we only want the active images to be displayed).

private function loadImages( _e : Event ) : void
{
	xdata = new XML( _e.target.data );
	var i : Number = 0;
	for each( var img:XML in xdata.img )
	{
		images[i] = new Img();
		i++;
		imagesClip.addChild( images[i] );
	}
}

Step 8

To give our Img instances more functionality, create an Img class and save it as "Img.as". In a similar way to loading the XML we can load the image itself and display it inside the Img movieclip. The loading should not occur in the constructor or all images would try to load at the same time; we'll create a separate function for doing this.

		
public class Img extends MovieClip
{
	public var id : Number;
	private var src : String;
	private var imageLoader:Loader = new Loader();
	private var main : Gallery;
	private var orgWidth:Number = 0;
	private var orgHeight:Number = 0;

In the constructor, we set a reference to the main Gallery class so we can later access elements on the stage or public variables and functions of the main class. The string "load" will contain the path to the image which php returned, we'll save it to a variable so we can access it later.

	
	public function Img( load : String, m : Gallery ) : void
	{
		orgWidth = width;
		orgHeight = height;
		main = m;
		src = load;	
	}

The "loadImage" function loads the image and when finished runs the "displayImage" function.

		
	public function loadImage() : void
	{
		imageLoader.load( new URLRequest( "img/" + src ) ); 
		imageLoader.contentLoaderInfo.addEventListener( Event.COMPLETE, displayImage );
	}

The displayImage function checks the images array we created and loads the next image. It sets the smoothing to true on the Loader (by default, smoothing is set to false on dynamically loaded images). Once you start scaling or rotating an image it's important to set the smoothing so the image remains its quality. As the registration point of the Img movieclip is in the center we need to calculate the x and y position of where to place the image itself. In my example I've used a directory of images with the same width and height. If the width and height of the loaded image are variable this is the place to resize it on the fly. Just before adding it as a child we set the description text to "src", which holds the name of the image.

		
	private function displayImage( _e : Event ) : void
	{
		if ( main.images[id + 1] != null && !main.images[id + 1].parent ) main.images[id + 1].loadImage();
		Bitmap( imageLoader.content ).smoothing = true;
		imageLoader.x = main.spaceBetween/2 - ( orgWidth /2 );
		imageLoader.y = main.spaceBetween/2 - ( orgHeight /2 );
		descr.text = src;
		addChild( imageLoader );
	}
}

Step 9

After the changes we made to the Img class we need to update the way the instances are called in the loadImages function of the Gallery class. We now need to pass two arguments when calling new Img().

The first is the path name of the image that needs to be loaded, we get this from the xml. The second is a reference to the main Gallery class; we can use "this" which points to the class we're currently working in. Instead of adding the images with addChild to the imagesClip container we'll create a new function "goTo". This function will work out which images to place on the screen. The argument we need to pass is the id number of the image, the same number as the index key in the images array. When the images are loaded for the first time, we'll set the focus on the first image, of which the id number is zero.

		
private function loadImages( _e : Event ) : void
{
	xdata = new XML( _e.target.data );
	var i : Number = 0;
	for each( var img:XML in xdata.img )
	{
		images[i] = new Img( img, this );
		images[i].x = 200 * i;
		images[i].id = i;
		i++;
	}
	goTo( 0 );
}

Step 10

To use the goTo function we need to declare a variable "imagesToShow" first. This will set the amount of images we want to load at once on screen. To determine the direction in which the user is scrolling, we simply check if the image we're going to had a higher or lower id number than the last one.

private function goTo( imgId : Number ) : void
{
	var direction : Number;
	if ( orgImgId != imgId )
	{
		if ( imgId > orgImgId  ) direction = 1;
		else direction = -1;

The next "for loop" loops all images needed on screen. For example: if we set imagesToShow to 5, it will loop from -2 to 2. This means that if we pass the value of i to the Img class we can determine where on the screen it should be positioned (-2 being far left, 0 center and 2 the far right). Therefore, we can scale the images larger the more centrally they are positioned.

There's an additional check included so we don't activate non-existing images (it stops at the first and the last one). For each of the active images we'll run the "makeActive" function, which we'll create later on.

		for ( var i : Number = - Math.floor(imagesToShow/2); i <= Math.floor(imagesToShow/2); i++ )
		{
			if( imgId + i < images.length && imgId + i >= 0 ) images[imgId + i].makeActive( i, direction );
		}

Right after placing the images we need on screen, we'll check which ones shouldn't be there any more and get those off the stage. Since all images are added to the imagesClip container, we can easily loop through all children of that movieclip. If their id is not within those that should be active, we run the "deActive".

		for( var j : Number = 0; j < imagesClip.numChildren; j++ )
		{
			var tile : Img = imagesClip.getChildAt(j) as Img;
			if ( tile.id < imgId - Math.floor(imagesToShow/2) || tile.id >  imgId + Math.floor(imagesToShow/2) ) tile.deActive( direction );
		}

The next line updates the text of the dynamic textfield we created earlier. Since the ids of the images start their count at 0 we add + 1 to the imgId so the first image is actually number 1 etc. We can get the total number of images from accessing the length of the images array.

		countTxt.text = imgId + 1 + "/" + images.length;
	}

Finally, we'll set "orgImgId" so the next time the function is run, the direction being scrolled can be determined.

	orgImgId = imgId;			
}

Step 11

We now need the "makeActive" and "deActive" functions in the Img class. These will either add the image to the stage, or take it off. For now we'll just add them and place them correctly. Later on we'll also tween them to their correct place.

The makeActive function first checks if it is added to the imagesClip already. If there is no parent found, it adds itself to to imagesClip container. The parent is then the imagesClip. Next we set the visible property to true. When deactivating, we set it to false so it's only normal we want our image to show again when it's made active.

public function makeActive( position : Number, direction : Number ) : void
{
	if ( parent == null ) 
	{
		main.imagesClip.addChild( this );
	}
	visible = true;

There's a chance that the image itself hasn't yet loaded. To check this, I check if the amount of children is smaller than 3. This number can depend on the amount of shapes or other movieclips in your Img. If you feel uncertain about this method, a safer option would be to declare a boolean at the start and set it to true in the displayImage function.

	
	if ( numChildren < 3 ) loadImage();

There's no depth in AS3, but once we start scaling and rotating our images we need to make sure the image in the center is on top of the others. Because we passed the position as an argument in the goTo function we can now use it to set the index of the image in the imagesClip. The index of a child can be compared to a depth, but there won't be any issues when changing it since the other movieclips will move an index up or down. This step is unnecessary if you don't plan to overlap the images.

	
	parent.setChildIndex( this, ( parent.numChildren-1 ) - Math.abs( position ) );

Lastly, we determine the position of the image. The "extra" variable is used here to find out by how much the current image is away from the center. "DefaultWidth" and "spaceBetween" are public variables set in the main Gallery class so we can access them from anywhere. Since all the images in my directory have the same width, I set defaultWidth at 195 and spaceBetween to 20. To actually move the image to the new position we set the x property to the newly found x value.

	var extra : Number =  Math.round( position * ( main.defaultWidth + main.spaceBetween ) );
	var newX : Number = Math.round( ( main.stageWidth / 2 ) ) + extra;
	x = newX;
}

Step 12

The deActive function is pretty straight forward, it changes the visibility to false. The direction is already set as an argument since we'll need it later to know in which direction to send the image when taking it off the stage.

public function deActive( direction : Number ) : void
{
	visible = false;		
}

Step 13

By now, the first few images should appear on stage. There's only one functionality still missing. The slider is not connected to the goTo function yet. However, since we already dispatch a custom event once the handle is dragged, it's not very hard to connect the two.

Add the following line to the Gallery constructor function. This eventlistener will run the slide function every time the "sliding" event is called by the handle.

theHandle.addEventListener( "sliding", slide );

All we need the slide function to do is to calculate which image should be shown in the center depending on where the handle is. In the function "slider" and "theHandle" are the instance names we set earlier on the movieclips on the stage. To find out which image to go to we first determine the percentage of the handle's position over the slider's length. Then, multiplying that by the total of images brings us to the right image id.

private function slide( _e : Event ) : void
{			
	var percent : Number = ( theHandle.goToX - slider.x ) / ( slider.width - theHandle.width );
	var imgId : Number = Math.round( percent * ( images.length - 1 ) );
	
	goTo( imgId );
}

Step 14

If you've managed to follow this far and kept track of which classes to import and which variables to declare (or followed the source files) you should by now have a working example.

Step 15

To finish this tutorial we'll add tweening to the images using TweenLite, a free and lightweight tweening engine. The standard tweening classes provided by Adobe do not perform well when there's a lot going on. When trying those out they used to crash or freeze a lot, while I have yet to discover such problems with TweenLite. The syntax of TweenLite is very easy. I'll demonstrate this by comparing it to a normal Flash tween; tweening an object from its current x to 100 and changing the alpha to 0:

new Tween( object, 'x', Linear.easeOut, object.x, 100, 2, true );
new Tween( object, 'alpha', Linear.easeOut, object.alpha, 0, 2, true );

Now here's the TweenLite alternative syntax:

TweenLite.to( object, 2, { x:100, alpha:0, easing:Linear.easeOut } );

Step 16

Let's create a new function in which we can place all of the tweening actions. Name it "flyTo" and place it in the Img class.

private function flyTo( newX : Number, removeAfter : Boolean, scale : Number = 1 ) : void
{
	var tweeningOptions : Object = new Object;
	tweeningOptions.x = newX;
	
	if ( removeAfter )
	{
		tweeningOptions.ease = Linear.easeIn;
		tweeningOptions.alpha = 0;
		tweeningOptions.scaleX = tweeningOptions.scaleY = 0.3;
		tweeningOptions.visible = false;
	}
	else
	{
		tweeningOptions.ease = Back.easeOut;
		tweeningOptions.alpha = 1;
		tweeningOptions.scaleX = tweeningOptions.scaleY = scale;
		tweeningOptions.rotation = (Math.random() * 20) - 10;
	}
	TweenLite.to ( this, 0.4, tweeningOptions );
}

There are 3 arguments needed for this function: the x value we calculated earlier, whether it should be removed after the tween and the scale. The "removedAfter" parameter will be used in the deActive function, so the visibility of the image can be set to false once it's reached the end of the stage. The scaling parameter is only used for the center image; we'll display it slightly larger than the rest.

Let's check out the tweening options for when the image is removed from the stage. First we choose an easing option, in this case "Linear.easeIn" which gives normal, linear movement. Secondly, we fade the alpha value to zero so the image fades away. Then we scale it to only a small percentage of its width and height so it becomes smaller as it reaches the end. Lastly, when the tween is completed, we set the visibility to false.

tweeningOptions.ease = Linear.easeIn;
tweeningOptions.alpha = 0;
tweeningOptions.scaleX = tweeningOptions.scaleY = 0.3;
tweeningOptions.visible = false;

When an image is made active, the tweening options are different. We set the easing to "Back.easeOut" so the images seem to fly slightly too far and then bounce back; a very subtle effect. Next we change the alpha back to 1 and scale the image to the scale value we passed to the function. Lastly, we set a random rotation of -10 to 10 degrees. If your description text fails to load after this action you need to make sure the font is embedded.

tweeningOptions.ease = Back.easeOut;
tweeningOptions.alpha = 1;
tweeningOptions.scaleX = tweeningOptions.scaleY = scale;
tweeningOptions.rotation = Math.round( (Math.random() * 20) - 10 );

Step 17

Now we need to update the makeActive and deActive functions so they make use of the new flyTo function.

In the makeActive function we need to add an x value to the image so it can be tweened from that original value. The defaultWidth needs to be set in the main Gallery class and contains the width of the stage.

public function makeActive( position : Number, direction : Number ) : void
{
	deactivating = false;
	if ( parent == null ) 
	{
		x = ( direction == 1 ? main.stageWidth + main.defaultWidth * 2 : - main.defaultWidth * 2 );
		alpha = 0;
		main.imagesClip.addChild( this );
	}
	visible = true;
	if ( numChildren < 3 ) loadImage();
	parent.setChildIndex(this, ( parent.numChildren-1 ) - Math.abs( position ) );
	
	var extra : Number =  Math.round( position * ( main.defaultWidth + main.spaceBetween ) );
	var newX : Number = ( Math.round( ( main.stageWidth / 2 ) /* - ( main.defaultWidth / 2 )*/ ) + extra );
	flyTo( newX, false, ( position == 0 ? 1.2 : 1 )  );
}

In the deActive function all we need to add is a moveTo value which contains the x value to which the image should tween. If we locate this to outside the stage width, the image will disappear just outside the stage.

public function deActive( direction : Number ) : void
{
	if ( ! deactivating )
	{
		active = false; 
		var moveTo : Number = ( direction != 1 ? main.stageWidth + main.defaultWidth * 2 : parent.x - main.defaultWidth * 2 );
		flyTo( moveTo, true );
		deactivating = true;
	}			
}

Step 18

After updating everything, we now have a functional gallery. To see the movieclips disappearing from the stage check out the full version.

Conclusion

The final version is still low on functionality. The loaded images all need to be the same size and do not have a larger preview. You could add a resizing function and an option to view a larger preview of the image when clicked. Furthermore, an option to browse left or right with buttons or with a keyboard event could be added.

Once you understand the concept of using classes to separate and structure your code it will help in development and make things easier in the long run. I hope you enjoyed following along!


Enjoy this Post?

We'd love your vote!

User Comments

( ADD YOURS )
  1. PG

    André April 27th

    Genious, very nice work, congratulations…

    ( Reply )
  2. PG

    sike April 27th

    Pretty cool.

    ( Reply )
  3. PG

    kom April 27th

    Awesome !

    ( Reply )
  4. PG

    Dario Gutierrez April 27th

    Dude, this is awesome!! I like it.

    ( Reply )
  5. PG

    fraize April 27th

    so cool …

    ( Reply )
  6. PG

    Diego SA April 27th

    Oh my God! Wonderful!
    You’re great! Congratulations!
    I’ll try this later with another layout!

    ( Reply )
  7. PG

    Phenotype April 27th

    So, is this site FlashTuts or ActionScriptTuts? It’s nice seeing these really advanced AS3 tutorials but I think it would be really great if we could get some Tuts that explored the features of Flash a little better.

    ( Reply )
    1. PG

      shampi April 27th

      why?

      ( Reply )
    2. PG

      As-n00b April 27th

      Honestly, having been using flash for 6+ years and STILL only knowing basic actionscript since I was always a frame based tweener, these tutorials are the only way to go. Please don’t bitch about actionscript tutorials. If you want to be good with flash LEARN ACTIONSCRIPT! If you don’t, there is not a lot of sense using flash as you are extremely restricted with the stuff you can do.

      On that note, maybe more basic actionscript tutorials for beginners and things that are used everyday with flash like if, else conditionals etc.. Everybody can follow a tutorial step by step but it is pointless if you don’t know how or why it works the way it does.

      ( Reply )
      1. PG

        Phenotype April 27th

        Why can’t we have both? I definitely want to learn Actionscript but as a beginner to Flash these kinds of tutorials are basically useless to me when I haven’t even mastered the basics. Sure, there are a lot of other sites that have tutorials that cover the basics but their tutorials suck. The TUTS+ network has a higher caliber of tutorials. I’d love to see some tutorials that combined AS3 with basic-to-advanced Flash tools.

    3. PG

      André April 28th

      Basic tuts is what you find in terabytes at google, but this kind of tut, its very difficult to find, dont complain about this kind of tut, just try to learn…

      And you can see the biggest difference about websites based on actionscript and animated by the quality…

      ( Reply )
  8. PG

    Dave April 27th

    I wonder how long before someone takes this and turns it into coverflow :)

    I love seeing these tutorials OOP is huge, there’s no reason why we can have Flash and Actionscript tuts on here – we just need an AS category.

    werd?

    ( Reply )
  9. PG

    rishteria April 27th

    Congratulations for your work !!! you inspire me !!! ^^’

    ( Reply )
  10. PG

    Franky April 27th

    Sweeet tut.

    ( Reply )
  11. PG

    CgBaran Tuts April 27th

    Great post thanks

    ( Reply )
  12. Great tutorial Ben. I have been looking to do this for sometime within my projects. I love how the images drop off the edges when you scroll.

    It would be nice if you do a v2 where you can click the images within the gallery and they enlarge. The scroller will also move to the image position.

    ( Reply )
  13. PG

    lawrence77 April 27th

    Ben its really amazing….
    It something resembles Vista Flip Effect!

    :lol: lawrence :lol:

    ( Reply )
  14. PG

    Peewee1002 April 27th

    Thats great and useful, shame it didn’t have a pop-up when you click the image but I don’t think that would be too hard to add.

    ( Reply )
  15. PG

    Marquell April 27th

    Is there a possibility to do this using Flash CS3, because thats all i got at the momment?

    ( Reply )
    1. PG

      Ben Merckx April 28th

      The code would be exactly the same, but I realize now that I saved the fla in CS4 format so you’ll have to build it from scratch. You should be able to use the as files from the source without any problem though.

      ( Reply )
    2. PG

      shampi April 28th

      it works for CS3 and CS4 since it’s in AS3 …

      ( Reply )
    3. PG

      RUGRLN April 29th

      Flash CS4 has only differences in the tween model/ UI and new 3D sutff….AS3 is still there, so it should be exactly the same…

      ( Reply )
      1. PG

        Jennifer July 2nd

        RUGRLN I love your icon!!! SOOOO… CS4!!! :) Nice TUT Too!!! <3

  16. PG

    cyber April 27th

    By FAR THE COOLEST TUTORIAL Congrats , Ben, you bring home the bacon.

    ( Reply )
    1. PG

      André April 28th

      I agree!!

      ( Reply )
  17. PG

    Murdoc April 28th

    this is an awesome tut!!! and that’s also the effect that i’m looking for!!!
    Anyways, i have a question, is it possible to make the images clickable to view bigger images? As in considering those images you use as thumbnails.
    Thanks.

    ( Reply )
  18. PG

    Richard S Davies April 28th

    Great tut, got the visuals and the code spot on. Keep it up with the AS3 tuts!

    ( Reply )
  19. PG

    willian April 28th

    Very important

    Muito show de bola.
    and big foto!!!

    ( Reply )
  20. PG

    dudouz April 29th

    lacks a preloader…tryin to make it out

    ( Reply )
  21. PG

    Flash Content Designer April 29th

    nice work dummy, but you didn’t elaborate on the location of the images on the local folder, plus your source .fla file had the Gallery.as going to the same directory location instead of directing to classes.Gallery.

    ( Reply )
  22. PG

    Diego Andres Pardo April 29th

    excelent tut but i dont understand the step 5 I can´t complete de tutorial

    ( Reply )
    1. PG

      Designer April 30th

      i agree. I can’t complete it b/c there were no images and even though there is no ‘img’ folder from the source file. the tutorial is not 100% complete.

      This is the best tutorial with 99% completion.

      Did anyone complete it? how did you add the image folder.

      ( Reply )
  23. PG

    Arun J April 30th

    Cool work dude…..

    ( Reply )
  24. PG

    Zack April 30th

    TIGHT!!!!!! Thanks man. We need more like this

    ( Reply )
  25. PG

    brandon marius May 3rd

    Is anyone checking the comments??? I went through the tut, realized that there was no mention of the images, downloaded the source files… no images or image directory. I then found the path the images were to be pulled from in the as code, made the directory, added images, tried compiling the the swf and errors. First the pathing for the Gallery.as file and then errors for the arguments being passed. Can someone please address the issues with this tut?

    ( Reply )
    1. PG

      Ben Merckx May 4th

      The images directory did not get included in the source since I kept all source files and all the stuff that was to be uploaded apart. That was my fault and it can be fixed by creating a directory named ‘img’ in the same folder as the fla/swf.

      As for the errors you’re getting I’m not really sure why. It could be because Flash doesn’t read out the classes folder; if so you can place all contents of that folder with the fla/swf as before. One more thing that could have gone wrong is the php file. Are you running an apache server and did you acces the php file through localhost?

      I’m sorry if the problems were caused by me being unclear. Let me know if any more errors show up and please specify which ones if they do.

      ( Reply )
      1. PG

        brandon marius May 5th

        Thanks for the reply… I moved all the files from the classes directory and placed them in the directory along with the swf, html, etc. The gallery works now but I have an extra and empty instance of the img holder on the screen in the first position. The count for this is 1/32 but I only have 31 images in my img directory.

      2. PG

        Erick May 7th

        Check your Array! :) Good Work. I can look forward and finally complete it after one week.

        This is rather for intermediate to advanced designers, and it looks like they teach better interactive design in Europe than they do in the US.

  26. PG

    dudouz May 5th

    if you call it from an external SWF (like i do the preloader), it gives the type error #1009, to solve this you got to rethink the way it calls the function on the class. almost cracked my head tryin to solve this but i made it up, by the way this is the kind of tutorial that makes me evolve my flash skills, and makes me see that i dont know shit, yet…thanks for sharing your knowledge with us…hope you send more tutorials like that!

    ( Reply )
    1. PG

      Rishi July 15th

      Hey,

      How did you resolve the function calling issue?
      I have the exact same problem and have been tearing at my brains for a week.
      Got the gallery customized to my needs, now I need to load the .swf into my file and its giving me the type error #1009.
      Any kind of pointers would be appreciated. I have googled and referred to the error descriptions, but If you could point me in the right direction, I can figure it out.

      ( Reply )
      1. PG

        Rishi July 18th

        Ha! I figured it out after a week.
        It was painful and I almost gave up.
        But it opened my eyes to what AS 3.0 can do for you.
        Once again, Beautiful, beautiful tutorial.
        I want to post my solution, so anyone who wants to use this as a ‘part’ of their project can do so easily.

        :)

  27. PG

    steven May 5th

    Thanks for the great tut.

    Unfortunately it doesn’t work for me.

    I created a folder named ‘img’ in the same folder as the fla/swf and I moved the classes folder to the same location, but it still doesn’t work.

    Any suggestions?

    Regards,

    Steven.

    ( Reply )
  28. PG

    J-Rod May 6th

    great

    ( Reply )
  29. PG

    emlak May 7th

    thaks

    ( Reply )
  30. PG

    KaydenAidan May 8th

    Can someone please make a video of this. This was really hard to follow…

    ( Reply )
  31. PG

    blufragola May 8th

    Great tutorial! Thank you!

    When I started following the tutorial I noticed a bug (?):
    I hadn’t vertically aligned “handle” and “slider” yet and I couldn’t notice that “handle” was positioned under “slider” in the stack (in the same layer) -> it caused an error because
    “private var slider : MovieClip = MovieClip(parent).slider;” resulted in “null”.
    When I changed their order in the stack it worked.
    Could anyone explain me why? That would be great.
    Thank you.

    ( Reply )
  32. PG

    WLShafor May 11th

    Very nice tutorial thanks for sharing I look forward to see more tutorials from you in the near future

    ( Reply )
  33. PG

    Wes May 14th

    This is awesome, but the file doesnt work anymore?

    ( Reply )
  34. PG

    CruisinD May 14th

    Great tutorial, I love the whole thing.

    I was wondering, how could I make it work with multiple image folders. Would I have to copy and paste the flash files X times for X directories or would there be a way to switch from one folder to the next and get the images that way?

    Thank you again, great work!

    ( Reply )
  35. PG

    caiko May 14th

    who to use this in blog or open social like orkut?

    ( Reply )
  36. PG

    Horia Dragomir May 19th

    I’m giving a lecture on Flash and I plan to include this tutorial as an excercise.

    Pretty great tutorial, thank you!

    ( Reply )
  37. PG

    Frime May 20th

    hmm the whole thing doesnt work.
    5000: The class ‘Gallery’ must subclass ‘flash.display.MovieClip’ since it is linked to a library symbol of that type.
    i’ve got that error, dont know how to solve it.
    please, can anyone help me out ?

    ( Reply )
    1. PG

      rkriki May 23rd

      hi Frime, how do fix the error “5000: The class ‘Gallery’ must subclass ‘flash.display.MovieClip’ ” ? im having he same problem as well

      ( Reply )
      1. PG

        rkriki May 23rd

        no worries i already resolved it. : ) flash.display.MovieClip should be imported in the package and the class should be extends to the movieclip. :) poor me in Actionscript 3.lolz

  38. PG

    Frime May 20th

    i’ve fixed that error … now i have a new one xD at step 7.
    1180: Call to a possibly undefined method Img.

    ( Reply )
  39. PG

    Thani May 20th

    Killer tut. I’ve been looking for something like this. Tuts+ has been my resource for everything lately!

    However, the only thing I’m having trouble with is the backend.php. Either it’s not doing it job, its not being found, or its not in the correct spot. Any faced this problem and solved it?

    Thanks!

    ( Reply )
  40. PG

    Greg May 25th

    How would you attach this photo album to a specific movie clip in an .fla.

    would I just just import all the classes to the movie clip I want this to be in?

    How do you make a directory I think I botched that up?

    thanks!

    ( Reply )
  41. PG

    mike May 25th

    i been working on this for a full day..and keep getting these errrors

    the slider, the handle and the counter all work.. but the img doesnt show and the images i choose and resized do not show either

    Error #2044: Unhandled ioError:. text=Error #2032: Stream Error. URL: file:///C|/Users/ASSHOLE/Downloads/source/slideshow/backend.php?1243317337197
    at Gallery()

    i think i may not be setting up the right file names for the xml documents to read them… if anyone can help that be greaT!!!

    how do i test this to ensure it’s working

    ( Reply )
    1. PG

      Jelle Vervloessem June 8th

      Just put your swf on a webserver. the PHPfile will render and only then is your XMLfile complete

      ( Reply )
  42. PG

    Matt Przybylski May 29th

    great tutorial but be careful in your 8th step and your loadImage method. reusing a Loader object works in Flash Player 10 but in some version of FP9 it does not work properly and you have to create a new loader for everything you load in.

    ( Reply )
  43. PG

    Tinku Tharasing May 29th

    This is why i like flash tutes

    ( Reply )
  44. PG

    Danijel May 30th

    Read the tutorial and it’s great. Though I couldn’t complete it. I’m still a rookie when it comes to creating your own classes… I got stuck at step 5, got a error.. “5000: The class ‘Gallery’ must subclass ‘flash.display.MovieClip’ since it is linked to a library symbol of that type.” Didin’t know how to fix it so now I’m stuck.. What do I need to be able to proceed?

    ( Reply )
    1. PG

      Jelle Vervloessem June 8th

      Just import flash.display.MovieClip in your file, because you use some MovieClips

      ( Reply )
  45. PG

    Jelle Vervloessem June 8th

    Can someone explain me if its possible to resize the images?

    Now, thay overlap my whole swf an I can’t manipulate anything …

    ( Reply )
  46. PG

    tim June 8th

    any smal tip how to make things clickable? pls! anyone?

    ( Reply )
  47. PG

    dudouz June 12th

    what if i want to make the movement of the gallery automatic, on mouse over…based on the center of the stage??
    can any one help me?

    ( Reply )
  48. PG

    raz June 14th

    I get Error #2044: Unhandled ioError:. text=Error #2032: Stream Error. URL: backend.php
    at Gallery()
    when clickining on either link to demo.

    ( Reply )
  49. PG

    Paul June 20th

    Hello,

    I like this gallery very much, but it seems like when I compile the .fla from source, the .swf is made wrongly: it doesn’t work right. Flash doesn’t seem to show any errors either.

    Author, could you please make a revision of this tutorial and make it fully work?

    Thanks in advance.

    ( Reply )
  50. PG

    Seb June 26th

    Hi, very nice tutorial !

    can u guy give my a tips to make this slider repeating itself infinitely ? I will like to remove the scroller and make it slidable with the position of the mouse.

    Thanks!

    ( Reply )
  51. PG

    yogiii July 3rd

    Hello, i did it :) Used wamp server and looks great. But when I call it from an external SWF it doesn’t work. What to do? :(

    ( Reply )
  52. PG

    nodisturb July 10th

    Thanx, when i learn (i hope like you) AS3 i put some tutorials here, thanx for you time pal.
    Peace

    ( Reply )
  53. PG

    Reige July 13th

    Awesome! I’d like to see a version of this WITHOUT the slider. In its place, the direction of the slideshow follows the motion of the mouse — the images moves left when the mouse goes to the left; right, when the mouse moves right.

    ( Reply )
  54. PG

    Dexter July 15th

    Sigh I tried everything and nothing works. I wish errors can be fixed, and the source files fixed. And reuploaded. with all the folders in place, and files in the proper folders. I’ve been at it for 2 hours and nothing works and i’m giving up.

    ( Reply )
  55. PG

    Rishi July 15th

    Hi, Firstly AMAZING tutorial !
    beautiful slider Gallery, just what I envisioned.
    I have asked this in the comments and dont mean to double comment, but right now i need all the help I can get.

    Just how do I load the gallery as an external swf ?
    I keep getting type error #1009.

    ( Reply )
    1. PG

      rataxes July 22nd

      In order to avoid the error messages you need to do one of two things.

      1. Upload all the files to a server and view them live via the Internet.

      2. Rather than create a dynamic XML list via PHP, create an XML document that lists your images, then change the link in the .as files to reference the XML document rather than the PHP document.

      Both solutions finally worked for me.

      ( Reply )
  56. PG

    Cahz July 22nd

    This is great, but can make it to play by itself?

    ( Reply )
  57. PG

    rataxes July 22nd

    This is a fantastic gallery and is a great base for something I wanted to create.

    However, not being very familiar with AS3, I’ve been beating myself up trying to figure out some of the quirks and add some of my own ideas. (Obviously I’m not the only one having issues with it.)

    My main concern at this point is: the images and animation displays fine in Safari on a Mac, and IE on a Windows laptop, but are placed at the left edge of the stage when viewed in Firefox on a Mac. What in the world would cause this?

    ( Reply )
  58. PG

    Rishi July 23rd

    I am trying to attach a preloader to every image before it loads.
    This is just my guess: I am doing
    imageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, preload);

    Perhaps I am not doing it right or maybe the function is never called.
    I ran traces and never found anything that could help.

    Can anyone illuminate me?

    ( Reply )
  59. PG

    Rishi July 25th

    Nevermind, figured it out.
    :P

    http://www.rishighan.com, under the web+print section

    ( Reply )
    1. PG

      Ernie October 15th

      Does anyone have a complete source of this you can send over to me been suck on it for a week now!?

      Images are not coming up at all
      :/

      Someone please respond thanks!

      ( Reply )
  60. PG

    David July 28th

    Hi guys, I am trying to run this gallery, out of the box so to speak, on my PC with php/apache installed. When i run the SWF it doesnt seem to load the gallery images. Opening the php file in my browser will return a correct XML lost of images (if i create a directory called img next to the SWF).

    ( Reply )
  61. PG

    PhoenixPheather August 6th

    anyone got this to display fullsize images on click yet?

    ( Reply )
  62. PG

    Brian August 13th

    To display the images full size would involve adding a mouse click listener to the images and tweening them to a bigger size, and reversing the effect to push it back to the gallery mode.

    Also, to get the whole .swf to load the images, I had to install WAMPS, turn it on, move all my files to the c:\www root directory, and then visit it via http://localhost/gallery.swf

    If you need any help, give me a hollar.

    ( Reply )
  63. PG

    Brandon August 14th

    this was awesome, great organization of classes/functions reminds me of c++ from years back

    ( Reply )
  64. PG

    Michael August 17th

    rather than dynamically create an xml, i have replaced the php with the xml i created based off of the xml at the top of the tutorial. I have reorganized the classes to actually work and i have created an img directory next to the fla/swf. however i continue to get error #2044. i have traced (”img/”+src) to get img/images1 etc. but still does not load the images. Any help would be appreciated.

    ( Reply )
  65. PG

    Ken August 19th

    Gallery.as, Line 3 – 1046: Type was not found or was not a compile-time constant: TextField. – import flash.display.MovieClip;

    Can anyone help me with this error? I’m pretty new to ActionScript3 :(

    ( Reply )
  66. PG

    Nick August 22nd

    5000: The class ‘Gallery’ must subclass ‘flash.display.MovieClip’ since it is linked to a library symbol of that type.

    ( Reply )
  67. PG

    tally August 23rd

    package {

    import flash.display.MovieClip;

    public class Gallery extends MovieClip {

    Additionally, thank you so much for this tutorial! I started learning Flash/AS3 for the first time 3 weeks ago, when someone told me they wanted me to make them some Flash things for their website – this is a great guide to making my project more OO.

    ( Reply )
  68. PG

    mohammed August 30th

    very very good

    ( Reply )
  69. PG

    April September 11th

    Ben,

    Thanks for your tutorial; it was perfect. I’m a graphic designer with a programming degree and very little Flash experience, so I went into this venture with little hope of an actual working model upon completion. However, I have gone so far as to add horizontal centering functionality and am now working on a zoom feature.

    I’m sure more proficient programmers and Flash designers have already offered up these and more sophisticated add-ons, but I’m willing to send you my code if you’d like to add it to the post. I would only ask you note my involvement.

    Thanks again!

    ( Reply )
  70. PG

    Julio Villa September 17th

    Hey ….when i compiile it nothing happens…

    ( Reply )
  71. PG

    ChrisC September 26th

    Keep getting eror: Loaded file is an unknown type. Have tried .jpeg .png .bmp for my image files but no success – anyone know a solution – thank you

    ( Reply )
  72. PG

    Thomas October 4th

    For those who want to add buttons to control the scroller position :)
    Add two buttons (in the example bellow i named them buttonLeft and buttonRight) in the gallery.fla.
    In Gallery.as add in the public function Gallery the two lines bellow:
    moveRight.addEventListener(MouseEvent.CLICK, mouseRightClick);
    moveLeft.addEventListener(MouseEvent.CLICK, mouseLeftClick);

    And add this two private functions:
    private function mouseLeftClick(evt:Event) : void
    {
    var percent : Number = ( theHandle.goToX – slider.x ) / ( slider.width – theHandle.width );
    var imgId : Number = Math.round(percent * ( images.length – 1 ));
    imgId–;
    if(imgId(images.length-1)) imgId=0;
    percent=imgId/(images.length-1);
    theHandle.goToX=percent*( slider.width – theHandle.width )+slider.x;
    theHandle.x=theHandle.goToX;
    goTo( imgId );
    }
    The above functions loop the images ….
    Thanks for the tutorial… Fantastic…

    ( Reply )
  73. PG

    Dhareesh.D.Lal October 5th

    Hello Dear. Its really amazing. I don’t know how to express about it. Any way keep ty up. we are expecting more from you like this. All the best…..

    ( Reply )
  74. PG

    Ernie October 15th

    Does anyone have a complete source of this you can send over to me been suck on it for a week now!?

    Images are not coming up at all
    :/

    Someone please respond thanks!

    ( Reply )
  75. PG

    d October 15th

    same,,

    please if anyone has complete source code let us know?
    just comment with a link somewhere to download – would help us all a lot!

    ( Reply )
    1. PG

      Lilou October 22nd

      Hi you!

      Same thing happen to me.. Does anybody can help..please!? :s I’m not cofortable with php…

      Best regards,

      ( Reply )
      1. PG

        Mohammed Kayyali November 16th

        Hi,
        First thanks a lot Ben Merckx for this amazing tutorial.

        Second,to work on it locally you can do the following:

        1- create a dynamic XML file ( see step 5 and copy paste the output from the php )

        2- in Gallery.as change backend.php to (yourXML.xml)

        3- create a folder and rename it to ( img ) and put your images inside it ( for sure you will put same names as xml :) )

        4- inside flash: File > publish settings > Flash tab > Click Settings ( script: [ActionScript 3.0 ] )

        5-in Source path, link to the classes folder ( Click + icon then folder icon and browse for the classes folder inside your machine ) for example its ( D:\imgSliderAS3\source\classes ) on my machine.

        6-Click OK , and another OK and test it.

        i hope to work with you guys :)

  76. PG

    Jonathan October 25th

    Hello!
    The tutorial is amazing!, but, I was thinking, if the number of photos is much bigger like 400 photos, would it work fine? I mean, the “scroll space” for each photo is very small, you have like 4px to move the scroll before it switches the photo to the center, how could it be for that lot of photos?
    please answer ^^
    Bye!

    ( Reply )
  77. PG

    Bertman October 26th

    does this work in flash cs3?
    I downloaded your source file and stays also still nothing happenes..

    ( Reply )
  78. PG

    Erik November 9th

    hello, I’m trying to work on this image gallery and instead of using a PHP file, I’d rather use an XML one, but apparently I can’t make it work. The XML file is outputted correctly in flash while the SWF shows just a working scrollbar and nothing else. The dynamic text field bottom left shows just 1/0 while the pictures (PNGs) are 7. That’s the content in the XML:

    img/pic1.png
    img/pic2.png
    img/pic3.png
    img/pic4.png
    img/pic5.png
    img/pic6.png
    img/pic7.png

    …and that’s the code in the Gallery.as:

    private var galleryPic : XML;
    private var xmlLoader:URLLoader = new URLLoader();
    private var xdata : XML;
    public var images : Array = new Array();
    private var orgImgId : Number;
    private var skipTo : Number = 0;
    private var loaded : Boolean = false;

    public var imagesClip : MovieClip = new MovieClip();
    public var stageWidth : Number;

    public function Gallery() : void
    {
    stageWidth = stage.stageWidth;
    theHandle.addEventListener( “sliding”, slide );

    imagesClip.y = 180;
    addChild( imagesClip );

    xmlLoader.load( new URLRequest( “galleryPic.xml”))
    xmlLoader.addEventListener( Event.COMPLETE, loadImages );
    }
    private function loadImages( _e : Event ) : void
    {
    var galleryPic:XML = new XML(_e.target.data);
    xdata = new XML( _e.target.data );
    var i : Number = 0;
    for each( var img:XML in xdata.img )
    {
    var my_url:String = images[i];
    images[i] = new Img( img, this );
    images[i].x = 200 * i;
    images[i].id = i;
    i++;
    }
    goTo( 0 );
    trace(galleryPic.*.length());
    }

    Any help would be soooooo appreciated!

    ( Reply )
  79. PG

    Jay November 16th

    OK, so here is my issue. I’ve read through the comments but no one seems to have had the same thing happend.

    My Error is as follows:
    When I try to compile I get TypeError: Error #1006: makeActive is not a function.

    ( Reply )
  80. PG

    Jay November 16th

    Sorry guys, I just tried compiling again and I get:
    1136: Incorrect number of arguments. Expected 0. 1136: Incorrect number of arguments. Expected 0.

    How is that possible? I see that the Img class is expecting 2 arguments.

    Also, just so you know I’ve moved the classes into a directory structure like this;
    com.tutsplus.Gallery
    com.tutsplus.Handle
    com.tutsplus.Img

    I’ve also change the document class to point to com.tutsplus.Gallery and edit the source path of the fla to point to the correct directory.

    Thanks

    ( Reply )
  81. PG

    Jay November 16th

    Ahhh, nevermind. It was a stupid mistake. I’m sorry for the many post.
    I forgot to also adjust the class path in the library items.

    Thanks

    ( Reply )
  82. PG

    Cameron November 19th

    This has got to be the hardest tutorial to follow ever i’m having such a nightmare with it! How come the source file doesn’t work? I think I’ve followed it exactly step by step and still nothing! I’ve been reading the comments and people seem to be having the same problems that i am, but i still can’t seem to fix them!

    I just wasted two days of my project trying to do it.

    ( Reply )
  1. Arrow
    Gravatar

    Your Name
    November 19th