pause Timer with ExtendedTimer in ActionScript 3.0
hey guys, last week i needed to pause several timers and resume them later on. i ran into a problem which i try to explain in an little example.
so let’s say you start a Timer with 1000 milliseconds delay and stop it after 600 milliseconds. if you call Timer.start() again, it starts with a new delay of 1000 milliseconds again. there is no built-in possibility to resume the timer for the remaining 400 milliseconds. i thought “nothing easier than that, just call Timer.pause()”. but there was no such method, so i decided to write my own ExtendedTimer class and add the pause functionality. now i like to share it with you…
> ExtendedTimer.as
package com.fjakobs.utils
{
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* @author fjakobs
*/
public class ExtendedTimer extends Timer
{
private var _startTime : Number;
private var _initialDelay : Number;
private var _paused : Boolean = false;
public function ExtendedTimer(delay : Number,
repeatCount : int = 0)
{
super(delay, repeatCount);
_initialDelay = delay;
addEventListener(TimerEvent.TIMER,
onTimer,false,0,true);
}
private function onTimer(event : TimerEvent) : void
{
_startTime = new Date().time;
delay = _initialDelay;
}
override public function start() : void
{
if(currentCount < repeatCount)
{
_paused = false;
_startTime = new Date().time;
super.start();
}
}
public function pause() : void
{
if(running)
{
_paused = true;
stop();
delay = delay - (new Date().time - _startTime);
}
}
public function get paused() : Boolean
{
return _paused;
}
public function get initialDelay() : Number
{
return _initialDelay;
}
}
}
Categories: ActionScript 3, flash, general, utils


I’d rather make it:
delay = event.target.currentCount;
why exactly would you do this?
Thanks for code. But there’s little bug – then repeatCount reaches it’s maximum, method start() will trigger anyway. I added:
override public function start() : void {
if(currentCount < _repeatCount){
_paused = false;
_startTime = new Date().time;
super.start();
}
}
where _repeatCount is repeatCount from consructor. Now it’s work fine.
hey – make it a static function, and you’re a genius!
@Nikita, thank you for the tip, i updated the start method. now the timer won’t trigger if you call start() after the timer reaches it’s maximum repeatCount.
@grabek, do you think about a TimerManager?
Another slight issue I faced is that in :
override public function start() : void
{
if(currentCount < _repeatCount)
{
_paused = false;
_startTime = new Date().time;
super.start();
}
}
… the “if” will never return true if _repeatCount is 0 since currentCount and and _repeatCount have the same value initally. Appending
|| _repeatCount == 0
to the if statement solved the problem for me.
Oh, and needless to say: Lovely piece of code. Thanks a lot.
TimerManager – I suppose so! (:
Hey, thanks for this class!!! But, I’m newbie in AS3, classes!
How I use this code in my class document after import it?
(sorry for my poor english… I’m brazilian)
Yep! It’s works fine here now! Thanks!!!
very useful class. Thanks! I had to add this:
public function pause():void {
if (running) {
_paused = true;
stop();
var thisDelay:Number = delay – (new Date().time – _startTime);
if (thisDelay < 0) {
thisDelay = 0;
}
delay = thisDelay;
}
}
I kept getting errors when var delay was below 0.
Very useful thanks so much!!
@Peter – might be a little late but this is how you use it.
Once you import the class do the following.
1. Create a var with type Number and set it to how long you want the timer delay.
var newTimer:Number = 5000; //timer will run every 5sec
2. create a new instance of ExtendedTimer and pass in the timer var you just created above.
var timer1:ExtendedTimer = new ExtendedTimer(newTimer);
3. Now just use timer1.start(); and timer1.pause(); to pause the timer. To resume simply call timer1.start(); again.
That should do it! Good Luck
Thank you, saved me some time
This saved me a lot of hair pulling and time.
I needed the ability to reset this ExtendedTimer after it was paused but calling reset() didn’t reset the timer. I realized that was because you are adjusting the delay whenever start() was called.
I created a new function called resume() which acts like your start() function. I then modified your start() function to set delay = _initialDelay; This essentially resets the timer.
// timer continues from where it left off
public function resume() : void
{
if((currentCount < repeatCount) || (repeatCount == 0))
{
_paused = false;
_startTime = new Date().time;
super.start();
}
}
// timer gets reset
override public function start() : void
{
if((currentCount < repeatCount) || (repeatCount == 0))
{
delay = _initialDelay; // added to “reset” timer
_paused = false;
_startTime = new Date().time;
super.start();
}
}
So now I can either call start() which always resets the timer or I can call resume() which resumes the timer.
Thanks again for the code!
I used this code to fix up my own pausable timer – very helpful, thanks
I also encountered the “delay 0) //if there’s no remainder, timer should start next cycle
{
delay = remainder; //otherwise, timer should finish current cycle
}
that is really usefull. thank you..
Hello man,
I made it too
http://blog.ramonfritsch.com/t/timer-com-pause
cheers
Great little class. Just one thing I’d like to add which may be useful to others. I found that if I’d set the delay after the class was instantiated, then the specified delay would only work once, and afterwards it would revert to the original delay that was specified when the class was created. After adding the following, the problem was solved
override public function set delay(n:Number):void {
super.delay = n;
_initialDelay = n;
}
I should also mention that if you implement my fix from above, then you should change line 46 to:
super.delay = delay – (new Date().time – _startTime);
…unless you also use DorkBot’s fix (recommended), then change his line delay = thisDelay; into super.delay = thisDelay;
does anyone have a stable, complete, working, tested, etc, version of this? I see a bunch of evolution going on, wondering if I could get a final version? thanks to all
Here is the version I compiled with all of the above changes. It seems to be working great! Hope this helps everyone. I know this has been a huge benefit to me!
-Kipp
——————
package com.fjakobs.utils
{
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* @author fjakobs
*/
public class ExtendedTimer extends Timer
{
private var _startTime : Number;
private var _initialDelay : Number;
private var _paused : Boolean = false;
public function ExtendedTimer(delay : Number, repeatCount : int = 0)
{
super(delay, repeatCount);
_initialDelay = delay;
addEventListener(TimerEvent.TIMER, onTimer, false, 0, true);
}
private function onTimer(event : TimerEvent) : void
{
_startTime = new Date().time;
delay = _initialDelay;
}
// timer gets reset
override public function start() : void
{
if((currentCount < repeatCount) || (repeatCount == 0))
{
delay = _initialDelay; // added to “reset” timer
_paused = false;
_startTime = new Date().time;
super.start();
}
}
public function pause() : void
{
if(running)
{
_paused = true;
stop();
var newDelay:Number = delay – (new Date().time – _startTime);
super.delay = (newDelay < 0) ? 0 : newDelay;
}
}
// timer continues from where it left off
public function resume() : void
{
if((currentCount < repeatCount) || (repeatCount == 0))
{
_paused = false;
_startTime = new Date().time;
super.start();
}
}
override public function set delay(n:Number):void {
super.delay = _initialDelay = n;
}
public function get paused() : Boolean
{
return _paused;
}
public function get initialDelay() : Number
{
return _initialDelay;
}
}
}
Thanks for the compilation Kipp!
hi there
I’m using Kipp’s compilation to the letter. Everything seems to be working fine but i get an error nonetheless.
Can anyone help?
RangeError: Error #2066: The Timer delay specified is out of range.
at Error$/throwError()
at flash.utils::Timer/set delay()
at com.fjakobs.utils::ExtendedTimer/pause()
at be.figure8::SimpleSlideshow/pause()
at pages::ShowPage/pauseEvent()
It seems the error comes into play when the timer count gets reset.
Try running a timer with an interval of 50ms and pause it every other second while looking at yr trace window.
If anyone has an opinion about this error feel free to share, i have no idea why this is occurring.
Kudos for the class! Gets the job done and is very usefull with minimal fancyness
Hi, Thanx for the tut. I am working on this with a project of mine but it doesn’t work.
First I import the class:
import com.fjakobs.utils.*
Then I create the timer:
var newTimer:Number = 5000;
var slideTimer:ExtendedTimer = new ExtendedTimer(newTimer);
function onSlideFadeIn():void {
// check, if the slideshow is currently playing
// if so, start the timer again
if (bolPlaying && ! slideTimer.running) {
slideTimer.start();
}
}
I am using this class with this code showed on this website:
http://www.thetechlabs.com/tutorials/xml/extending-the-as3flash9-slideshow-with-xml/
I hope someone can help me with this,
thanx