"Do this. Then wait two seconds and do that. Once that is done, do the first part again. Do it five times within one second. On a certain condition, do only the first two parts and stop."
This should be an easy thing to ask Javascript, but actually isn't. The task requires multiple, successive or nested, setTimeout() and setInterval() calls.
It's heavy to code, indigestible to read, tiring to maintain, and painful to control properly.
This is where the clockWise Sequence object comes to rescue, allowing to build the most complex event sequences using an intuitive, logical syntax, then to control them smartly and precisely.
Basic use
var S = clockWise.setSequence();
S.at(1000).do(a_first_function);
S.at(2000).do(a_second_function).times(5);
S.at(2500).do(function(){ });
S.play();
Sequence-related methods
① Initialization
clockWise.setSequence()
Returns a blank sequence_object
, with a duration of 0 and no events. The object can then be configured and controlled using its own methods, described below.
② Writing
sequence_object.at( time )
Sets a point, expressed in milliseconds, on the
object's timeline for the next
given instruction to be written.
If the given
time
exceeds the
object's current
duration, the latter will be updated, meaning the sequence will now last
[ time
] milliseconds
(on the condition that an instruction is written to the new timeline point).
sequence_object.after( delay )
Sets a point,
[ delay
] milliseconds after the previously-set one, on the
object's timeline for the next
given instruction to be written.
The
object's duration will be updated under the same conditions as with the
.at() method.
sequence_object.do( callback )
Gives the
object instructions to execute when reaching the previously set point on its timeline.
This method does not affect the current writing position, meaning that its next call will set instructions at the same timeline point, unless a new positioning method such as
.at() or
.after() is used meanwhile.
sequence_object.do_again()
Makes the
object execute the last
given instruction again.
The new execution happens when the previously set point on the timeline is reached, meaning immediately if no new point has been set between the
.do() and
.do_again() calls.
Has no effect if no previous instruction was given.
sequence_object.until( time )
Makes the
object execute the last
given instruction in loop, starting at the previously set point on its timeline, until
[ time
] is reached.
Has no effect if no previous instruction was given.
Additionally, if the given
time
exceeds the
object's current
duration, the latter will be updated, meaning the sequence will now last
[ time
] milliseconds.
The loop's rate is defined by the global parameter
clockWise.sequence_default_repeat_interval
, set to
50 by default. Meaning the instruction will be executed again every 50 milliseconds.
sequence_object.during( time )
Makes the
object execute the last
given instruction in loop, starting at the previously set point on its timeline, during
[ time
] milliseconds.
Has no effect if no previous instruction was given.
Additionally, the
object's duration will be updated under the same conditions as with the
.until() method.
The loop's rate is defined by the global parameter
clockWise.sequence_default_repeat_interval
, set to
50 by default. Meaning the instruction will be executed again every 50 milliseconds.
sequence_object.times( iterations )
Makes the
object execute the last
given instruction [ iterations
] times.
Has no effect if no previous instruction was given.
The executions will occur immediately at the previously set point on the
object's timeline, unless this method is combined with
.until(),
.during() or
.at_interval().
In this case a loop will be set, with executions triggered at the
interval given via the
.at_interval() call, or calculated for the whole loop to take the desired duration.
sequence_object.at_interval( time_interval )
Has to be combined with an
instruction followed by
.until(),
.during() or
.times().
Sets the
time_interval
, in milliseconds, to elapse between looped executions of the previously given instruction.
The loop's duration or iteration count (depending which one is not manually set) will be automatically calculated.
sequence_object.while()
When used after a loop-inducing method such as
.until() or
.during(), this method allows to reset the current writing point on the
object's timeline to the loop's start.
This way, the next
given instruction will be triggered simultaneously with the loop instead of waiting for its end.
sequence_object.end()
When used after a positioning method such as
.at() or
.after(),
this method sets an empty instruction to be triggered at the corresponding timeline point.
As a result, if the point is positioned at a time greater than any other ones on the
object's timeline, the sequence's global duration will be stretched without having to execute an additional instruction.
Can be useful for example if the
object is later required to
play in loop, with a "blank" period between its last event and its next iteration.
Has no effect if not positioned after the timeline's previously furthest point.
sequence_object.chapter( chapter_name )
Labels the previously set point on the
object's timeline. Can be useful if the
object is later required to
play from or to this point.
chapter_name
has to be a
string.
③ Controls
sequence_object.play( [ settings ] )
Triggers the
object if not already active. An
object previously played and
paused will resume from its last reached time.
The
settings
argument is optional. If given, it has to be a
{ property:value }
list.
Accepted properties for settings :
→
reset
: boolean
Set to the global parameter
clockWise.sequence_loop_by_default
(defined as
false) if not specified. If set to
true, the sequence will start from its beginning (altered beginning if
from
is set), regardless of any point reached in a previous
paused action.
→
from
: integer or string
Sets a custom point on the
object's timeline to start from, instead of
0. Can be a time value in milliseconds or a
chapter name.
→
to
: integer or string
Sets a custom point on the
object's timeline to stop the sequence when reached, instead of elapsing the total duration. Can be a time value in milliseconds or a
chapter name.
→
loop
: boolean
Set to
false if not specified. If set to
true, the sequence will re
play when it reaches its end.
→
times
: integer
If set, defines how many times the sequence has to be looped. Ignored if
loop
is already set.
These settings will be kept until the sequence is
cleared or reaches its end (natural or altered via a
to
setting - the end of its last iteration if
times
is set).
Meaning, as well, that
clearing the sequence or waiting for its end is necessary before it can be
played again with new or no custom settings.
sequence_object.pause( [ settings ] )
Stops the
object's sequence.
When
played again, the sequence will resume from its last reached timeline point (unless the
reset
option is set to
true then).
The
settings
argument is optional. If given, it has to be a
{ property:value }
list.
Accepted properties for settings :
→
at
: integer
If set, the pause will occur only once the passed
time value (in milliseconds) is reached on the timeline.
→
after
: integer
If set, the pause will occur only once the passed
time value (in milliseconds) is elapsed.
→
if_too_late
: string
Handles the case of an already overstepped
at
value / an out-of-timeline
after
value.
If set to
"immediate", the pause will occur immediately in this case. If set to
"postpone", it will occur on the right time at next iteration, or be ignored if there is no next iteration (no current
loop
or
times
setting).
If not set, the default behaviour is to ignore the pause.
If a given
at
value is permanently out of reach because of an altered starting or ending time (
from
or
to
values given when
playing the object),
all of the above settings will be ignored and the pause will be immediate.
sequence_object.clear( [ settings ] )
Stops the
object's sequence and resets its timeline position to
0. If the sequence was currently playing with custom settings, these are cancelled too.
The
settings
argument is optional. If given, it has to be a
{ property:value }
list.
Accepted properties for settings :
→
at
: integer
If set, the reset will occur only once the passed
time value (in milliseconds) is reached on the timeline.
→
after
: integer
If set, the reset will occur only once the passed
time value (in milliseconds) is elapsed.
→
if_too_late
: string
Handles the case of an already overstepped
at
value / an out-of-timeline
after
value.
If set to
"immediate", the reset will occur immediately in this case. If set to
"postpone", it will occur on the right time at next iteration, or be ignored if there is no next iteration (no current
loop
or
times
setting).
If not set, the default behaviour is to ignore the reset.
If a given
at
value is permanently out of reach because of an altered starting or ending time (
from
or
to
values given when
playing the object),
all of the above settings will be ignored and the reset will be immediate.
Retrieving time data
sequence_object.getElapsed()
Returns the
object's elapsed time (in milliseconds) in its current or last (if
paused) sequence.
An
object's elapsed time is reset to
0 when
cleared or at the end of its sequence.
sequence_object.getDuration()
Returns the object's total duration (in milliseconds).