Bookmark now!

AddThis Social Bookmark Button

Most popular

The most viewed tutorials in April:

  1. Best dynamic image gallery
  2. Loading external JPG images
  3. Ultimate preloader

Advertisements

Amazing video loops, stunning photo galleries, video and audio players ready to go! Smooth, amazing flipNavigation system!

Making the ultimate dynamic image gallery in Flash 8 — part 10

12.6. Defining the functionality of the menu section buttons: Enabling the display of the roll over and roll out states and defining which thumbnails shall be loaded

Here's the enableButtons() function which has numberOfGalleries passed as a parameter to it (which is of the Number type) and it does not return a value, hence the Void keyword:

function enableButtons(numberOfGalleries:Number):Void {
for (i=0; i<numberOfGalleries; i++) {
pressedButton = galleryMenu_mc.buttonsHolder_mc["galleryButton"+i];
pressedButton.onRollOver = function():Void {
this.gotoAndStop(2);
};
pressedButton.onRollOut = function():Void {
this.gotoAndStop(1);
};
pressedButton.onPress = function():Void {
removeMovieClip(thumbsDisplayer);
removeMovieClip(displayBigImage);
tracker = 0;
thumbsDisplayer = imagesHolder.createEmptyMovieClip("thumbsDisplayer_mc", imagesHolder.getNextHighestDepth());
clickedGallery = Number(this._name.substr(13));
howManyImages = imagesInGallery[clickedGallery];
whichGallery = galleryNames[clickedGallery];
descText.text = galleryIntros[clickedGallery];
currentRow = 0;
currentColumn = 0;
loadThumbnail();
};
}
enableGalleryNavigation();
}

Almost all the code of the enableButtons() function is wrapped in a for loop which serves to pass through all the gallery section buttons and define their onRollOver, OnRollOut and onPress event handler functions.

for (i=0; i<numberOfGalleries; i++) {

Now you see how important the numberOfGalleries variable is — without it, you wouldn't be able to know the number of gallery section buttons.

The first thing that needs to be done is to set up another shorcut: a variable which will point to each button in your gallery menu as the loop progresses: pressedButton.

pressedButton = galleryMenu_mc.buttonsHolder_mc["galleryButton"+i];

Of course, Flash will process the expression between the angled brackets: [ and ], which will result in galleryButton0, galleryButton1, galleryButton2, etc.

Now comes the definition of the onRollOver event handler function, which gets executed when the user rolls her mouse over a button in the gallery section menu:

pressedButton.onRollOver = function():Void {
this.gotoAndStop(2);
};

Basically, what happens is that the movie clip's (which acts as a gallery section button) playhead gets sent to the second frame, where there is a different background color, to accentuate the rollover effect.

After that, the rollOut event handler function is defined, which gets run once the mouse has been pulled out of the button area. This returns the movie clip's playhead to the first frame, putting it back to its primary state.

pressedButton.onRollOut = function():Void {
this.gotoAndStop(1);
};

NOTE In both event handler functions, the keyword this points to the gallery section button movie clip itself, because it is contained inside the functions (inside the curly braces). Thanks to this, there is no need to specify the full path to the movie clip.

The diagram below explains this functionality well. The gallery section button has a blue background in the first frame and a crimson one in the second frame, when the onRollOver event has been fired and its event handler function executed.

The rollover/rollout functionality of image gallery buttons explained.

And now, a very important event handler function comes up: onPress, which governs what actions will be taken when the user has clicked a button. What will happen is the following:

  1. Any previously existing thumbnails and big image will be removed.
  2. The tracking of the number of thumbnails will be reset to zero.
  3. A new empty movie clip which will hold all the section's thumbnails will be created.
  4. The following information will be retrieved and stored: what gallery section was selected, how many images are in it, the name (title) of the section and its description.
  5. The variables which keep track of the rows and columns into which the thumbnails are placed will be reset to zero.
  6. The function for loading the section's thumbnails will be invoked.

pressedButton.onPress = function():Void {
removeMovieClip(thumbsDisplayer);
removeMovieClip(displayBigImage);
tracker = 0;
thumbsDisplayer = imagesHolder.createEmptyMovieClip("thumbsDisplayer_mc", imagesHolder.getNextHighestDepth());
clickedGallery = Number(this._name.substr(13));
howManyImages = imagesInGallery[clickedGallery];
whichGallery = galleryNames[clickedGallery];
descText.text = galleryIntros[clickedGallery];
currentRow = 0;
currentColumn = 0;
loadThumbnail();
};

Any thumbnails or big images that may have been loaded before are removed with the removeMovieClip() method. If there weren't any present, it doesn't matter — nothing will happen. This is done by removing the placeholder movie clips that are created when the user clicks on a gallery section button or a thumbnail.

removeMovieClip(thumbsDisplayer);
removeMovieClip(displayBigImage);

Then, the tracker is reset to zero.

tracker = 0;

And the thumbsDisplayer empty movie clip is created from scratch, using the createEmptyMovieClip() method. It will hold all the thumbnails of the gallery section that was selected by the user. This movie clip is created inside the imagesHolder movie clip, the empty movie clip which you have created on the stage during the first stages of this tutorial. You could have created this latter one dynamically via ActionScript too, but I wanted things to be a little more diverse and simplified. Not everything needs to be done through coding.

thumbsDisplayer = imagesHolder.createEmptyMovieClip("thumbsDisplayer_mc", imagesHolder.getNextHighestDepth());

There are two parameters used in the createEmptyMovieClip() method:

Now the clickedGallery variable gets its value assigned. This value will be the identification number of the gallery section movie clip which was clicked. Since it is being extracted from the movie clip's instance name, you need to pass it through the Number() method to convert the character into a number.

clickedGallery = Number(this._name.substr(13));

The substr() method of the String object is used to do the extraction, since the instance name of the movie clip is a string (text) value. It goes on like this: suppose that the user clicked on the fourth gallery section button (which is the monochrome section in my gallery example). The instance name of the clicked movie clip will be galleryButton3. Yes, there is the number 3 at the end of the instance name, because, as you remember, in the for loop which is used to create these buttons, the starting value is always zero. The extraction would proceed like this (this is pseudo-code, not real one, just to show you how this process goes):

clickedGallery = Number(this._name.substr(13));
clickedGallery = Number("galleryButton3".substr(13));
clickedGallery = Number(3);
clickedGallery = 3;

The first parameter of the substr() method is the starting point of extraction. The first character in a string (a piece of text) has the position 0 (zero).

The second parameter is the number of characters to be extracted (the length of the new, extracted string). And if it is omitted (like above), then all the characters from that point until the end of the string will be extracted. So it doesn't matter if your button has the name galleryButton3, galleryButton42 or galleryButton128, the number will always get extracted properly, because the extraction starts at position 13 and gets any remaining characters in the string from that point on.

After the extraction has been done, the result is converted to a mathematical value from a plain text character.

And this final value is used three times after that:

howManyImages = imagesInGallery[clickedGallery];
whichGallery = galleryNames[clickedGallery];
descText.text = galleryIntros[clickedGallery];

Specifically, It is used to:

  1. See how many images are in the selected gallery section (howManyImages).
  2. What is the name/title of the selected gallery section (whichGallery).
  3. Get and display the description for the selected gallery section ( descText.text).

All three values are extracted from different arrays. In all three cases, this happens in the same manner, so I will explain it for the gallery title, for example. Let's suppose again that the user clicked on the fourth (monochrome ) button, so the value of the clickedGallery variable is 3. Flash will proceed like this:

whichGallery = galleryNames[clickedGallery];
whichGallery = galleryNames[3];
whichGallery = "monochrome";

Why so? Because the number between the angled brackets: [ and ] points to the value at the position no. 3 inside the galleryNames array. You may already know it, but here it is: the first value inside an array in ActionScript has the position 0. The image below explains this nicely.

The position of elements inside an array.

Now you see how the values for the other two variables were extracted from their respective arrays, too.

Next, the values of the variables which serve to place the thumbnails into rows of five are reset to zero:

currentRow = 0;
currentColumn = 0;

Then the loadThumbnail() function is invoked, which will load the thumbnails for the chosen gallery section. This functions comes in the code just after the current one. Remember that all of this happens when the user has clicked on a gallery section button.

loadThumbnail();

Once all of three event handler functions (onRollOver, onRollOut and onPress) for all the gallery section menu buttons have been properly defined, there is still one line of code (outside the for loop, so it is executed once the loop has reached its end) that is going to be run:

enableGalleryNavigation();

This calls the enableGalleryNaviagtion() function which sets up the scrollability of the menu via the two buttons (up and down). This function will be defined at the end of all the gallery's code.

Let me explain you now what happens when a gallery section button has been clicked and the thumbnails begin to load via the loadThumbnail() function.

Top of page

12.7. Thumbnail positioning and thumbnail preloading

So, the user has clicked on a gallery section to see its images. Here is the function that will attach the thumbnail holders, place them in an orderly fashion and trigger the preloading, so that the user can see that something is actually happening!

function loadThumbnail() {
currentThumbnail = thumbsDisplayer.attachMovie("thumbnail holder", "thumbnail"+(tracker+1), thumbsDisplayer.getNextHighestDepth());
target = currentThumbnail.thumbImage_mc;
if ((tracker%5) == 0 && tracker != 0) {
currentRow += 1;
}
if (currentColumn>3) {
currentColumn = 0;
} else if (tracker == 0) {
currentColumn = 0;
} else {
currentColumn += 1;
}
currentThumbnail._x = currentColumn*thumbMarginX;
currentThumbnail._y = currentRow*thumbMarginY;
currentThumbnail.percent_txt._visible = true;
thumbNumber = currentThumbnail._name.substr(9);
thumbPath = "gallery/"+whichGallery+"/thumbs/"+thumbNumber+".jpg";
whatIsLoading = "thumb";
loader.loadClip(thumbPath, target);
}

The first action inside the function is the process of attaching a thumbnail holder movie clip from the Library, to the thumbsDisplayer empty movie clip. This is done with the attachMovie() method which you have already encountered in this tutorial.

currentThumbnail = thumbsDisplayer.attachMovie("thumbnail holder", "thumbnail"+(tracker+1), thumbsDisplayer.getNextHighestDepth());

The parameters of the method are as follows:

  1. The Linkage identifier, which serves to pull the movie clip out of the Library: "thumbnail holder".
  2. The new instance name of the attached movie clip: "thumbnail"+(tracker+1). So the Instance names will be thumbnail1, thumbnail2, thumbnail3... and so on, until thumbnail20. Remember, I created the gallery so that each section can have a maximum of 20 thumbnails. I have written (tracker + 1) here because I don't want the name of the first thumbnails to be thumbnail0, but thumbnail1. Why? Because I will need to extract that number later to point to the thumbnail JPEG image, and the first thumbnail in each gallery section is name 1.jpg and not 0.jpg.
  3. And of course, the depth level assignment via the getNextHighestDepth() method.

And the newly attached movie clip is referenced by the currentThumbnail variable.

Next, the target variable is defined, which will tell Flash where the external thumbnail will be loaded into. As you can see in the line of ActionScript code below, it is being loaded inside the thumbImage_mc empty movie clip of the current thumbnail holder.

target = currentThumbnail.thumbImage_mc;

And now come the chunks of code which serve to position the thumbnails into rows, 5 thumbnails per row. First, the counting of rows is done.

if ((tracker%5) == 0 && tracker != 0) {
currentRow += 1;
}

The important thing to be aware of here is that this line serves to place thumbnails in rows of 5, so the condition(s) will be fulfilled for thumbnail number 6, 11and 16 (when tracker equals 5, 10 or 15). This means that when those thumbnails' turn comes, the value of the currentRow variable will be increased by 1 (currentRow += 1).

There are two conditions in the if conditional statement here and both must be fulfilled in order for the code inside the curly brackets to be executed:

For example, what happens at the beginning, when tracker equals 0, or when it equals, say, 3 or 5? Let me show you how Flash makes the calculation in all three cases:

(tracker%5) == 0 && tracker != 0
(0%5) == 0 && 0 != 0

You don't even have to look at the first condition in the example above, because the second condition is false. It says that zero does not equal (!=) zero, which is false. And when just one condition turns out as false, the whole thing is scrapped and the code inside the curly braces (currentRow += 1) is skipped altogether.

OK, let's see now what happens when tracker equals 3.

(tracker%5) == 0 && tracker != 0
(3%5) == 0 && 3 != 0
3 == 0 && 3 != 0

This time, it is the first condition that yields as false (it says that 3 equals 0, which is false) and so the whole thing is again false.

And now, the case when the value of tracker reaches either 5, 10 or 15:

(tracker%5) == 0 && tracker != 0
(5%5) == 0 && 5 != 0
0 == 0 && 5 != 0

Both conditions are now true, because zero does equal zero and five does not equal zero. Here, the value of currentRow will be increased by 1 and this will be used later to place the subsequent five thumbnails into the next row.

Ok, you need now to see the code that will ensure that the thumbnails are set apart from each other:

if (currentColumn>3) {
currentColumn = 0;
} else if (tracker == 0) {
currentColumn = 0;
} else {
currentColumn += 1;
}

Translated into english, this if/else if/else conditional statement means this:

if (the value of currentColumn is greater then 3 — meaning it is not 0, 1, 2 or 3) {
reset the value of currentColumn to 0
} on the other hand, if (tracker equals zero) {
reset the value of currentColumn to 0
} and in all other cases, meaning when currentColumn is either 0, 1, 2 or 3 {
increase the value of currentColumn by 1
}

And finally, the code that actually positions the thumbnails on stage based on what I just explained to you.

currentThumbnail._x = currentColumn*thumbMarginX;
currentThumbnail._y = currentRow*thumbMarginY;

The _x and _y properties, as you know by now, position a movie clip horizontally and vertically on the stage. The value of currentColumn is multiplied by thumbMarginX and that of currentRow is multiplied by thumbMarginY. These two values serve to put some space between the thumbnails. You defined them at the beginning of your code, remember? They are set to 96 and 68, respectively. This is the value of space between the thumbnails expressed in pixels.

The spacing between image gallery thumbnails.

And now the dynamic text field inside the thumbnail holder is made visible:

currentThumbnail.percent_txt._visible = true;

Using the substr() method of the String object (a text object, and the name of a movie clip is a piece of text), the number of the thumbnail is extracted:

thumbNumber = currentThumbnail._name.substr(9);

As I have told previously in this tutorial, the first parameter of the substr() method is the place where the extraction starts. And when the second parameter (length) is omitted, as above, all the characters from the exatraction point up to the end of the string will be extracted. Why do this? Because like that, you will be able to extract the number of the thumbnail, whether it is a one or two-digit number. No need to write any conditional statements at all here. The image below explains this clearly (the blue numbers are character positions inside the string):

The substring method used without the length parameter.

And the value of the thumbNumber variable is used next to point to the right thumbnail which needs to be loaded:

thumbPath = "gallery/" + whichGallery + "/thumbs/" + thumbNumber + ".jpg";

The line above is using simple concatenation (the joining of two or more strings together) to create the path to the thumbnail. Again, remember well that this path is relative to the HTML page inside which your image gallery SWF is embedded.

For example, if the third thumbnail of the essays gallery section were to be loaded, Flash would create the path like this:

thumbPath = "gallery/" + whichGallery + "/thumbs/" + thumbNumber + ".jpg";
thumbPath = "gallery/" + "essays" + "/thumbs/" + "3" + ".jpg";
thumbPath = "gallery/essays/thumbs/3.jpg";

Subsequently, you have to tell Flash what is loading, the thumb or the big image:

whatIsLoading = "thumb";

And finally, the loadClip() method of the MovieClipLoader object (which is called loader, you created it earlier, remember) is used to tell Flash to start loading (and preloading) the current thumbnail:

loader.loadClip(thumbPath, target);

The first parameter inside the parenthesis is the external file that is going to be loaded (a JPEG thumbnail in this case). The second parameter is the target empty movie clip into which the external file will be loaded.

And now that the loadClip() method has been invoked, the MovieClipLoader and its associated listener will start working together and preload the image and display it, with the DropShadow filter applied to it. You can read again (I recommend it, it will be much more clear to you now) how this is done on the page which explains the use of the onLoadInit() and onLoadProgress() methods.

Now you know how the placement and preloading of thumbnails is done! Move on to see how the functionality of the thumbnails is defined.