Creating a Four-State Button With the Flash Timeline and ActionScript 3.0

Creating a Four-State Button With the Flash Timeline and ActionScript 3.0

This tutorial came about after looking online for help with the very same topic. A lot of people seem to be asking the same question, but it was hard to find a neatly packaged set of instructions to follow.

So, like any decent netizen, I cobbled together this article, gaining inspiration from a couple of other blogs and using experience from some trial and error on my own. And now I offer it to you, hoping this will end your own search.

This tutorial uses Flash CS4 in combination with ActionScript 3.0, but you can apply these principles in Flash CS3. It presumes you already have a pretty good handle on creating animations in the timeline and a fair understanding of how to apply ActionScript to the timeline.

The aim is to have a navigation button in the form of a tab, tucked away to the side, for stepping backwards through an image presentation. I want it to slide open, change color and display its label. When the user clicks on it, it will navigate back one slide. If the user mouses out before clicking on it, it will slide back to its original position and color.

Note: remember to save often to avoid starting from scratch should something go wrong.

Limits of the Button Symbol

Flash gives you the ability to create a button symbol, but it’s limited to three states: Up, Over and Down. There is also Hit which defines the interactive area around the button. This is fine for most uses of a simple button. In fact, this button symbol is actually a member of the SimpleButton class. But what if you want to change the appearance of the button or animate it when the user mouses over and then mouses away without clicking? In that case, you will need a fourth state called Out.

The built-in button symbol sadly doesn’t have an out state.

Here’s the takeaway: any symbol, like a graphic symbol or a movie clip symbol, can become a button. You just need to apply the proper ActionScript. In this tutorial, a movie clip will be turned into a button with four states.

Step 1: Storyboard or Sketch the Button

It will make your life a lot easier if you already have a clear visual idea of how your button will behave in each of the four states. Sketch it out on paper or use Illustrator or Photoshop to prototype the visual elements which can in turn be imported into Flash. This is a bit of work up front, but it’s a lot better than working blind and having to go back and fix something because the concept wasn’t thought through logically.

Step 1

Step 2: Set Up the Document

Create a new document and choose Flash File (ActionScript 3.0). Set up the stage with the proper size and background color.

Step 2

Step 3: Create an Empty Movie Clip Symbol

Instead of creating a button symbol, we’ll create a new movie clip symbol. Press Control-F8 (Command-F8 on a Mac) or choose Insert > New Symbol from the menu. We’ll call it “four state button”.

Step 3

Step 4: Add an Actions Layer

In the “four state button” movie clip, add a new layer and call it “actions”.

Step 4

Step 5: Add Labels for the Four States

Create another layer and call it “labels”. Insert four blank keyframes at roughly equal intervals just enough so that you can leave enough room to read each label. Here I’ve put them at 20 frame intervals. Give label names of up, over, down and out in the Properties panel. These will be your button states.

Step 5

Step 6: Create Action Keyframes

Add keyframes in the actions layer which correspond to the four states in the labels layer.

Step 6

Step 7: Add Stop Actions

For each blank keyframe in the actions layer, add this.stop(); in the ActionScript Editor. This will make sure that the movie clip doesn’t play through to other button states.

Step 7

Step 8: The Up State

Create a new movie clip symbol by pressing Control-F8 (Command-F8 on a Mac) or choose Insert > New Symbol from the menu and call it “up animation”.

Step 8

Step 9: Up State Graphic

For the button, draw a green box in one layer and add a white arrow in a layer above. Make sure it’s registered in the top left corner. As this is static, there’s no need for a series of frames for animation, but you always have the flexibility should you decide to animate it, such as a box that fades up into view.

Step 9

Step 10: Add a Stop Action

Create a new layer and call it “actions”. Make sure it’s at the top. Select the blank keyframe and add this.stop(); to the ActionScript Editor. It’s not completely necessary in this case since it’s just a static image, but it’s good practice to keep each state from looping.

Step 10

Step 11: Define the Hit Area

The one thing missing from the button symbol editing mode that you don’t have with movie clips is a special frame reserved for the hit area. This would define the boundaries where mouse events occur like clicks and hovers. Create a new layer and call it “hit area”.

Draw a shape on the layer and set its alpha value to 0 in the Properties panel, making it invisible. This hit area will be as large as the button when it’s fully extended. Note: If you have an animated sequence, make sure the hit area frames span the entire length of the animation.

Step 11

Step 12: Instantiate the up state movie clip

Create a new layer in the four state button movie clip symbol called button states. Drag an instance of the up animation symbol from the Library panel and into the four state button movie clip symbol editing area in the button states layer. Make sure its X and Y coordinates are set to 0. Insert a frame at frame 20.

Step 12

Step 13: The Over State

Press Control-F8 (Command-F8 on a Mac) or choose Insert > New Symbol from the menu and choose Movie Clip. We’ll call it “over animation”.

Step 13

Step 14: Shape Tween Animation

Return to the “up animation” movie clip, click on the green button and copy it. Return to the “over animation” movie clip and add a new layer called “button morph”. Right-click to paste the green button in place in the blank keyframe.

Create another blank keyframe at frame 20 and right-click to paste in place again. With this shape, increase its width and change its color to orange. It should be the same size as the hit area created in Step 10. Select the entire range of frames and right-click to create a shape tween.

Step 14

Step 15: Fade up the Label

To add a button label, create a new layer called “text appear” and use the type tool to create a static text object, in this case, PREVIOUS in a blank keyframe.

Right-click to insert a frame at frame 20. Select a frame in the layer and right-click to create a motion tween. I want the label to fade up starting in the middle of the animation, so I’ll go to the motion editor and create keyframes in the middle and at the end, making three keyframes. The first keyframe will add a color effect with an alpha of 0% and the last two will have an alpha of 100%.

Step 15

Step 16: Define the Hit Area

Add a new layer called “hit area”. You can select the longer orange shape from the end of the shape tween, copy it and paste it in place into a blank keyframe on the “hit area” layer. Select it and give it an alpha value of 0% in the Properties panel. Insert a frame at frame 20 to make the hit area span the entire animation.

Step 16

Step 17: Add a Stop Action

Add a new layer at the top and call it “actions”. Add a blank keyframe at frame 20 and add a this.stop(); action in the actions panel. This will prevent the animation from looping.

Step 17

Step 18: Instantiate the Over State

Return to the “four state button” movie clip. Insert a blank keyframe in frame 21 on the button states layer and drag an instance of the over animation movie clip from the Library. Make sure its coordinates are set to 0. Insert a frame at frame 40.

Step 18

Step 19: The Down State

Create a new graphic symbol by pressing Control-F8 (Command-F8 on a Mac) or choose Insert > New Symbol from the menu and call it “down graphic”. There is no explicit animation required since it will only be displayed instantaneously when the mouse button is being clicked.

Step 19

Step 20: Down State Graphic

For this state, all that is required, optionally, is to change the color of the fully extended button. You can copy and paste in place the orange box as well as the PREVIOUS label from the “over animation” movie clip in their respective layers. Change the orange box to red. Only one frame is required, there is no need for a hit area as the button covers the full area. And, since it’s a graphic symbol, no stop(); action is needed.

Step 20

Step 21: Instantiate the Down State Graphic

Return to the “four state button” movie clip. Insert a blank keyframe in frame 41 on the “button states” layer and drag an instance of the “down graphic” symbol from the Library. Make sure its coordinates are set to 0. Insert a frame at frame 60.

Step 21

Step 22: The Out State

Press Control-F8 (Command-F8 on a Mac) or choose Insert > New Symbol from the menu and choose Movie Clip. We’ll call it “out animation”.

Step 22

Step 23: Reverse the Shape Tween

The out state will essentially be a reversed version of the over state. Return to the “over animation” movie clip and copy the shape tween frames, then come back to the “out animation”, create a layer called “button morph” and paste the frames into the blank keyframe. Then select all the frames in that layer and choose Modify > Timeline > Reverse Frames from the menu.

Step 23

Step 24: Fade Out the Label

Return to the “over animation” movie clip and copy the PREVIOUS text object, then go back to the “out animation”, create a new layer called “text disappear” and paste in place.

Insert a frame at frame 20 then select the range of frames and create a motion tween. You will do the reverse of the motion tween created in Step 15 and create keyframes in the middle and at the end in the Motion Editor, but the first and middle keyframes will have an alpha of 100% while the last keyframe will have an alpha of 0%.

Step 24

Step 25: Add the Arrow

To return the appearance of the button to its original up state, add a layer called “arrow” and place a keyframe in frame 20, leaving the first 19 frames blank. Copy the arrow from the “up animation” and paste in place back in the “out animation” in that last keyframe.

Step 25

Step 26: Define the Hit Area

Again, we need to create a new layer called “hit area” and place a box large enough to cover the full size of the extended button. Give it an alpha of 0 to make it invisible.

Step 26

Step 27: Add a Stop Action

Again, to keep the “out animation” from looping, we need to add a layer called “actions”, put a blank keyframe in frame 20 and add a this.stop(); action in the Actions panel.

Step 27

Step 28: Instantiate the Out State

Return to the “four state button” movie clip. Insert a blank keyframe in frame 61 on the “button states” layer and drag an instance of the “out animation” symbol from the Library. Make sure its coordinates are set to 0. Insert a frame at frame 80.

Step 28

Step 29: Add Event Listeners

Now comes the ActionScript to make it all work. To detect mouse events like clicks and hovers, we need to add event listeners.

Click on the first keyframe of the actions layer in the “four state button” movie clip where we first added a stop action and open the Actions panel. We will add event listeners as shown below to detect a mouse ROLL_OVER, a MOUSE_UP (when the mouse button is released) and a MOUSE_DOWN (when the mouse button is pressed).

We use the ROLL_OVER event instead of the MOUSE_OVER event because of how it treats the child elements of the movie clip in context with the parent movie clip which is more suitable for this setup. We add false, 0, true to the parameters as a good practice to mark these listeners for garbage collection for when they’re no longer needed.

this.addEventListener(MouseEvent.ROLL_OVER, onMouseRollover, false, 0, true);

this.addEventListener(MouseEvent.MOUSE_UP, onMouseClick, false, 0, true);

this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownButton, false, 0, true);

Step 30: Toggling Functions

For each event listener, a function will be called. Each function essentially advances the timeline to the appropriate state within the four state button movie clip and plays that section by referring to the label name.

You’ll notice there’s no event listener created for a MOUSE_OUT event. Instead of creating a standalone event listener, we will simply use the ROLL_OVER event to call up a function which will in turn remove its own event listener and add a new event listener for a ROLL_OUT event. In this setup, a ROLL_OUT event will work better than a MOUSE_OUT event.

The same goes for the opposite, where a ROLL_OUT event removes its own listener and reinstates the event listener for a ROLL_OVER event. By toggling these rollovers and rollouts, we keep the code clean and free from potential conflicts.

function onMouseRollover(e:MouseEvent):void {       e.target.gotoAndPlay("over");
		this.removeEventListener(MouseEvent.ROLL_OVER, onMouseRollover);
		this.addEventListener(MouseEvent.ROLL_OUT, onMouseRollout, false, 0, true);
	}

function onMouseRollout(e:MouseEvent):void {
		e.target.gotoAndPlay("out");
		this.removeEventListener(MouseEvent.ROLL_OUT, onMouseRollout);
		this.addEventListener(MouseEvent.ROLL_OVER, onMouseRollover, false, 0, true);
	}   

Step 31: onMouseDownButton Function

To play the down state, create a function that corresponds to the MOUSE_DOWN event set up by the event listener.

function onMouseDownButton(e:MouseEvent):void {
e.target.gotoAndPlay("down");
}

Step 32: onMouseClick Function

Finally, we need to actually tell the button what to do when it’s clicked. Add a function that corresponds to the MOUSE_UP event. A MOUSE_UP event is essentially the same thing as the last part of a CLICK event (down, then up).

For test purposes, I created a web link in a URL variable (in this case, to Adobe’s website) then added the navigateToURL() method to the function so that I could verify that it’s working. However, you can substitute this method with a call to navigate to another frame label, number or scene using gotoAndPlay or any other method you prefer.

var linkToAdobe:URLRequest = new URLRequest("http://www.adobe.com");

function onMouseClick(e:MouseEvent):void {       e.target.gotoAndPlay("up");
		navigateToURL(linkToAdobe); // you can substitute this with any other method or function
	}

Step 33: Instantiate the Button

The four state button is now ready to be used. Return to the main timeline and drag the four state button movie clip symbol to the stage on its own layer. A substitute background is added on another layer to better see the effect in context with other elements on the stage.

Step 33

Step 34. Test the Movie

Make sure the file is saved and press Control-Enter (Command-Enter on a Mac) to test the movie.

Acknowledgements

Much thanks goes to Alex at Sanctified Studios for inspiring the original idea to use a movie clip as a button and to Dominic Gelineau of Zedia Flash Blog for showing the best way to create rollovers and rollouts in ActionScript 3.

Add Comment

Discussion 34 Comments

  1. André says:

    It´s very novice tutorial, it´s very usefull for who is learning flash now…

    Two tips: use this.buttonMode=true; for hand cursor, dont remove the event listeners, it´s not needed… :D

    • Oto says:

      You can’t use just buttonMode. You will also need to set

      this.mouseChildren = false

      • André says:

        Since he is using static text the mouseChildren=false isnt needed, has no effect use or not it, but one more line doesnt hurt anyone =)

        Explaining for everbody the “this.mouseChildren=false”:
        It disables the mouse for each child of the movieclip, but the movieclip stills interacts with the mouse, but if you set this.mouseEnabled=false; it removes the interaction of the whole movieclip…

  2. Alex says:

    Haha, Gary. When starting to read the tut, I was thinking to myself “Hmm…I wrote a brief tut about doing something like this in AS2 a long time ago.” Turns out it was that article you read.

    Glad that you found the article useful. You should post a follow up with an AS only version of it, so you can get nice backwards playing animations on the over to out state transitions.

  3. Gary Horsman says:
    Author

    @André
    Though removing event listeners is not absolutely necessary, from the sources I researched, it’s a good habit to do some ‘manual’ garbage collection to reduce the memory overhead and also to make sure not to trigger functions due to small mouseover events when the pointer has not left the ‘hotspot’ completely. You can check the link to the Zedia Flash Blog to see the reasoning behind this methodology.

    @Alex
    I appreciate your insight from your original article and helping me to figure out a methodology to accomplish this particular task. Unfortunately, I’m not quite advanced enough to take the AS-only route, but being fluent enough in AS3 to go all-code to develop SWF docs is a nice skill set to have. One day, maybe.

    • Alex says:

      Gary, it’d be a fairly simple task to get buttons working like that, and would probably go a long way to teaching yourself those kind of AS skills. It’s also nice to have a button class you can reuse, lol.

    • André says:

      It´s a good habit you remove the listeners whenever you will no longer use it, like when you remove a child wich have listeners, removind and adding everytime uses less memory but more processing, and more line codes…
      .
      Also a good habbit is programming AS3 in DocumentClass, not in Timeline

  4. BJ says:

    I have to disagree with the usefulness of the tutorial. This execution doesn’t make for a smoother button since you are still jumping around keyframes. If you rollover the button and 1/2 way through the animation you roll out again, the button jumps to the “Out” frame, hence making a harsh jump. In my mind this is a ton of work to have little benefit over the classic built in button. The jump is just in a different place now. All this could be done 100% smooth without jumps using ActionScript and almost evolve the same -or- even less work to setup. Having said that, you did a nice job writing the tutorial and laying out the steps for novice users.

    • Alex says:

      BJ, this provides a solid starting point for adding functionality that you can’t really have with a SimpleButton, like additional states (selected, disabled, etc).

      It’s also nicer to do button intro animations this way, rather than having a bunch of keyframes on your main timeline. If you have to change the instance name of your button…its way easier to change it once, than it is to have to do it on every keyframe of an animation.

      This is just a step towards being DRY in Flash/AS. And you can’t argue that not repeating yourself isn’t a huge time saver in any moderately sized project.

  5. Dave says:

    Seriously? I mean if you had created the entire thing with classes and drawing with as3, maybe, but a timeline button? I mean, if you guys need some cool flash tuts you just let me know…

    • Ian Yates says:
      Staff

      Suggestions are always welcome :)

    • Gary Horsman says:
      Author

      I believe activetuts+ was looking to provide more tutorials for novices, in other words, those who are just beginning to add interactivity using AS3 to their Flash movies.

      I realize there’s a contingent of developers who favor using more advanced methods employing code only, but that’s for another tutorial, which I am sure if you were willing to take the time write, these fine people at activetuts+ would be more than happy to pay you to do.

      The title is “Creating a Four-State Button With the Flash Timeline and ActionScript 3.0″, which would probably indicate that this was not really intended for members of the AS3-code-only set. So I’m surprised you bothered to even read the article if it obviously didn’t apply to you.

      I’d be very interested to read your tut on the same exercise but without the Flash IDE. Some of us are just on different parts of the journey learning this platform, Dave, and I think that’s okay.

      Thank for your comment ;)

  6. Steve says:

    It is very glitchy and buggy. Doesn’t even actually work either..I never see a DOWN state. I would suggest doing this with all code..timeline animation can be used in certain situations, but this wouldn’t be very hard to achieve with AS.

  7. In my opinion this kind of approach is wrong, because the mouse pointer is not changing to Pointer, it stays in standard mode, so the user can`t understand that it is a button.

    So You can just create standard button, and make a MovieClip animation to use it in OVER, other animation in the DOWN and etc…

    • Gary Horsman says:
      Author

      Good point. In a standard button, the pointer would change, but since this is a movie clip, that hasn’t been taken into account. I was relying on the visual cues to help the user understand what the function of the animation would be.

      • ASIM says:

        u can set mc.buttonMode = true;
        this wiill enable a movieclip to behave like a button. [shows a hand when pointer is over]

  8. Karl Macklin says:

    Is the demo correct?

    I was expecting to see something at least somewhat similar to the Button type in Flash, but this is just buggy – no down state, jumps frames like crazy.

    How about some nice tweening on ROLL_OVER and ROLL_OUT?

    • Gary Horsman says:
      Author

      You’re right. The animation could be a little jumpy because the button’s a bit large and the animation slow. A faster animation and a tighter, smaller button might have helped resolved some of these issues.

  9. otaner says:

    your code is to long you can do it the same in a simple code lines

  10. Erik says:

    Who is picking tutorials on this site?

    The last two tutorials have had an awfully low level of professionality.
    I kind of expect tutsplus tutorials to be high quality throughout the whole material.

    Of course I respect anyone doing their best, I mean nothing personal on you Gary, but this site should not post amateur material. I think 80% of the readers here could make something better than this in 5 minutes.
    Congratulations to Gary for getting your tutorial posted, and thumbs down to tutsplus for posting it.

    Btw, someone should actually make a tutorial to show Gary how to do this in a better way.

    • Ian Yates says:
      Staff

      Well, that would be me..

      We try to cover a broad range of topics and abilities on all the Tuts+ sites; it’s difficult to please everyone all the time. This concept sparked my interest as it was an approach to solving a Flash problem for novices, by a non-seasoned Flash developer.

      At the very least it’s triggered good discussion here in the comments and you can expect a comprehensive guide to buttons in the near future.

      • Erik says:

        I like the idea of “for novices, by non-seasoned” – the result is just not what I expect to see when viewing tutorials on activetuts. Well the world is not always what you expect and maybe I shouldn’t have been so quick to judge and rant.

        But maybe the concept should be explained or the tutorial be visually tagged somehow to indicate the reader on what to expect beforehand. The “for-novice-by-novice” concept might even get it’s own featuring or section of tutorials, providing novice developers with a useful platform for increasing their skills by discussion and feedback from more experienced readers.

        There goes my idea-making brain again.

      • Ian Yates says:
        Staff

        You’re quite right Erik!

        Plans are already underway to improve the tagging and categorizing of tuts (across all the Tuts+ sites).

        We’re also looking into providing info with each tut (similar to what Sean at Vectortuts+ does). This way you’ll be able to see difficulty grading, time and skills needed, that sort of thing.

        Stay tuned – and thanks for the feedback :)

  11. Gary Purdue says:

    I’m sorry but I have to say that this tutorial is far too basic, and not even advantageous to learning flash.

    I myself haven’t created any tutorials so I give you some credit and well done for taking the time and effort to create this tutorial. But the reason I haven’t created a tutorial is because I feel I wouldn’t be able to give users an informative and useful tutorial, even though I’ve been using flash for 10 years, teaching it is something different.

    Like has been said above, if it used classes or some tweening, it might feel more useful. This seems like something I would learn in my first time using flash 5!!

  12. Ray says:

    Great tutorial. Can you add to it or point to another blog/tutorial that can show a programmer, who uses flex, can use this in how code to create a swf? I mean your button with the fade and states is great and I want to add the concept to my code but as a strict programmer who lives in flex and flex builder I am not sure how to import or utilize the above. I recognize that I would need to change the URL gets you make above when the user clicks a button into an event call so that flex can receive it but not sure how to import it all as a button so that I can manipulate and place it where I need.

  13. André says:

    Ok, i didnt want to get in deeper in this discussion, but as Erik said, the level of the tutorials are going down, i can see too much of timeline programming here using AS3 (it´s not more tham actionscript 2.0 using actionscript 3.0 syntax), some buggly tutorials, the first thing i´ve note on this tutorial, when i pass the mouse fast over the button when it´s returning from over state, it will stay on over state even the mouse is out, also i didnt see the down state as promissed on the title, using timeline for programming, wich is a very bad habbit for AS3.0…

    Just a point to see:
    When anyone write a tutorial, should test it about 10 times before send it to avoid bugs, i know a 100% bugless tutorial is very difficult, but it´s a good way avoid hard bugs.

    Just a tip, using TweenLite class you can go forward and backward in timeline using some ease…

  14. Gary Horsman says:
    Author

    Thanks to everyone for their comments and criticism.

    Some of the points were delivered with a bit of a harsher attitude than I had anticipated and I guess I should have expected it from this kind of crowd. I didn’t expect to start a mini flame war over such a benign topic like Flash buttons, but I suppose some people take this kind of stuff more seriously than others.

    I wrote this article because no one else did. It’s certainly far from perfect, obviously. But if any one of you really felt that I somehow dropped the ball, by all means, please go ahead and write a better tutorial. I’m serious. I think it would be a benefit to everyone concerned, including myself. You can call it: ‘A Better Way to Create a Four-State Button With the Flash Timeline and ActionScript 3.0′ and I’d be happy to let it stand in place of my own. And you’ll make a little spending dough in the meantime.

    So let’s see you guys put your money where your mouth is and let’s see some competent writing from the true experts. I welcome the enlightenment.

  15. Radu says:

    The DEMO is wrong I think,
    I’ll give it another go tomorrow but if it’s still that buggy, I believe this is the most rubbish tutorial placed on a pretentious website.

    I think you spent more time doing 1.jpg than anything else.

  16. henrylow says:

    1. mings and goings of the Internet marketing industry. Sure there are times like this when a report surfaces talking about their issues and concerns but, for the most part, we like to talk about big brands and how they do the Internet marketing thing well or not so well.

    onlineuniversalwork

  17. Joe Horan says:

    I use AS2 for a lot of things yet, simply because I feel it’s simpler (And I’m too lazy to look into AS3).

    I downloaded this .mxp called “mc tween” and it made smooth tweening, color changing, etc SOOOOOOOOOOOOOOOOOO much easier.

    So here is me, suggesting it!

  18. alvin says:

    which frames and layer do you put script steps 29-33

  19. Kamil says:

    want to know the same thing as alvin above ^^^

    Where do you put the scripts in steps 29-33??

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.