Delayable
Updated on August 22, 2024Source code
Delayable
is a class that enriches a function, allowing it to:
- Be called after a certain number of milliseconds, on an infinite loop OR until a user-specified number of executions has been reached
- Store the number of times the function has been executed
- Store time data:
- Timestamps for each execution
- Total time elapsed since starting the delay
- Time elapsed since the last execution
- Total time remaining until all executions are complete
- Time remaining until the next execution
- Store a status (
ready
,delaying
, ordelayed
)
In other words, Delayable
implements all the main features of setTimeout
and setInterval
, then exposes data that describes the active timeout or interval.
Caveat when using Delayable
in inactive tabs
Notably, Delayable
doesn't actually use setTimeout
or setInterval
under the hood. Instead, it depends on Animateable
, which uses requestAnimationFrame
(among other dependencies) internally.
Because of this, your Delayable
delays will pause when the tab is inactive (i.e. when users switch to a different tab), and will resume when the tab is active again (i.e. when users return to your tab).
This is different than the behavior you would get from setTimeout
and setInterval
—browsers typically (and inconsistently) throttle those timers when the tab is inactive, rather than pausing and resuming them via requestAnimationFrame
.
So, just be aware: even though Delayable
's API is designed to replace the setTimeout
and setInterval
APIs, it does work differently under the hood.
Construct a Delayable
instance
The Delayable
constructor accepts two parameters:
effect
Passes the callback function that will be made delayable.
Your effect
will receive a timestamp
argument (DOMHighResTimeStamp) indicating the time since time origin.
options
Delayable
instance. See the Delayable
constructor options section for more guidance.Delayable
constructor options
delay
0
effect
executions
1
Indicates the number of times the callback function will be delayed and executed.
Set executions
to 1
to make it behave like setTimeout
, set it to any number greater than 1
to make it delay and execute a specific number of times, and set it to true
to make it behave like setInterval
(i.e. delay and execute on an infinite loop).
State and methods
effect
A slightly altered version of the effect
you passed to the Delayable constructor. The altered effect
will execute repeatedly at a rate of 60fps, and it won't call your original function until your number of milliseconds (specified in the delay
option) have passed.
If you assign a value directly to effect
, a setter will pass the new value to setEffect
.
status
Delayable
instance. See the How methods affect status, and vice-versa section for more information.executions
effect
has been executed.time
elapsed
and remaining
. Both keys' values are millsecond values (Number), and they indicate the time elapsed since the last execution of the effect
and the time remaining until the next execution.progress
0
and 1
indicating the time progress toward the next execution of the effect
.setEffect(effect)
effect
timestamp
parameter (see the Construct a Delayable instance section for a refresher on that parameter).Delayable
instancedelay()
Delays the execution(s) of the effect
.
If you call delay
while the effect
is currently being delayed, it will start over from the beginning (and reset executions
, time.elapsed
, and progress
to 0
).
Can't be called until the DOM is available.
Delayable
instancepause()
Delayable
instanceseek(progress)
Seeks to a specific time progress in the delay. If status
is playing
or reversing
, the animation will continue progressing in the same direction after seeking to the time progress.
If your effect
is supposed to execute more than one time, you can pass a time progress that is greater than 1
to seek to a specific execution. For example, to seek halfway through the third delay, you can call seek(2.5)
. Your effect
will instantly be executed twice, and will be halfway toward the third execution.
Can't be called until the DOM is available.
seek
Accepts one parameter: a time progress to seek toDelayable
instance.resume()
status
is anything other than paused
or sought
. Can't be called until the DOM is available.Delayable
instancestop()
Delayable
instance.How methods affect status, and vice-versa
Each Delayable
instance maintains a status
property that allows it to take appropriate action based on the methods you call, in what order you call them, and when you call them.
At any given time, status
will always be one (and only one) of the following values:
ready
delaying
delayed
paused
sought
stopped
There's a lot of complexity involved in the way each status
is achieved (it's affected by which methods you call,in what order you call them, and exactly when you call them), but you likely will never need to worry about that. status
is available to you if you feel you need it, but for all intended use cases, it's an implementation detail, and you can ignore it.
The only thing you may want to be aware of is how status
affects your ability to call certain methods—some methods can be called at any time, and some can only be called when status
has a specific value.
The table below has a full breakdown:
status
is...setEffect
delay
pause
delaying
seek
resume
paused
or sought
stop
Or, just remember:
- If you
delay
while the animation is already delaying, the delay will start over from the beginning (and resetexecutions
,time.elapsed
, andprogress
to0
). - You can only
pause
while the delay process is in progress - You can
setEffect
,seek
, andstop
at any time. Just remember thatsetEffect
will alwaysstop
the delay, and if you callseek
while a delay is progressing, the animation will continue delaying after it seeks to the time progress you specified. - You can only
resume
after callingpause
orseek
Using with TypeScript
Nothing special to know about using Delayable
with TypeScript 🚀
API design compliance
options
object.effect
setEffect
set<Property>
methodsstatus
, executions
, time
, progress
delay
, pause
, seek
, resume
, stop
stop
methodable