Workshop Chapter 4. Building a Slide Show

CONTENTS

    After the last couple of workshop chapters, this one will seem like a breeze. That doesn't mean that the results won't be impressive. In this workshop, you'll see how a little code can create a really nice effect. We're going to build a slide show that lets the user step through a series of images in a Movie Clip. Although the user can step forward and back in the slide show, instead of simply jumping to the next frame, we'll make the current page fade out and the next one fade in.

    In addition to creating a slide show, you'll learn two general techniques: First, you'll use the enterFrame event to continuously make changes to the _alpha property of the current slide. You'll also look at how you can deactivate buttons and display a dim version so that when users view the first slide, they can't click the "Page Back" button. Similarly, when users are on the last page, they shouldn't be able to click the "Page Forward" button. Although these two techniques are useful for this workshop, they'll also prove helpful in many of the workshops to come.

    1. First you'll create a Movie Clip with a separate image on each frame. Create a new Movie Clip, insert blank keyframes as you import pictures or just draw something onto each frame. Put the script stop(); in the first frame so that the clip appears to be paused on frame 1 from the start (see Figure W4.1).

      Figure W4.1. Our slide show will be a simple Movie Clip with several frames.

      graphics/20fig01.gif

    2. Drag an instance of this clip onto the Stage and give it an instance name of slides.

    3. In the main timeline, draw a triangle that points to the right and convert it to a Button symbol. Make a copy of the Button symbol and rotate the copy 180 degrees (see Figure W4.2).

      Figure W4.2. The same Button symbol is used in two places, just rotated 180 degrees.

      graphics/20fig02.gif

    4. Give the two buttons instance names of forward and back, respectively. Then place the following code in the first frame of the main timeline (which is where all the code for this workshop will go):

      back.onPress=function(){   goPage(-1);  }  forward.onPress=function(){   goPage(1);  }

      In a minute, we'll write the goPage() function in the main timeline. Just make sure that for the "Forward" button, you use 1 for the parameter. The preceding script uses -1 because it's the "Back" button.

    5. Now we can write the goPage() function. Even though it's not going to be terribly complex, I'd much rather keep the buttons as simple as possible and place all the code in a function. This way there won't be any repeated code. Type this version of the function in the first frame of the movie:

      function goPage(whichWay){   slides.gotoAndStop(slides._currentframe+whichway);  }

      This code just uses the gotoAndStop() method to make the slides clip jump to a frame equal to its current frame plus either 1 or -1.

    6. The clip basically works, but we're going to make the clip fade out first and then jump to the destination frame. To start, add the following script to the frame in the main timeline:

      slides.onEnterFrame=function(){   this._alpha+=this.alphaChange;  }

      If the homemade variable alphaChange were 0 or undefined as it will be if we never assign it this script would have no effect. That is, if on every enterframe we assign the _alpha to be 0 more than it is, nothing happens visually. Recall from Chapter 5, "Programming Structures," that saying _alpha+=alphaChange is the same as saying _alpha=_alpha+alphaChange.

    7. Return to the goPage() function in the first keyframe and add the following line of script:

      slides.alphaChange=-5;

      Although many bugs remain, it's amazing how close to the finish we are. First, notice that regardless of the value of the whichWay parameter received in the goPage() function, we always want the slides instance's alphaChange variable to be negative. Also notice that goPage() is premature in making slides jump to a new frame we don't want the page to advance until it has faded out completely. Finally, if you debug the movie and watch the properties for the slides instance, you'll see that once alphaChange is set to -5, the _alpha property continues to drop indefinitely.

    8. Change the goPage() function so that it appears in its revised form, as follows:

      function goPage(whichWay){   slides.alphaChange=-5;    slides.destinationframe=slides._currentframe+whichway;  }

      Instead of actually making the slides clip "go to" a page, we set a variable in slides called destinationFrame (which won't be used until the clip is ready to advance).

    9. Now we can adjust the onEnterFrame callback on slides. The first line is fine. We just need to keep checking to see whether _alpha has gotten low enough (say 0) at the point when we want to jump to the destination frame (either the next or the previous frame), and then change alphaChange to a positive 5 so that it starts to fade back up. Check out the final version:

      slides.onEnterFrame=function(){   this._alpha+=this.alphaChange;    if (this._alpha<0){     this.alphaChange=this.alphaChange*-1;      this.gotoAndStop(this.destinationFrame);    }    if (this._alpha>100){     this.alphaChange=0;      this._alpha=100;    }  }

      Basically, if _alpha ever goes below 0, we jump to the destination frame and set alphaChange to 5 so that the frame will start "unfading." The last if statement prevents _alpha from going past 100.

      //

      You might not think there's any harm in letting the clip's _alpha increase past 100. However, if you let several seconds pass as it keeps increasing above 100 (to, say, _alpha 300), the next time the user clicks "Forward" or "Back," it will take just as long to come back down from 300 and then below 100, where you'll see the clip fade out again.

      One other note: You just as easily could have written the two conditions for the if statements as _alpha==0 and _alpha==100. Although that might work fine, I think the solution presented in the preceding script is "safer." What would happen if the _alpha skipped past 0 or 100? It won't now with alphaChange being -5 and 5, but it could jump past such round numbers if you decided to start alphaChange at -3. Personally, I always prefer an if statement condition using > or < instead of == (when doing so makes sense, of course).

      This slide show works pretty well. Now we're going to add a feature that deactivates the appropriate buttons when the user reaches the beginning or end of the slide show. It turns out that the current version doesn't break when the user tries paging past either end because the gotoAndStop() method is ignored when you provide a frame number below 1 or above _totalframes. I point out the fact that Flash doesn't break only because you can often save yourself from writing error-checking scripts (for instance, one that makes sure there's a next or previous frame to go to). Instead of writing such an error check, in this exercise we will write a script that simply deactivates the buttons thus eliminating the issue entirely.

      In Flash MX it's really easy to just set a button's enabled property to true or false, as appropriate. Although we'll do that first, you'll see that the technique for making the button look like it's not enabled is a bit trickier. I'll show two solutions for making the button look dim. One way involves changing the _alpha of the button when it's inactive. Another way is just to move the button offscreen to reveal a dim looking graphic that was underneath the whole time (see Figure W4.3). In many ways, this is the easier of the two solutions.

      Figure W4.3. An alternative to "un-enabling" a button is to move it offscreen to reveal a fake button underneath.

      graphics/20fig03.gif

      A more involved solution involves creating a new object class, which is really just a Movie Clip acting like a button but with an additional getter/setter property that we could call "active." I'll show the solution for that later so that you can see a good application for the addProperty() command. Let's do the easy way first.

    10. We need to add code that will lower the _alpha and enabled properties to false for the Forward button (when on the last page) and the Back button (when on the first page). Add two if statements to the goPage() function so that it appears as follows:

       1 function goPage(whichWay){  2   slides.destinationFrame=slides._currentframe+whichway;   3  slides.alphaChange=-5;   4   if(slides.destinationFrame>=slides._totalframes){  5       forward.enabled=false;   6       forward._alpha=50;   7   }   8   if(slides.destinationFrame<=1){  9       back.enabled=false;  10       back._alpha=50;  11   }  12 }

      The two if statements (lines 4 and 8) check to see whether the frame number we're headed to (destinationFrame) is at either end. Notice that I don't just say "greater than total frames" but rather "greater than or equal to total frames." It just seems much safer this way.

    11. It turns out this code is pretty good, but it fails to ever restore the buttons. You could work out an else statement to the two if statements, but I think it's easiest just to add the following six lines of code before the two if statements:

      forward.enabled=true;  forward._alpha=100;  back.enabled=true;  back._alpha=100;  forward.gotoAndStop(1);  back.gotoAndStop(1);

      It might seem weird to go ahead and set everything to enabled=true and _alpha=100; however, it's simple, it works, and the two if statements fix any problems before anyone see anything. If we didn't include those last two lines, there would still be some weirdness when the buttons become inactive (that is, when they stay in their Over state).

      That solution works pretty well. You can probably figure out that you could have plain graphics underneath the two buttons, and rather than setting the _alpha and enabled states, just change the _x or _y property to move them offscreen to leave the graphic behind. There are countless ways to make buttons look inactive.

      Just for fun, I worked out a totally different solution that first involved creating a Movie Clip that would replace the two buttons. Inside this clip, I created four keyframes: _up, _over, _down, and _inactive. The first three keyframes make the clip act like a button, but the last one was my idea. I used the two instances of my new clip in place of the Back and Forward instances. Finally, I placed the following code in the first frame of the movie:

       1 function setActive(toWhat){  2   this.enabled=toWhat;   3   if (toWhat){  4     this.gotoAndStop("_up");   5   }else{  6     this.gotoAndStop("_inactive");   7   }   8 }   9 function getActive(){ 10   return this.active;  11 }  12 MovieClip.prototype.addProperty("active", getActive, setActive);

      Basically, this makes an active getter/setter property for all Movie Clips. (You can learn more about how to create getter/setter properties using the addProperty() command in Chapter 14, "Extending ActionScript.")

    12. With the new active property in place, I can change the goPage() function to the following:

       1 function goPage(whichWay){  2   slides.destinationFrame=slides._currentframe+whichway;   3   slides.alphaChange=-5;   4   5   forward.active=true;   6   back.active=true;   7   8   if(slides.destinationFrame>=slides._totalframes){  9       forward.active=false;  10       forward._alpha=50;  11   }  12   if(slides.destinationFrame<=1){ 13       back.active=false;  14       back._alpha=50;  15   }  16 }

      The point is that setting active to true or false (in lines 5, 6, 9, and 13) takes care of both the enabled property and jumping to a fourth keyframe (_inactive) when appropriate. Arguably, the first solution (step 11) is easier, but this is a great example of how a little extra code can make something even better.

    13. Finally, the Back button is active at the beginning. To fix that, just put some code outside the rest of the code in frame 1 (that is, not inside a function or callback). The following code is all you need:

      back.active=false;

      The workshop is pretty complete now. There are a few things you might consider adding. One would be a Dynamic Text Field inside the clip that displays a message such as "Page 1 of 5" (or something similar). You could place the following statement in the onEnterFrame callback (right after the gotoAndStop() script):

      this.myField.text="Page "+this._currentframe+" of "+this._total  frames;

      Naturally, you'll need a field with the instance name myField.

      Another cool idea is to add some background music and have it fade down and up to match the _alpha of the slides clip. Provided you have a sound in your Library with a Linkage of "music" you can start the music with these three lines of code:

      my_sound = new Sound();  my_sound.attachSound("music");  my_sound.start(0,999999);

      This is boiler-plate Sound Object code, which was covered in Chapter 12, "Objects."

      Finally, add the following line of code inside the onEnterFrame callback function (after _alpha is set line 2 from step 9):

      _root.my_sound.setVolume(this._alpha);

      Now the volume will always match the slide's _alpha. There are tons of other things you might want to try. I have a few variations online that you can check out.

    The main thing that you learned in this workshop chapter was how to use the enterFrame event to make changes repeatedly (in this case, to the _alpha property). In other workshops, including Workshop Chapter 10, "Creating Timers," and Workshop Chapter 12, "Developing Time-Based Animations," you'll learn how to use enterFrame to make changes only when necessary or desired instead of repeatedly, as you did in this workshop. Notice that one flaw of this exercise is that the speed of the alpha change is tied directly to the movie's frame rate. If you change the frame rate, the fade speed also changes. In upcoming workshop chapters, you'll learn ways to make animations based on time rather than on frame rate.

    You also learned how to inactivate buttons both by simply setting the enabled property and also by extending the Movie Clip class (by adding a property).

    I think the best part of this workshop chapter was that we created something that looks really cool, works really well, and takes very little work. It just proves that simple solutions are sometimes best.

    CONTENTS


    ActionScripting in MacromediaR FlashT MX
    ActionScripting in MacromediaR FlashT MX
    ISBN: N/A
    EAN: N/A
    Year: 2001
    Pages: 41

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net