• No results found

Making the big image clickable

In document FLASH ACTIONSCRIPT TUTORIAL (Page 76-84)

3. And of course, the depth level assignment via the getNextHighestDepth() method And the newly attached movie clip is referenced by the currentThumbnail variable.

12.9. Making the big image clickable

Inside the bigClickable() function, the big image's onPress event handler function is defined. function bigClickable():Void { displayBigImage.onPress = function() { removeMovieClip(this); enableThumbs(); descText.text = galleryIntros[clickedGallery]; }; } The line removeMovieClip(this);

removes the big image with the removeMovieClip() method, inside the parenthesis of which is the movie clip destined for removal. The keyword this points to the big image itself, since it is placed inside its onPress event handler function.

After that , the enableThumbs() function call is made. So, the thumbnails will be made clickable again, since the big image has been removed and they can be seen again. You probably noticed that I never made any code that would hide the thumbnails, because the big image effectively covers them all, even when there are twenty of them present. That's just how I solved the problem, of course, if you wish, you may choose to hide them.

Lastly, the description text is reverted to the one that describes the selected gallery section. descText.text = galleryIntros[clickedGallery];

OK! Let me show you now how that nice alpha fade-in effect was achieved. 12.10. Fading in the loaded big image

Why go for a simple image appearance when there is eye-candy like the alpha fading in effect at your disposal? :-) function fadeIn():Void { target.onEnterFrame = function():Void { this._alpha += 10; if (this._alpha>=100) { delete this.onEnterFrame; this._alpha = 100; } }; }

This function consists of an onEnterFrame movie clip event handler. This particular movie clip event is used very often because it makes possible for actions to be performed repeatedly. To be more exact, every line of code contained inside an onEnterFrame event handler will be executed as many times per second as your movie speed is set to. So, if your movie speed is set to 30 fps, the code inside the onEnterFrame event handler will be run 30 times in a second. Ideal for a fade-in effect!

What happens inside is that the _alpha property (transparency) of the target movie clip, into which the big image has been loaded, is increased by 10 each time the event fires.

this._alpha += 10;

Remember that the target movie clip's _alpha property was set to 0 (total transparency, i.e. invisibility) once the onLoadInit() function (one of the two preloading functions) saw that the loaded file was the big image.

And once _alpha becomes equal to or greater than 100 (this._alpha >= 100), the onEnterFrame event handler is deleted and the alpha set to 100.

if (this._alpha >= 100) { delete this.onEnterFrame; this._alpha = 100;

}

The keyword this inside the onEnterFrame event handler function points to the target movie clip, because it is placed inside an event handler function associated with it

(target.onEnterFrame). This function is invoked once the image has been fully loaded. 12.11. Creating the scrolling functionality for the gallery sections menu

I have made an example just for the purpose of showing you how the menu will look like when there are plenty of sections inside it. The section buttons in the example below are not clickable, but the menu is perfectly scrollable. Click on the down button to try it and then the up button when it appears!

The big function that follows, enableGalleryNavigation(), is made of two main parts: the definitions of onPress event handler functions for the two buttons that serve for scrolling the menu: menuDown and menuUp. Just as a reminder, here is a screenshot of these two buttons:

function enableGalleryNavigation():Void { menuDown.onPress = function() {

if (firstLook) {

menuUp._alpha = 100; menuUp.enabled = true; var firstLook:Boolean = false; }

var menuTop:Number = menuButtons._height-Math.abs(menuButtons._y); if (menuButtons._y<=0 && menuTop>=galleryMask._height) {

var targetPos:Number = menuButtons._y-galleryMask._height; menuDown.enabled = false; menuUp.enabled = false; menuButtons.onEnterFrame = function():Void { menuButtons._y += (targetPos-menuButtons._y)/menuSpeed; if (menuButtons._y<=(targetPos+0.8)) { menuButtons._y = Math.round(targetPos); delete menuButtons.onEnterFrame; menuDown.enabled = true; menuUp.enabled = true; } }; } }; menuUp.onPress = function() {

var menuTop:Number = menuButtons._height-Math.abs(menuButtons._y); if (menuButtons._y<0 && menuTop>0) {

var targetPos:Number = menuButtons._y+galleryMask._height; menuDown.enabled = false; menuUp.enabled = false; menuButtons.onEnterFrame = function():Void { menuButtons._y += (-menuButtons._y+targetPos)/menuSpeed; if (menuButtons._y>=(targetPos-0.8)) { menuButtons._y = Math.round(targetPos); delete menuButtons.onEnterFrame; menuDown.enabled = true; menuUp.enabled = true; } }; } }; }

Let's see how the functionality of the menuDown button is set up. To understand what is going on inside the function, keep in mind the following facts:

1. In Flash coordinate system, the vertical direction (Y) is positive downwards. This means the further you go down from the origin point, the bigger the positive value of an object's Y coordinate.

2. Each movie clip has its own independent coordinate system. The origin of this coordinate system is the movie clip's registration point.

menuDown.onPress = function() { if (firstLook) { menuUp._alpha = 100; menuUp.enabled = true; firstLook = false; }

var menuTop:Number = menuButtons._height-Math.abs(menuButtons._y); if (menuButtons._y<=0 && menuTop>=galleryMask._height) {

var targetPos:Number = menuButtons._y-galleryMask._height; menuDown.enabled = false; menuUp.enabled = false; menuButtons.onEnterFrame = function():Void { menuButtons._y += (targetPos-menuButtons._y)/menuSpeed; if (menuButtons._y<=(targetPos+0.8)) { menuButtons._y = Math.round(targetPos); delete menuButtons.onEnterFrame; menuDown.enabled = true; menuUp.enabled = true; } }; } };

The first thing inside the event handler function is an if conditional statement which serves only to activate the menuUp button. If you remember, the menuUp button is invisible in the beginning, to avoid confusing the user. Once the menuDown button has been clicked, its

counterpart will appear and the if statement will never be used again, because the condition will yield as false. if (firstLook) { menuUp._alpha = 100; menuUp.enabled = true; firstLook = false; }

The condition if (firstLook) translates as if (firstLook == true). And when the menuDown button has been clicked for the first time, this condition will yield as true, because the value of the variable firstLook has been set as true at the very beginning of your code (when all the variables were defined).

So, the code between the curly braces, { and }, will be run. It restores the button's alpha

(transparency) property to 100, meaning full opaqueness. After that, the button is enabled (it can be clicked).

menuUp._alpha = 100; menuUp.enabled = true;

After that, the variable firstLook is set to false and that's why the if statement will be ignored every subsequent time that the menuDown button is clicked: the other button has appeared and that's it.

firstLook = false;

Next, the menuTop variable is defined. Keep in mind that the menuButtons variable is the shortcut for the buttonsHolder_mc movie clip, which is itself situated inside the

galleryMenu_mc movie clip. So, the menuButtons movie clip is the one into which all the gallery section buttons were attached from the Library.

var menuTop:Number = menuButtons._height - Math.abs(menuButtons._y);

The value of the menuTop variable is the lowest point of your menu, all section buttons

included. I called it menuTop because the Y coordinate values increase when going down, that's why. This value is obtained by substracting the absolute value (meaning the number itself, whether positive or negative, it will be converted to a positive value) of the vertical position (_y) of the menuButtons movie clip from its height. This value will be used to scroll the menu (to move it) properly, without fear that it will disappear by going off the stage etc.

Next comes an if conditional statement that checks for two things:

 If the menuButtons vertical position is less than or equal to zero (menuButtons._y <= 0) and

 If the value of menuTop is greater than or equal to the height of the galleryMask movie clip, the one that serves as the mask for the menu buttons (menuTop >=

galleryMask._height).

if (menuButtons._y <= 0 && menuTop >= galleryMask._height) { These two conditions ensure that:

 The menu can only be scrolled down if its position is lesser than or equal to zero.

 The menu won't be scrolled down if its lower (menuTop) edge's coordinate is lesser than the lower edge of the mask.

So, if these conditions have been met, the menu will be scrolled down, thanks again to an onEnterFrame event handler function and a few variables defined before it is executed. The variable that gets defined is the following:

The targetPos variable is a reference point up to which the menu will be scrolled. Think of it as an anchor towards which the menu is pulled. Its value is obtained by substracting the height of the mask from the position of the menu buttons. It makes sense: you have to scroll your menu by the height of its mask, so that each time the buttons below the current ones appear.

Next, both buttons that serve for scrolling the menu (menuDown and menuUp) are disabled just before the scrolling begins. You don't want your menu to be moved up and down without control — it is best to lock it until it has reached the targetPos coordinate.

menuDown.enabled = false; menuUp.enabled = false;

And now comes the onEnterFrame event handler: menuButtons.onEnterFrame = function():Void { menuButtons._y += (targetPos-menuButtons._y)/menuSpeed; if (menuButtons._y<=(targetPos+0.8)) { menuButtons._y = Math.round(targetPos); delete menuButtons.onEnterFrame; menuDown.enabled = true; menuUp.enabled = true; } };

The code line that makes the menu move is the one that adds a value to the menuButtons' Y coordinate each time the onEnterFrame event is fired:

menuButtons._y += (targetPos-menuButtons._y)/menuSpeed;

Remember that the addition assignment operator (+=) adds the value on its right side to the cuurent value of the variable on its left side. And what's added is the result of substracting the position of the menu section buttons from the target position point, divided by menu speed. As the menu approaches the target position, the distance is smaller each time and there you have the easing effect. Remember that the lower the value of menuSpeed, the quicker the menu will move. I found 6 to be an optimal value in combination with the speed of the SWF, which was set to 30 fps at the beginning.

And each time the menu approaches the target point, a check must be made to see if the point in question has actually been reached. This is done through an if conditional statement, of course. if (menuButtons._y <= (targetPos+0.8)) {

The if conditional checks if the menuButtons movie clip's vertical position is lesser than or equal to (<=) the target position plus 0.8 pixels (targetPos+0.8). You have to make this so as a safeguard against waiting too long for the menu to reach the target position. This easing method is described in more detail in my sliding image mask tutorial, located on the following URL

http://flashexplained.com/actionscript/making-a-sliding-image-mask/

And, once that condition is fulfilled (meaning that the menu has reached the target position), its position is fixed in place by setting it definitely to the rounded targetPos value. I recommend that you always do that in cases like this, because objects placed on round pixels are rendered much better than in other cases. Well, Flash 8 renders graphics greatly, but ensuring this with round coordinates doesn't hurt.

menuButtons._y = Math.round(targetPos);

Then, of course, you should delete the onEnterFrame event handler, because it has fulfilled its purpose and it is good to take load of the user's computer processor.

delete menuButtons.onEnterFrame;

After that, the buttons for scrolling the menu up and down are enabled again. menuDown.enabled = true;

menuUp.enabled = true;

As for the onPress event handler function that serves to enable scrolling the menu up, the differences are only in the conditions and some other details.

menuUp.onPress = function() {

var menuTop:Number = menuButtons._height-Math.abs(menuButtons._y); if (menuButtons._y<0 && menuTop>0) {

var targetPos:Number = menuButtons._y+galleryMask._height; menuDown.enabled = false; menuUp.enabled = false; menuButtons.onEnterFrame = function():Void { menuButtons._y += (-menuButtons._y+targetPos)/menuSpeed; if (menuButtons._y>=(targetPos-0.8)) { menuButtons._y = Math.round(targetPos); delete menuButtons.onEnterFrame; menuDown.enabled = true; menuUp.enabled = true; } }; } };

The main if conditional statement checks if the position of menu buttons movie clip is lesser than zero and if the lower edge point of the menu buttons movie clip is greater than zero. This time, the target position is determined by adding the height of the mask to the menuButtons' current position.

Congratulations on going through to the end of this tutorial and learning very much about

ActionScript! I am glad that you have followed me until the end. There are some things I want to tell you.

First, this gallery is modular, expandable and pretty powerful. Of course, it could have been done in many other ways: having many thumbnails in each section instead of a maximum of 20, scrolling thorough thumbnails etc. But that would be another gallery.

The main purpose of my tutorial is to teach you to build a powerful dynamic image gallery by combining ActionScript and XML so that you can also build other galleries, which will have different interfaces and menus. I wanted you to show how to handle the main elements of such image galleries: XML, preloading, navigation, visual effects, etc. I hope that you have learned much and that you will use the knowledge in other galleries and create cool Flash websites. Note also that if you are going to have many, many images (let's say, about 100 sections), the XML file is going to be heavy. In that case, you will need to preload the XML too, using the XML object's getBytesLoaded and getBytesTotal methods. Also, note that in this tutorial's code I have limited the number of pictures to 1000. This is more than enough for any practical

purposes. If you need even more than that, just change the if/else if/else statement inside the enableButtons function.

In document FLASH ACTIONSCRIPT TUTORIAL (Page 76-84)