4. Learning about GSAP timelines¶
A timeline (see the GSAP timeline docs) is a sequencing tool that allows one to coordinate different animations (e.g. different calls to gsap.to() and gsap.set()), and allowing absolute and relative control over when each animation starts and finishes.
Animations can be added to a timeline without the programmer needing to modify the timings of any of the existing animations in the timeline.
Modularity is supported by allowing a timeline to be added as an animation within another timeline.
4.1. Initialising a timeline (the function gsap.timeline())¶
Timelines are initialised with a call to gsap.timeline().
This function takes a configuration dict vars that has the same form as the vars passed to gsap.to().
This dict should contain all the key-value pairs you want the timeline to have (see the GSAP Timeline vars docs for more details).
Keys that might be useful for an animation that is repeating while the player plays a game round (e.g. blinking eyes on a character) include repeat, repeatDelay, and repeatRefresh.
In addition, a key defaults is accepted that itself has a value that is a dict.
Any items in defaults will apply to each animation (e.g. each to() and set()) in the timeline.
For more information see the GSAP Timeline defaults docs.
The function gsap.timeline() returns an initialised Timeline object to which to() and set() animations can then be added, as explained in subsequent subsections.
In file dungeonescape/webapp/__init__.py, the function update_problem_instance() initialises a timeline, and includes a default duration for each animation in the timeline, with
default_duration = 1
"""A default duration (in seconds) for each step of the animation."""
# Create a GSAP timeline to hold all of the steps of the animation
tl = gsap.timeline(
{
'defaults': {'duration': default_duration},
}
)
In this example, name tl is used to refer to the initialised Timeline object.
For all of the examples that follow, you can assume that tl is an initialised Timeline object.
4.2. The function Timeline.to()¶
The function Timeline.to() adds a gsap.to() animation at the end of the current timeline, or elsewhere if the position parameter is set.
Timeline.to() takes the same two parameters as gsap.to() (namely, a DOMNode object or list of DOMNode objects, and a dict of attribute-value pairs) plus an additional third argument
positionA number or
str, default'+=0': A value that specifies the insertion point of the animation in the timeline as explained in the GSAP Timeline position parameter article. If it is a number (or a name referring to anintor afloat) it means that many seconds from the start of the timeline. If it is a string, it is a word in the position parameter mini-language (the full mini-language is not explained here; see the GSAP Timeline position parameter article for extra features such as labels).Examples of this mini-language to specify a position to insert a new animation into the timeline (in all cases,
durationcan be anintor afloat, e.g. 0.25) include
f'{duration}'durationseconds from the start of the timeline (in such a casedurationcould also have been passed as a number without conversion to a string)
'+=0'(the default) at the current end of the timeline
f'+={duration}'durationseconds past the current end of the timeline (creates a gap)
f'-={duration}'durationseconds before the current end of the timeline (overlaps)
'<'at the start of the most recently inserted animation, i.e. starting in parallel with the most recently inserted animation
f'<{duration}'durationseconds after the start of the most recently inserted animation
f'<-{duration}'durationseconds before the start of the most recently inserted animation
'<25%'25% after the start of the most recently inserted animation
'>'at the end of the most recently inserted animation (note, not equivalent to the end of timeline word'+=0'because the most recently inserted animation may end before the end of the timeline)
f'>{duration}'durationseconds after the end of the most recently inserted animation
f'>-{duration}'durationseconds before the end of the most recently inserted animation
'>25%'25% after the end of the most recently inserted animation
'>-25%'25% before the end of the most recently inserted animation
For more details about this function see the GSAP Timeline.to() docs.
In file dungeonescape/webapp/__init__.py, the function update_problem_instance() adds to the end of the timeline an animation to move an object to the right with
# Move the robber; increment its 'x' position by `IM_SIDE`
tl.to(
robber,
{'x': f'+={IM_SIDE}', 'duration': duration, 'ease': 'sine.inOut'},
)
In this example, and in the others from dungeonescape/webapp/__init__.py, the duration key had been in the timeline defaults, but is included in these code examples for transparency.
In file dungeonescape/webapp/__init__.py, the function update_problem_instance() adds to the end of the timeline an effect where one object fades in at the same time as another object fades out.
It does this by scheduling two animations to occur simultaneously, by passing '<' as the optional position parameter to the second animation, with
# Hide the key on the ground to illustrate it being picked up by the robber
tl.to(
f'#dungeon_{dungeon_index}',
{'duration': duration, 'autoAlpha': 0},
)
# At the same time show the key in the bag
tl.to(
f'#key_{key_index}',
{'duration': duration, 'autoAlpha': 1},
'<',
)
In file dungeonescape/webapp/__init__.py, the function update_problem_instance() adds to the end of the timeline three animations in the following way.
The first runs for duration seconds and the other two animations run in sequence with each other, but in parallel with the first (i.e. the first runs in parallel with the second, but halfway through the first the second finishes and the third starts).
This is achieved with
# Remove the top key from the bag
tl.to(
f'#key_{key_index}',
{'duration': duration, 'autoAlpha': 0},
)
# At the same time, hide the door lock for half the duration
tl.to(
f'#dungeon_{dungeon_index}',
{'autoAlpha': 0, 'duration': duration / 2},
'<',
)
# After the door lock has been hidden, but half-way through
# the key being removed, swing the door open.
tl.to(
f'#dungeon_{dungeon_index}_door',
{'scaleX': 0.2, 'duration': duration / 2},
'>',
)
This is a good example for the usefulness of the '>' word to add an animation at the end of the previously inserted animation, as distinct from adding the animation at the end of the timeline.
4.3. The function Timeline.set()¶
The function Timeline.set() instantly changes the specified attributes of DOMNode objects at the end of the current timeline, or elsewhere if the position parameter is set.
Timeline.set() takes the same three parameters as Timeline.to().
More details can be found in the GSAP Timeline.set() docs.)
In file dungeonescape/webapp/__init__.py, the function update_problem_instance() adds to the end of the timeline a command to instantly hide a particular SVG image element with
# Hide the door after it has been opened
tl.set(
f'#dungeon_{dungeon_index}_door',
{'autoAlpha': 0},
)