AS Reference  :  Notes Index  :  Resources  :  About/Contact  :  Downloads

Creating a Toggle Button with ActionScript


At the bottom of the event handler page, we looked at several examples of movieclip controls ("buttons") -- some with one frame and actionscript to control the look of the content in that frame on rollOver and rollOut, and some with multiple frames, each defining a different mouse state (up, over, down). Now we'll look at how to make a movieclip that not only changes on rollOver and rollOut, but looks different depending on which of two states it's in (on/off, play/pause, go/stop, etc).

Keeping track of the state

If we're designing a control that can have two states, we need to keep track of which state it's in at any given time. The easiest way to do that is with a Boolean (true/false) variable. It can either be a variable on the main timeline (if we want to track the state globally), or a property of the control, or a property of the thing being controlled.

We also need to indicate to the user the state the control is in currently. This can be done with a one-frame control whose state is changed via actionscript (as in examples 1 and 2 below), or with a two-keyframe control whose state is changed via actionscript to gotoAndStop (or gotoAndPlay) the corresponding keyframe, as in example 3.

Example 1: Changing the visual state (color) with actionscript

We'll look first at an example of the first way (variable on the main timeline). Get a copy of beegame_start.fla if you don't have one already (free download link at right). Delete bee2_mc from the stage. Rename bee1_mc to bee_mc. Add a control layer and drag a copy of beecontrol onto the stage and call it control_mc. That is the control that will change color to indicate which state the movie is currently in, like so:

This is what the code will need to contain:

And this is that code, using the framework on the code structure page:
/*********  DECLARE AND INITIALIZE VARIABLES  **************************/
var flying:Boolean = true;
var controlcolor:Color = new Color(control_mc);

/*********  DEFINE FUNCTIONS, INCLUDING INIT FOR MOVIE SETUP  **********/
// handler for bee1 control on rollover
function growImmediate() {
   // expand to 120% of original size
   this._xscale = 120;
   this._yscale = 120;
}

// handler for bee1 control on rollout
function shrinkImmediate() {
   // return to original size
   this._xscale = 100;
   this._yscale = 100;
}

// handler for bee1 control click
function stopStartBee() {
   // check to see if the bee is flying or stopped
   if (flying) {
      // if it's flying, stop it
      bee_mc.stop();
      // tell the program the bee is stopped
      flying = false;
      // change the color of the control to green
      controlcolor.setRGB(0x0FE50F);
   } else {
      // if it's stopped, start it up again
      bee_mc.play();
      // tell the program the bee is flying
      flying = true;
      // change the color of the control back to pink
      controlcolor.setRGB(0xFFD4FF);
   }
}

// startup code for movie (event property assignments)
function init() {
   control_mc.onRollOver = growImmediate;
   control_mc.onRollOut = shrinkImmediate;
   control_mc.onRelease = stopStartBee;
}

/*********  CALL THE INIT FUNCTION TO START THE MOVIE  *****************/
init();
	

Example 1: Changing the visual state (text) with actionscript

Here's another example, where text on the control changes to indicate what it will do:

Now our control is a movieclip that contains a rectangle on one layer and a dynamic text field on the layer above it. In the textfield, the text is set to be unselectable by "unchecking" the little Ab button in the Properties panel, so it won't interfere with the operation of the movieclip. The text should also be embedded (click Embed and either shift-click Uppercase and Lowercase, or enter the exact characters in your button, eg PLAYSTOP, into the "Include these characters" box). Give the textfield an instance name playstop_txt. The code structure is identical to that above. The only changes are to remove the color instance, make the rollOver action a little smaller, and have the if/else part of the stopStartBee function change the text in the control rather than changing its color. This is that function:

function stopStartBee() {
   if (flying) {
      bee_mc.stop();
      flying = false;
      this.playstop_txt.text = "PLAY";
   } else {
      bee_mc.play();
      flying = true;
      this.playstop_txt.text = "STOP";
   }
}

Other ways to track state

The state of the bee (flying or not flying) can be tracked as we did above with a variable on the main timeline. Alternately, as mentioned above, it can be tracked with a property of the bee movieclip itself, as we'll do in the bee game example, or with a built-in property, like _currentframe, which we'll use below.

Example 3: Changing the visual state by jumping to a frame

In this example, in which a short 9-second videoclip embedded in a swf (with stop actions in its first and last frames) is loaded and can be played with the play button, we've included keyframes in the play/pause control and the sound on/off control to display the visual state change. When the movie is playing, a pause button is displayed; when it is stopped, a play button shows. The sound button works in the opposite way, with the displayed state indicating the current state of the sound (off with a red line through it, on without). You should choose a display state which you think corresponds to one your user would expect.

Since each control has two keyframes built into it, we'll use the _currentframe property of the movieclip to keep track of which state it (and the movie) is in. That is, when playpause_btn._currentframe is 1, we know the movie is currently paused (its start-up state). If it's not 1, the movie is playing. If you download tv_movie1.swf (a swf with a video embedded in frame 1, and stop actions in the first and last frames), and tv_movieplayer_start.fla (from the download link at right, subscription required), you can follow along with the instructions below. Look in tv_movieclip.fla to see the final code.

The first thing we'll look at is the event handlers for the controls. Each control needs to have a function assigned to its onRelease event property, and those functions, according to the framework discussed on the code structure page, go into section 4 of our code. So initially, our code will look like this:

/************  1. DOCUMENT MOVIE, AUTHOR, HISTORY  ***************************/
// put your documentation here

/************  2. IMPORT CLASSES  ********************************************/
// don't need these for this movie

/************  3. DECLARE AND INITIALIZE VARIABLES  **************************/
// we'll get to this later

/************  4. DEFINE FUNCTIONS, INCLUDING INIT FOR MOVIE SETUP  ***********/

// define a handler function for the play pause button
// remember that "this" in this function will refer to the play pause control 
// because the function will be "attached" to that control (by assignment to its 
// onRelease property)

function playPause() {
   // assumes frame 1 contains an indicator that the movie is currently PAUSED
   if (this._currentframe == 1) {
      this.gotoAndStop("playing");
      movie_mc.play();
   } else {
      this.gotoAndStop("paused");
      movie_mc.stop();
   }
}

// define a handler function for the rewind button
function rewind() {
   // assumes frame 1 contains an indicator that the movie is currently PAUSED
   if (playpause_mc._currentframe == 1) {
      // if movie is paused, rewind sends playhead to beginning to wait
      movie_mc.gotoAndStop(1);
   } else {
      // if movie is not paused, rewind sends playhead to beginning and plays
      // goto frame 2 because frame 1 has a stop in it
      movie_mc.gotoAndPlay(2);
   }
}

// define a handler function for the sound on/off button
function soundOnOff() {
   // assumes frame 1 contains indicator of sound currently ON
   if (this._currentframe == 1) {
      this.gotoAndStop("off");
      so.setVolume(0);
   } else {
      this.gotoAndStop("on");
      so.setVolume(100);
   }
}

/************  5. CALL THE INIT FUNCTION TO START THE MOVIE  ******************/
// assume that we will define an init function later
init();

Notice that the soundOnOff function refers to a variable so, which is an instance of the Sound class that we'll set up to control the sound in the movie. Thus, we need to create a variable of type Sound in our variable initialization section. We'll also create a variable vloader that we'll use to control the loading of the swf. Section 3 of your code should be modified accordingly:

/****************  3. DECLARE AND INITIALIZE VARIABLES  ******************/

// create sound object to control all sound in movie
var so:Sound = new Sound(this);

// create video loader object to load video swf
var vloader:MovieClipLoader = new MovieClipLoader();

The last thing we need to do, now that variables have been initialized and functions defined, is to think about what needs to happen when the movie starts up. We have our requisite variables in place, and we have the requisite functions in place. What we don't have is any assignment of those functions to the event properties of the corresponding controls. We'll put those assignments inside an init function, so add this to the section 4 code:

function init() {
   // set up play/pause (toggle) button to play or stop movie
   // by assigning the playPause function to the button's onRelease property
   playpause_mc.onRelease = playPause;

   // set up rewind to restart the movie
   // by assigning the rewind function to the button's onRelease property
   rewind_mc.onRelease = rewind;

   // set up sound button to toggle sound on/off
   // by assigning the soundOnOff function to the button's onRelease property
   sound_mc.onRelease = soundOnOff;
}

One other thing we need to do at the beginning of the movie is to assign a function to the channel 1 control to make it load a swf when it's clicked. Sticking with our method of first defining event handling functions, we'll add this code to section 4:

function onChannel1Click() {
   vloader.loadClip("tv_movie1.swf", "movie_mc");
}

and then assign that function inside the init function, which will now look like this (also in section 4):

function init() {
   // set up play/pause (toggle) button to play or stop movie
   // by assigning the playPause function to the button's onRelease property
   playpause_mc.onRelease = playPause;

   // set up rewind to restart the movie
   // by assigning the rewind function to the button's onRelease property
   rewind_mc.onRelease = rewind;

   // set up sound button to toggle sound on/off
   // by assigning the soundOnOff function to the button's onRelease property
   sound_mc.onRelease = soundOnOff;
	
   // set up channel 1 button to load tv_movie1.swf into movie_mc
   ch1_mc.onRelease = onChannel1Click;
}

Now everything is declared, defined and assigned. We've even added the code already in section 5 to start the movie going by calling the init function.

There are many embellishments that could be made to this movie to improve it, including:

Intro
Flash: What & How
Example Sites
Create
Draw, Edit Shapes
Gradients
More Drawing Tips
Import
A Sample
Animate
Frames, Keyframes
Motion Tweens
More Motion Tweens
Shape Tweens
Masks
Control
Stop/Replay
Movieclips Intro
Movieclip Reference
Site Structure 1
Slideshow Movieclip
Contact Form
Scroll Resume
Preloader
Site Structure 2
Publish
Display Options
Player Detection
Optimize
AS 2.0 Basics
Intro to Syntax
Playhead Commands
Playhead Cmds 2
Coded Tween
onEnterFrame
Intro to Classes
Declare/Assign
Comments, Trace
Simple Data Types
Arrays & Objects
Code Blocks
Operators
Beyond Buttons
Code Structure
Toggle Controls
Group of Buttons
Drag and Hit
Distort Magnifier
Scroll Text
Bee Game
Dart Shooter
Sound Control
Easing Slider
Easing Slider 2
Components Intro
Timers & Delays
Dynamic Content
Intro
Drawing API
Create Text
Attach Movieclips
Easing Slider 3
Easing Slider 4
Load jpg/swf
Sliding Viewer
Preload swf
XML
Easing Slider 5
Server Comm
LoadVars (w/ PHP)
AS - PHP Lookup
Text File
Database 1:LoadVars
Database 2:Remoting
Read from directory
AS 2.0 Classes
Intro
Math
Key
Date
Color
EventDispatcher
New Samples
Pie Chart
Event-model Emailer
Tween Sequence
Fuse Sequence
SVG in Flash
Bitmap Topo
SWF as Data Holder
Two-level Menu
Yahoo! Flash Maps
Class-based Game
ASTB Samples
Disclaimer
3D Outlines
Bounce Collide
Address Book
Save Drawings
Home  :  Notes Index  :  Resources  :  About/Contact  :  Downloads