Creating an Image Gallery in Flash

 

This tutorial will teach you how to create an animated interactive Flash gallery. The gallery items could be scrolled through horizontally and a larger image is displayed when a thumbnail is clicked. We are going to create this gallery using ActionScript only. We will be using ActionScript loops, conditionals, and the Tween class. You can follow this tutorial without necessarily knowing much about all of these, but you will benefit more if you do read each of the tutorials we have previously written on each of these topics.

You can examine an example of our gallery we will be creating below.

Setting Up the Images

It is possible to use images of any size for following this tutorial as the code that we will write will layout the images depending on their actual width and height as long as all the thumbs are of the same width, however, for the gallery to fit the stage that we will use, I recommend that you use the same sizes I specify when following this tutorial.

You will have to create thumbnails for each of your images, the size that I used here is 150x150 pixels, while the actual images of the gallery are 400x400 pixels each. The naming convention for images and thumbnails is as follows:

  • image1, image2, image3, image4
  • thumb1, thumb2, thumb4, thumb5

It is important to take note of this naming convention as we will use it when setting the linkage names of our library items in the tutorial.

You can create your own 10 thumbs and images, or you can alternatively download my set of images to use to save time when following the tutorial. Here is a zip file containing the images used in this tutorial.

Starting off

Start up a new Flash movie, use ActionScript 2.0. Set the stage dimensions to 450x450 pixels and the frame rate to 30. We are going to use the default white for the background.

Movie Properties - Properties Inspector

We will now import the images into our library, go through File>Import>Import to Library, browse to find the images you extracted from the zip file you downloaded earlier (both the large images and their thumbs), select all the images and import them in one go.

Import All Your Images to the Library

All your images should now be in the Library which you can view by press Ctrl+L on your keyboard. We need to create movie clip symbols for each of our images so that we can call these images at runtime using ActionScript. This is a relatively lengthy manual process. Start off by dragging the very first image from your library (image1) and onto the stage, and then press F8 to convert it to a symbol. Name in accordance with its actual image name, image1, set the symbol type to Movie Clip, and set the registration point to top left corner. This last point is very important as it is easier to align objects on the stage when their location is in reference to their top left corner. When you are done with this, click on Advanced to configure some more options.

Convert the Image to Symbol

When you click on Advanced you should get an expanded set of options for Linkage and Source settings. We are going to use the Linkage settings to be able to use create an instance of this object at runtime using ActionScript. So click on the option to Export for ActionScript, that should automatically generate an Identifier for your instance that is identical to its name, if it is not, make sure that says image1, we are going to use this identifier to refer to this object later. The option for Export in first frame should also be checked by default. When you finish click on OK.

Advanced Symbol Options

You should now have a copy of this movie clip symbol on stage and in your library as well. Our next step is going to sound weird, but you now have to delete this instance from the stage because we are going to call it from the library directly using ActionScript and we don't need to have it on stage. To do this select it on stage and press delete.

You cannot call an image from the library directly using ActionScript without first converting it to a movie clip symbol. That is why we have to convert all of our images to move clips.

We are done working on the first image, you have to repeat this process for each of the images in your library, it is not really a lengthy process, all you have to do is drag you image onto stage, press F8 to convert it to a symbol, assign an instance name to it in accordance with the name of the image (ie image2, image3, thumb2, thumb3), and check the option to Export it for ActionScript, and then delete this copy from the stage. All settings such as the movie clip type and registration point should be set in accordance with the previous symbol automatically. When you're done, you should have nothing on stage, but your library should have a set of movie clip symbols for each of the images and thumbs. To verify that you have completed this stage properly, you can check that all the names of the new movie clips and their linkage properties are identical to the image names by inspecting the library panel.

Flash Library Items

Creating the Container

Start off by right-clicking the only frame on stage and type the following code to create your container. The code is really simply, a new empty movie clip is created with the instance name container and at the depth 1. The depth is the the level or layer number at which the movie clip is located.

this.createEmptyMovieClip("container",1);

Attaching the Images and Aligning Them on Stage

We will use the movie clip method attachMovie to attach instances of our movie clips to this container, we will use a loop to repeat the code for the number of images that we have. We will save the number of images in a variable because it will be used multiple times.

The attachMovie method requires three parameters, the identifier to locate the symbol in the library, a new instance name to refer to the item later in ActionScript, and the depth at which the item is to be located. The loop below generates the values for each of these on the fly, our first thumb is called as thumb1, it is given the instance name thumb1_mc, and it saved on level 1. Please refer to the loops tutorial to learn how this works.

var imagesNumber:Number = 9;
for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
}

The code above should be enough to load all your thumbnails from the library and put them on stage, but the problem here is that they all will be placed over each other, so you will only be able to see the one you loaded last. To fix this problem we will have to assign new _x values for each of the clips as they are assigned. We will have to create a temporary variable to hold the name of the clip and then we will position the images next to each other by calculating the width of the thumbnails aligned before. The position of any thumb will be calculating by adding up the width of all preceding thumbs. The diagram below demonstrates an example.

 

 

Positioning Boxes on Stage Using ActionScript

Here is our code, the bold part is what we have added in this stage.

var imagesNumber:Number = 9;
for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
myThumb_mc = container["thumb"+i+"_mc"];
myThumb_mc._x = (i-1)*myThumb_mc._width;

}

To make our scrolling gallery look nicer we should align the container vertically to the center of the stage, to do this we have to change the _y property of each of the image. To align the images to the center of the stage we will recall the height of the actual stage and calculate the distance at which the object has to be positioned at using the following simple formula:

Align Center

We can find the values of x (the height of the stage) and y (the height of the thumbnail), so we can just use these to calculate z (the distance at which the object needs to be positioned to be at the center). Here is our updated code:

var imagesNumber:Number = 9;
for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
myThumb_mc = container["thumb"+i+"_mc"];
myThumb_mc._x = (i-1)*myThumb_mc._width;
myThumb_mc._y = (Stage.height-myThumb_mc._height)/2
}
It is important to note that the properties of the Stage class are not the same as those for instances of the Movie Clip class. The code above shows an example, the height property is .heightwithout the underscore sign present in the property of a movie clip.

Creating the Scrolling Effect

If you test your movie now, you should be able to see some of the thumbnails aligned next to each other, the rest will not be seen because they go beyond the visible part of the stage. The moving part of our gallery will solve this. The movement of the gallery in the sample that I showed you earlier reacts to the position of the mouse on the stage. We are going to use a math formulate that uses the width of the stage and position of the mouse on it to determine whether the _x position of the container movie clips should be increased or decreased (in other words making it move left or right) and by how much.

It is possible to use a much simpler command to increase the _x position if the mouse has reached a certain place on stage and then decrease the value of _x if the mouse bypasses that point, but that will not create a smooth animation similar to the one that you will create. Our code makes use of the Cosine graph which creates a wave that has a positive value in the first half a negative value in the second half, if you consider the location of the mouse as the _x axis of the graphic and the _y axis as the amount by which the _x property of the container should increase or decrease, you will realise that this is perfect for our gallery.

Cosine Graph For ActionScript Animation

I apologise if this sounds too complicated for some, but you can easily use it without necessarily understanding the math behind it anyway. The code has been attached to an onEnterFrame handler property assigned to the container movie clip so that this code is executed repeatedly throughout. The number 15 at the end is a variable which could be changed to speed up or down the movement of the gallery. The code below is to be pasted below what we have written before.

container.onEnterFrame = function (){
this._x += Math.cos((-_root._xmouse/Stage.width)*Math.PI)*15;
)

A problem that we have now is that our gallery will scroll in any of the two directions without stopping at the end, we will fix this by using a conditional to check if the movie exceeds any of the two limits, on the left or the right, and position it at the maximum or minimum position it is allowed to be in if that happens. The code we added a minute ago is changed this way.

container.onEnterFrame = function() {
this._x += Math.cos((-_root._xmouse/Stage.width)*Math.PI)*15;
if (this._x>0) {
this._x = 0;
}
if (-this._x>(this._width-Stage.width)) {
this._x = -(this._width-Stage.width);
}

};

You can test your movie now to get a result similar to this.

 

Assigning a Variable to Each Thumb

We will first assign a reference to each of the thumbnails to hold the number of image it should load, this is necessary because each button has to load a different image from the others. To do this, we have to add to the loop that we created earlier the code in bold below.

for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
myThumb_mc = container["thumb"+i+"_mc"];
myThumb_mc._x = (i-1)*myThumb_mc._width;
myThumb_mc._y = (Stage.height-myThumb_mc._height)/2
myThumb_mc.largerImage = i;
}

i in the previous code segment is a reference to the counter of the loop, which should be identical to the number of image being referred to at that instance.

Making the Buttons Clickable

Now to make our thumbs actually clickable, we have to assign a onRelease event handler property to each thumb within that same loop at as well, this property will tell the main timeline to attach the thumbnail we need. We have used attachMovie before, so it should be understandable now.

for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
myThumb_mc = container["thumb"+i+"_mc"];
myThumb_mc._x = (i-1)*myThumb_mc._width;
myThumb_mc._y = (Stage.height-myThumb_mc._height)/2
myThumb_mc.largerImage = i;
myThumb_mc.onRelease = function(){
_root.attachMovie("image"+this.largerImage,"large_mc",2);
}

}

The larger version of each thumbnail should now be displayed when the thumbnail is clicked, you can test the movie to see it in acton. However, you might want to position this movie at the center of the stage, the same way we did for the thumbnails vertically earlier. We will do it this time for both the _x and the _y properties.

for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
myThumb_mc = container["thumb"+i+"_mc"];
myThumb_mc._x = (i-1)*myThumb_mc._width;
myThumb_mc._y = (Stage.height-myThumb_mc._height)/2
myThumb_mc.largerImage = i;
myThumb_mc.onRelease = function(){
_root.attachMovie("image"+this.largerImage,"large_mc",2);
large_mc._x = (Stage.width - large_mc._width)/2;
large_mc._y = (Stage.height - large_mc._height)/2;
}
}

To make our larger image delete itself when clicked, we simple add another event handler property that does exactly that.

for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
myThumb_mc = container["thumb"+i+"_mc"];
myThumb_mc._x = (i-1)*myThumb_mc._width;
myThumb_mc._y = (Stage.height-myThumb_mc._height)/2
myThumb_mc.largerImage = i;
myThumb_mc.onRelease = function(){
_root.attachMovie("image"+this.largerImage,"large_mc",2);
large_mc._x = (Stage.width - large_mc._width)/2;
large_mc._y = (Stage.height - large_mc._height)/2;
large_mc.onRelease = function(){
this.removeMovieClip();
}
}
}

You can now test your movie to see a fully functional scrolling gallery! It is not as polished as the example we showed in the first page, but it works fine.

Creating a Hover Effect for the Thumbnails

The hover effect that we will apply is pretty simple, our buttons will have a transparency of 50% when they are created and will be fully opaque when the user rolls the mouse over it. We also have to add a code to set the transparency to 50% again when the mouse rolls out of the thumbnail. This code is pretty simple all you have to do is update the thumbnail creation loop with the following code in bold:

for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
myThumb_mc = container["thumb"+i+"_mc"];
myThumb_mc._x = (i-1)*myThumb_mc._width;
myThumb_mc._y = (Stage.height - myThumb_mc._height)/2;
myThumb_mc._alpha=50;
myThumb_mc.largerImage = i;
myThumb_mc.onRollOver = function(){
this._alpha=100;
}

myThumb_mc.onRollOut = function(){
this._alpha=50;
}

myThumb_mc.onRelease = function() {
_root.attachMovie("image"+this.largerImage,"large_mc",2);
large_mc._x = (Stage.width-large_mc._width)/2;
large_mc._y = (Stage.height-large_mc._height)/2;
large_mc.onRelease = function() {
this.removeMovieClip();
};
};
}

Creating a Fade-In Fade-Out Animation

We are going to use the Tween Class to animate the transparency of the images, we are going to use a very basic tween for the _alpha property from zero to 100, this should be easy to understand if you have read our Tween Class Tutorial. We are going to use the event handler .onMotionFinished to delete the movie at that instance of the movie clip upon the completion of the fade out tween. Update the the creation loop in accordance with the code in bold:

//Paste this code at the top of your existing code to be able to use the Tween Class

import mx.transitions.Tween;
import mx.transitions.easing.*;
for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
myThumb_mc = container["thumb"+i+"_mc"];
myThumb_mc._x = (i-1)*myThumb_mc._width;
myThumb_mc._y = (Stage.height - myThumb_mc._height)/2;
myThumb_mc._alpha=50;
myThumb_mc.largerImage = i;
myThumb_mc.onRollOver = function(){
this._alpha=100;
}
myThumb_mc.onRollOut = function(){
this._alpha=50;
}
myThumb_mc.onRelease = function() {
_root.attachMovie("image"+this.largerImage,"large_mc",2);
large_mc._x = (Stage.width-large_mc._width)/2;
large_mc._y = (Stage.height-large_mc._height)/2;
new Tween(large_mc,"_alpha",Strong.easeOut,0,100,0.5,true);
large_mc.onRelease = function() {
var myFadeOut = new Tween (large_mc,"_alpha",Strong.easeOut, 100,0,0.5,true);
myFadeOut.onMotionFinished=function(){

large_mc.removeMovieClip();
}
};
};
}

An easy combo that we can do along with this is to fade out the existing thumbnails at the same as the time to clear the stage for the main image.

for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
myThumb_mc = container["thumb"+i+"_mc"];
myThumb_mc._x = (i-1)*myThumb_mc._width;
myThumb_mc._y = (Stage.height - myThumb_mc._height)/2;
myThumb_mc._alpha=50;
myThumb_mc.largerImage = i;
myThumb_mc.onRollOver = function(){
this._alpha=100;
}
myThumb_mc.onRollOut = function(){
this._alpha=50;
}
myThumb_mc.onRelease = function() {
_root.attachMovie("image"+this.largerImage,"large_mc",2);
large_mc._x = (Stage.width-large_mc._width)/2;
large_mc._y = (Stage.height-large_mc._height)/2;
new Tween(large_mc,"_alpha",Strong.easeOut,0,100,0.5,true);
new Tween(container,"_alpha",Strong.easeOut,100,50,0.5,true);
large_mc.onRelease = function() {
var myFadeOut = new Tween (large_mc,"_alpha",Strong.easeOut, 100,0,0.5,true);
new Tween(container,"_alpha",Strong.easeOut,50,100,0.5,true);
myFadeOut.onMotionFinished=function(){
large_mc.removeMovieClip();
}
};
};
}

Stopping the Gallery from Scrolling and Disabling the buttons while the large image is displayed

If you test your gallery before applying this optional section you should be able to notice that the gallery still scrolls around when the image is displayed, it is even possible to click on the visible thumbs through the margins on the sides of the stage. To stop this we can use a conditional and the enable property of the button class.

To stop the scrolling, we will create a variable that is checked before moving the gallery, when a button is clicked, the value of this variable changes to false and when the image is remove its value is changed back to true. This will require applying changes to four sets of the code: (1) we have to create our variable at the beginning of the code, (2) we will have to change the value of the value when the button is clicked, (3) we have to change the value of the variable when the image is removed, and (4) then we will have to check for the variable each time the gallery needs to scroll. Here is the update code of our entire gallery:

import mx.transitions.Tween;
import mx.transitions.easing.*;

this.createEmptyMovieClip("container",1);
var imagesNumber:Number = 9;
var scrolling:Boolean = true;

for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
myThumb_mc = container["thumb"+i+"_mc"];
myThumb_mc._x = (i-1)*myThumb_mc._width;
myThumb_mc._y = (Stage.height-myThumb_mc._height)/2;
myThumb_mc._alpha = 50;
myThumb_mc.largerImage = i;
myThumb_mc.onRollOver = function() {
this._alpha = 100;
};
myThumb_mc.onRollOut = function() {
this._alpha = 50;
};
myThumb_mc.onRelease = function() {
scrolling = false;
_root.attachMovie("image"+this.largerImage,"large_mc",2);
large_mc._x = (Stage.width-large_mc._width)/2;
large_mc._y = (Stage.height-large_mc._height)/2;
new Tween(large_mc, "_alpha", Strong.easeOut, 0, 100, 0.5, true);
new Tween(container,"_alpha",Strong.easeOut,100,50,0.5,true);
large_mc.onRelease = function() {
scrolling = true;
var myFadeOut = new Tween(large_mc, "_alpha", Strong.easeOut, 100, 0, 0.5, true);
new Tween(container,"_alpha",Strong.easeOut,50,100,0.5,true);
myFadeOut.onMotionFinished = function() {
large_mc.removeMovieClip();
};
};
};
}

container.onEnterFrame = function() {
if (scrolling){
this._x += Math.cos((-_root._xmouse/Stage.width)*Math.PI)*15;
if (this._x>0) {
this._x = 0;
}
if (-this._x>(this._width-Stage.width)) {
this._x = -(this._width-Stage.width);
}
}
};

The very last addition that we can use to polish up our gallery is to disable the buttons that could be clicked through the margins around the large image. Doing this will require using another loop to cycle through all the thumbs and change their enabled property. This property should be changed when a button is clicked, and when the fade-out motion of the large image finishes. We will also have to add the code to set the transparency back to 50% because the RollOut action will no longer work for the button clicked as it will no longer be enabled. Here is our new updated code for the whole thing.

import mx.transitions.Tween;
import mx.transitions.easing.*;

this.createEmptyMovieClip("container",1);
var imagesNumber:Number = 9;
var scrolling:Boolean = true;

for (i=1; i<=imagesNumber; i++) {
container.attachMovie("thumb"+i,"thumb"+i+"_mc",i);
myThumb_mc = container["thumb"+i+"_mc"];
myThumb_mc._x = (i-1)*myThumb_mc._width;
myThumb_mc._y = (Stage.height-myThumb_mc._height)/2;
myThumb_mc._alpha = 50;
myThumb_mc.largerImage = i;
myThumb_mc.onRollOver = function() {
this._alpha = 100;
};
myThumb_mc.onRollOut = function() {
this._alpha = 50;
};
myThumb_mc.onRelease = function() {
this._alpha=50;
for (i=1; i<=imagesNumber; i++) {
var myClip = container["thumb"+i+"_mc"];
myClip.enabled = false;
}

scrolling = false;
_root.attachMovie("image"+this.largerImage,"large_mc",2);
large_mc._x = (Stage.width-large_mc._width)/2;
large_mc._y = (Stage.height-large_mc._height)/2;
new Tween(large_mc, "_alpha", Strong.easeOut, 0, 100, 0.5, true);
new Tween(container,"_alpha",Strong.easeOut,100,50,0.5,true);
large_mc.onRelease = function() {
scrolling = true;
var myFadeOut = new Tween(large_mc, "_alpha", Strong.easeOut, 100, 0, 0.5, true);
new Tween(container,"_alpha",Strong.easeOut,50,100,0.5,true);
myFadeOut.onMotionFinished = function() {
for (i=1; i<=imagesNumber; i++) {
var myClip = container["thumb"+i+"_mc"];
myClip.enabled = true;
}

large_mc.removeMovieClip();
};
};
};
}

container.onEnterFrame = function() {
if (scrolling){
this._x += Math.cos((-_root._xmouse/Stage.width)*Math.PI)*15;
if (this._x>0) {
this._x = 0;
}
if (-this._x>(this._width-Stage.width)) {
this._x = -(this._width-Stage.width);
}
}
};

You should get something very similar to the movie below if you test your movie now.