Timeline queuing
Often, we need to animate more that one Shape at a time.
⏱ Timeline queuing to the rescue.
A Timeline allows for complex queuing of Shapes in sequence (one after the other) or in parallel (alongside each other).
By default, when we pass more than one Shape to a Timeline, they will queue in sequence.
import { shape, timeline, render, play } from 'wilderness' const shape1Keyframe1 = { type: 'circle', cx: 5, cy: 10, r: 5, fill: '#DBF8A1' } const shape1Keyframe2 = { type: 'rect', x: 40, y: 5, width: 10, height: 10, fill: '#1F9FFD' } const shape2Keyframe1 = { type: 'rect', x: 50, y: 5, width: 10, height: 10, fill: '#1F9FFD' } const shape2Keyframe2 = { type: 'circle', cx: 95, cy: 10, r: 5, fill: '#DBF8A1' } const shape1 = shape(shape1Keyframe1, shape1Keyframe2) const shape2 = shape(shape2Keyframe1, shape2Keyframe2) const animation = timeline(shape1, shape2, { duration: 2000, iterations: Infinity, alternate: true }) render(document.querySelector('svg'), animation) play(animation)
Fine grain queue control
As well as Shapes, the timeline
function can also accept arrays as arguments.
timeline( [ shape1, { name: 'SHAPE_1' } ], [ shape2, { name: 'SHAPE_2', queue: { after: 'SHAPE_1', offset: -200 } } ] )
When passing an array argument to the timeline
function, the first array item should be a Shape, and the second an options object.
This options object has two properties that can help with fine grain queue control – name
(a string or a number) and queue
(an object).
The name
property is a value we can use to reference a Shape from another Shape. In the case of Timeline queuing, we can reference the name
value from another Shape's queue.at
or queue.after
properties.
The mutually exclusive at
and after
properties queue a Shape in parallel or sequence respectively.
If neither the at
nor after
property is defined, the after
property will be set to reference the previous Shape in the Timeline. This is the reason why, by default, Wilderness queues a Timeline in sequence.
The final queue
property to understand is offset
. This is a number that defines the milliseconds to offset the Shape from its position on the Timeline. For example, a queue object of { at: 'SHAPE_X', offset: 200 }
means start playback 200 milliseconds after SHAPE_X
has started.
import { shape, timeline, render, play } from 'wilderness' const shape1Keyframe1 = { type: 'circle', cx: 5, cy: 5, r: 5, fill: '#DBF8A1' } const shape1Keyframe2 = { type: 'rect', x: 90, y: 0, width: 10, height: 10, fill: '#1F9FFD', duration: 1000 } const shape2Keyframe1 = { type: 'circle', cx: 5, cy: 15, r: 5, fill: '#1F9FFD' } const shape2Keyframe2 = { type: 'rect', x: 90, y: 10, width: 10, height: 10, fill: '#DBF8A1', duration: 1000 } const shape1 = shape(shape1Keyframe1, shape1Keyframe2) const shape2 = shape(shape2Keyframe1, shape2Keyframe2) const shape1WithOpts = [ shape1, { name: 'SHAPE_1' } ] const shape2WithOpts = [ shape2, { queue: { at: 'SHAPE_1', offset: 250 } } ] const animation = timeline(shape1WithOpts, shape2WithOpts, { iterations: Infinity, alternate: true }) render(document.querySelector('svg'), animation) play(animation)
Something to note is that when we are working with fine grain queue control we should be setting our duration
properties at the Keyframe level (on our Plain Shape Objects). The reason for this is that all queue calculations are made before playback options are applied to the timeline.
Take a look at the Timeline API reference for further detail.