AS3 How to and Tips > Repeat Effect for Buttons

Some user interface effects are so ubiquitous it is easy to take them for granted. Many beginners are surprised that holding down the mouse button on a button does not trigger a repeated event. When the button controls motion (as in many video games), this is unintuitive. This little how-to shows a simple application where we take for granted this "hold down to repeat" effect -- namely, the buttons that everyone uses to set a timer or an alarm clock. Try it below, noting that we are only implementing buttons to change the "minutes," nothing else.

As you can see, pressing the button once increments/decrements the minute display, but pressing and holding automatically steps up/down the minutes. Some super fancy clocks even have the feature that if you hold the button down for a while, the change in display speeds up. Since we use a Timer object to manage the auto-change behavior, we implement this additional feature -- it's easy because the delay property of a Timer object can be adjusted programmatically on the fly.

To learn more about the Timer object, see our Basic area tutorial, Using the Timer and Date classes. To learn about technical issues concerning performance of timers, see Use and Performance of the Timer Class in the How To area.

Download

Download the Flash CS3 file for this tutorial:

Setting up the stage

To keep the code focused on the "repeat button" effect, we place as much on the stage as possible. In particular, we need two buttons called btnInc and btnDec, respectively.

The ones shown at the right were created by drawing a filled triangle with the PolyStar tool and converting it to a button using Modify > Convert to Symbol. If you are not inclined to create your own buttons, we recommend selecting your favorite fast forward and rewind buttons from Window > Common Libraries > Buttons. In addition, we create a simple dynamic textbox with instance name txtMinutes and static text placed as shown on the right.

Stage for Repeat Button Example

The code for RepeatButton.fla

The complete code with comments is given below.

var firstDelay:Number = 300; // Initial delay (in msecs) for auto-changing minutes.

var tm:Timer = new Timer(firstDelay,0); // Timer object for auto-changing minutes.

var min:int = int(txtMinutes.text); // A global variable for the minutes.

var chng:int = 1; // This variable is 1 or -1 so we can add it to min for both buttons.

The tmChange function, defined at the bottom of this page, will be exectuted on each firing of tm's TIMER event.

tm.addEventListener(TimerEvent.TIMER,tmChange);

Add the mouse event listeners: The MOUSE_DOWN event on btnInc initiates incrementing; rolling off the button or letting MOUSE_UP anywhere will stop incrementing. The button btnDec is handled similarly.

btnInc.addEventListener(MouseEvent.MOUSE_DOWN, autoInc);

btnInc.addEventListener(MouseEvent.ROLL_OUT, stopChange);

stage.addEventListener(MouseEvent.MOUSE_UP, stopChange);

 

btnDec.addEventListener(MouseEvent.MOUSE_DOWN, autoDec);

btnDec.addEventListener(MouseEvent.ROLL_OUT, stopChange);

stage.addEventListener(MouseEvent.MOUSE_UP, stopChange);

The function autoInc immediately increments min and then starts the Timer object tm with chng=1. Note that the reset method is called in order to put tm.currentCount back to 0. This is important in the TIMER event handler (tmChange), defined further below. The function autoDec is similar but with chng=-1.

function autoInc(mevt:MouseEvent):void {

min++;

displayMinute();

chng = 1;

tm.delay = firstDelay;

tm.reset();

tm.start();

}

 

function autoDec(mevt:MouseEvent):void {

min--;

displayMinute();

chng = -1;

tm.delay = firstDelay;

tm.reset();

tm.start();

}

This function, which simply stops the Timer object tm, is executed on MOUSE_UP or ROLL_OUT.

function stopChange(mevt:MouseEvent):void {

tm.stop();

}

The tmChange function is the heart of the program. In it we change the value of min and update the display. If tm has fired more than 5 times, we reduce the tm.delay value; if tm has fired more than 15 times, we reduce the tm.delay even more. This produces the effect of having the timer speed up as it is held down longer.

function tmChange(tevt:TimerEvent):void {

min += chng;

displayMinute();

if (tm.currentCount > 15) {

tm.delay = firstDelay/5;

return;

}

if (tm.currentCount > 5) {

tm.delay = firstDelay/2;

return;

}

}

The displayMinute function adjusts min to keep it in the 0 to 60 range and updates the display on the screen, adding a leading 0 when necessary.

function displayMinute():void {

if (min > 60) {

min -= 60;

}

if (min < 0) {

min += 60;

}

if (min < 10) {

txtMinutes.text = "0" + String(min);

}

else {

txtMinutes.text = String(min);

}

}

Back to AS3 How To and Tips              Back to Flash and Math Home

We welcome your comments, suggestions, and contributions. Click the Contact Us link below and email one of us.

Adobe®, Flash®, ActionScript®, Flex® are registered trademarks of Adobe Systems Incorporated.