Advanced Buttons |
Using Movie Clips as Buttonsrevised 1/17/08
INTRO: One of my students asked me whether he could include the text on a button symbol instance from outside the button. He wanted to use multiple instances (copies of a single Library symbol) of one button symbol instead of having multiple button symbols each with a unique instance. Text written from outside the button would allow very sparing use of resources. But it just wouldn't work: ActionScript wouldn't write to a dynamic text box inside the button, and even if it did, the presence of the text box disrupted the normal action of the button. The answer is to use movie clips as buttons! Not only is this a good answer, it is the proper one; pros don't use the ready-made buttons availble in Flash at all, the Flash Button object type. It turns out the button object type is a sub-class of the much larger and more powerful movieclip class. This tutorial is meant to turn you away from the old buttons, and get you to embrace the new. First, for clarity, I'm going to call the regular buttons symbols created in flash Flash buttons and those created from movie clips clip buttons. If I just use "buttons" it's generic. The beauty of the hard-wired Flash button is that it's dead easy to use, but for advanced use, it has its limits. To replace them with clip buttons, you have to recreate the button states in your clips, and hand-code the event handlers that are built into Flash buttons. WARNING! DO NOT COPY AND PASTE CODE FROM THIS SITE TO YOUR FLASH DOCUMENT! Inspect the SWF file below: both buttons are movie clips (clip buttons), not Flash buttons. the "GO" button is scripted to make the movie animation roll forward, and the "ON" button has no script on it at all ---> |
||||||||||||||||||||
SWF example |
Note how the "ON" button doesn't act like a button when the cursor rolls over it. Instead of turning to a "pointing finger" as it should, it becomes an insertion point indicator, as if you could type into the button. This is exactly what happens if you try to place a dynamic text box into a button. Useless. But when we code it as a button … all will be different! |
||||||||||||||||||||
| Intro 2. | Making a Clip for the Clip ButtonStart making a clip button the same way you would a Flash button: create a button image, then go Modify > Convert to Symbol. For my clip button, I just used the oval tool with a black stroke and red fill. In the dialogue box, choose "movie clip" as the perameter, and name it some dual-sounding name like "button_mc" that reminds you this is no ordinary clip. Double-click on the new clip to go inside it. You should now be looking at a standard timeline with one layer and your button on one keyframe. Name the layer (always, right?).
|
||||||||||||||||||||
| Intro 2. |
Recreating the Flash Button TimelineInside, a Flash button has a timeline based on user interaction, and you can place keyframes on each button state and place an image that plays on each, as shown here:
You'll need to mimic this structure by placing keyframes at frame positions 1, 5 and 10, as below (these exact frame positions are not critical). NOTE: instructions on setting a hit area like in a Flash button with ActionScript, is covered below *.
Now that your keyframes have been placed and the image (shape) copied at each one, change the fill color at each keyframe to mark the button states when we've coded them:
So when we're done, the button will have an orange fill when the mouse is away from it (the Flash button "Up" state), red when the mouse is over it (the Flash button "Over" state) and green with the mouse button is pushed (the Flash button "Down" state).
NEW NOTE: To add a stop, click on a keyframe (show above with little "a"s) and scroll down to "Actions" to open the frame's Action Panel: type in stop(); in the work area — also, instead of using the frame numbers, you can use frame labels. To use these, create a new layer called "MARKERS" and place keyframes at 1,5 and 10, right above the stops. Click to select frame one, go down to the frame's Properties Panel, and where there's a box with a grayed-out message "Instance Name", replace with the text "up"; at frame 5, do the same and write in "over"; at frame 10, write in "down" — more instructions in another "NEW NOTE" below. |
||||||||||||||||||||
|
|
Scripting Events on the Clip ButtonAs before, we must track button events in our clip button as they are in a Flash button. The states in the Flash button are Up, Over and Down. NEW: ALL THE CODE FOR THE BUTTONS GOES ON THE FIRST FRAME'S ACTIONS!!! UP: This needs no script; your clip button is already coded to stop at frame 1, so what shows from the start of the movie is the "up" state. OVER: Your clip button will track the event of the mouse moving over the clip and gotoAndStop at 5, where the image for the next image/state resides, the button with a red fill. When you go to type the first parens for the event, you'll find "rollOver" on the list: this amounts to the "over" of Flash buttons.
or, if you're using frame labels:
DOWN: Make a new line in the Actions Panel, and begin another event handler. When you go to type the first parens for the event, you'll find "press" on the list: this amounts to the "Down" of Flash buttons.
or, using frame labels:
WAIT, THERE'S MORE: Although the button events on our clip button now seem to match those of a Flash button, in truth they do not. Hidden from view are scripts that handle the vagaries of button actions, such as covering what occurs when the user lets the mouse button up, or doesn't let the button up when its expected. ROLLS OFF WITHOUT PRESSING THE BUTTON : Your button must return to its original position when the user rolls off of it, having pressed it or not. This will reset the button:
or with frame labels:
PRESSES BUTTON, CONTINUES TO HOVER : If the user presses the button, but doesn't roll away to return the button to its "Up" state, the "Over" state must be what shows:
PRESSES BUTTON, BUT RELEASES AWAY: But if the user doesn't remain hovering over the button, when the button is released, it must return to its original "Up" state:
or with frame labels:
*How to set the button's hit area: The hit area of a button is the area of and around the button where the "link finger" cursor appears and the button can be activated. Inside the clip button, create a new layer called "hitarea", drag it to the bottom of the stack, and use the rectangle tool to make a shape you want to represent the button's hit area. Modify it into a movie clip and iname it "hit_rectangle_mc". Alter its alpha to "0", and give it the instance name "hit_rec". At the top of all the code above on the button on the main timeline, add the following:
The "this" is self-referential, that is, the code refers to whatever object it's on. Test the movie. The cursor should switch out to the "link finger" when you roll over the invisible hit area shape. |
||||||||||||||||||||
|
|
Give the Clip Button its InstructionsSo the movie clip now behaves like a button. Now just add the argument to the event handler of your choice. Usually, this is "onRelease", probably because the action of the button doesn't interfere with actions that occur when the button is pressed. Alter the "on release" handler to add a "gotoAndPlay" to make the movie on the main timeline (the root) play by going past the stop on frame 1 to frame 2 when it is activated:
or, if the button is referring to the timeline it is a "child" of, that is inside (which is pretty usual, and very often the root timeline, you'd use parent-child scripting, like this:
NOTE: frame labels can be used instead of frame numbers on the parent, too. | ||||||||||||||||||||
|
|
Putting Different Labels on Instances of a Single Clip Button SymbolNow to the nub of Rob's question, reusing a button design with different texts for different purposes. In our library we have only the one clip button, "button_mc". We have one instance of it on the stage, without an instance name. Give it one now, "buttonclip". Having this name means we can code to the object. Now drag another instance of the clip button from the Library as a "control" in this experiment. Make sure it has no scripting on it, and give it the instance name "testclip". It won't do anything but illustrate that our script is working. Add a layer inside the clip button, and call it "text". With the empty keyframe, use the text tool to place a text box over the button area. Use the rolldown on the Properties Panel to make the box a dynamic text box. Give it the instance name "button_txt" as below.
When you're done with this, the timeline of the button should look like this:
Needless to say, both button instances now have this dynamic text box embedded within, since their symbol has it. If we put a button label in the symbol, it would show up in both instances, which is what we're avoiding with all this. We're going to send different text to the two instances. Since the two instances have different names on the stage, the textbox instance name can be addressed separately(!!). Find the script for frame 1 of the ACTIONS layer. At present, all it has on it is a "stop();". Since this frame will be read on the opening of our SWF, anything we want to set once at the start of the movie can be set here. We'll address the two same-name dynamic text boxes first by the instance names of the objects in which appear, then with their name like this:
The address first locates the clip button one at a time, then the dynamic text box inside them, then the function "text" loads the string (series of letters) GO or ON into them. FINALLY: These strings are being written into the various instances; you could have as many instances of the clip button as you'd like, and if they all had different instance names, you could have as many different labels as you're willing to script. When you test the movie by outputting a SWF, you'll notice that the clip button with the code on it acts like a normal Flash button; although totally identical in internal makeup, the one with no code on it does not. The very act of coding the movie clip like a button makes the movie clip a button.
|