Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C liability, trademark and document use rules apply.
This specification defines a model for synchronization and timing of changes to the presentation of a Web page. This specification also defines an application programming interface for interacting with this model and it is expected that further specifications will define declarative means for exposing these features.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document was published by the CSS Working Group (part of the Style Activity) and SVG Working Group (part of the Graphics Activity) as a First Public Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-fx@w3.org (subscribe, archives). All feedback is welcome.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by groups operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures (CSS) and a public list of any patent disclosures (SVG) made in connection with the deliverables of each group; these pages also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
AnimationTimeline
interfaceAnimationPlayer
interfaceAnimationNode
interfaceAnimationTiming
interfaceAnimationTimingInput
dictionaryAnimationGroup
interfaceAnimationNodeList
interfaceAnimationSequence
interfaceAnimation
interfaceAnimatable
interfaceAnimationEffect
interfaceIterationCompositeOperation
enumerationCompositeOperation
enumerationKeyframeEffect
interfaceKeyframe
dictionaryComputedKeyframe
dictionaryMotionPathEffect
interfaceEffectCallback
callback functionAnimationPlayerEvent
interfaceDocument
interfaceElement
interfacePseudoElement
interfaceThis section is non-normative.
Web Animations defines a model for supporting animation and synchronization on the Web platform. It is intended that other specifications will build on this model and expose its features through declarative means. In addition, this specification also defines a programming interface to the model that may be implemented by user agents that provide support for scripting.
The Web Animations model aims at two broad areas of application:
Animation can be used to give visual clues and feedback to make a user interface more readily comprehensible.
For example, a user action results in a table row being removed to represent an item being removed from a shopping cart. In such a case, fading the row to transparent and then shifting the subsequent rows up to fill the space over a few hundred milliseconds provides the user with clear feedback as to the results of their action as opposed to instantly removing the row from the DOM.
To support this scenario not only are the animated effects of fading and shifting required, but so is synchronization, both between the animations, and between animations and scripted actions (removing the table row from the DOM after the animations have completed).
Another type of animation uses the animated effect to convey a story or represent some information. Unlike user interface effects which are largely a presentational adjunct to the content, these animations form an essential part of the content presented to the user.
For example, in an animated cartoon two cats fly through space to another planet leaving a rainbow trail behind them. After arriving at the planet a change of scene occurs and the user should decide whether or not the cats enter a magic mountain by selecting one of two preset destinations in the scene.
This scenario requires the following features:
Similar use cases in this category include visualising physical phenomena such as spring motion for educational purposes, or visualising data such as the prevalence of a disease over a geographical space over a year whereby animation is used to present the time-based component of the data.
CSS Transitions [CSS3-TRANSITIONS], CSS Animations [CSS3-ANIMATIONS], and SVG [SVG11] all provide mechanisms that generate animated content on a Web page. Although the three specifications provide many similar features, they are described in different terms. This specification proposes an abstract animation model that encompasses the common features of all three specifications. This model is backwards-compatible with the current behavior of these specifications such that they can be defined in terms of this model without any observable change.
The animation features in SVG 1.1 are defined in terms of SMIL Animation [SMIL-ANIMATION]. It is intended that by defining SVG's animation features in terms of the Web Animations model, the dependency between SVG and SMIL Animation can be removed.
As with Timing control for script-based animations (commonly referred to as “requestAnimationFrame”) [RAF], the programming interface component of this specification allows animations to be created from script. The animations created using the interface defined in this specification, however, once created, are executed entirely by the user agent meaning they share the same performance characteristics as animations defined by markup. Using this interface it is possible to create animations from script in a simpler and more performant manner.
The time values used within the programming interface correspond with those used in Timing control for script-based animations [RAF] and their execution order to defined such that the two interfaces can be used simultaneously without conflict.
The programming interface component of this specification makes some additions to interfaces defined in HTML5 [HTML5].
This specification begins by defining an abstract model for animation. This is followed by a programming interface defined in terms of the abstract model. The programming interface is defined in terms of the abstract model and is only relevant to user agents that provide scripting support.
This section is non-normative.
At a glance, the Web Animations model consists of two largely independent pieces, a timing model and an animation model. The role of these pieces is as follows:
Graphically, this flow can be represented as follows:
For example, consider an animation that:
The first three points apply to the timing model. At a time of 6 seconds, it will calculate that the animation should be half-way through its second iteration and produces the result 0.5. The animation model then uses that information to calculate a width for the rectangle of 75.
This specification begins with the timing model and then proceeds to the animation model.
This section describes and defines the behavior of the Web Animations timing model.
This section is non-normative.
Two features characterise the Web Animations timing model: it is stateless and it is hierarchical.
The Web Animations timing model operates by taking an input time and producing an output time fraction. Since the output is based solely on the input time and is independent of previous inputs, the model may be described as stateless. This gives the model the following properties:
There are a few exceptions to the stateless behavior of the timing model.
Firstly, a number of methods defined in the programming interface to the model provide play control such as pausing an animation. These methods are defined in terms of the time at which they are called and are therefore stative. These methods are provided primarily for convenience and are not part of the core timing model but are layered on top.
Likewise, player events are fired when the first sample occurs at the limit of the source content. This too is stative behavior but is part of the play control layered on top of the timing model.
Similarly, the limiting behavior of players means that dynamic changes to the end time of the media (source content) of a player may produce a different result depending on when the change occurs. This behavior is somewhat unfortunate but has been deemed intuitive and consistent with HTML. As a result, the model can only truly be described as stateless in the absence of dynamic changes to its timing properties.
Finally, each time the model is sampled, it can be considered to establish a temporary state. While this temporary state affects the values returned from the programming interface, it has no influence on the subsequent samples and hence does not conflict with the stateless qualities described above.
The other characteristic feature of the Web Animations timing model is that time is inherited. Time begins with a monotonically increasing time source and cascades down a number of steps to each animation. At each step, time may be shifted backwards and forwards, scaled, reversed, paused, and repeated.
A consequence of this hierarchical arrangement is that complex animation arrangements can be reversed, scheduled, accelerated and so on as a whole unit since the manipulations applied to the parent cascade down to its descendants. Furthermore, since time has a common source, it is easy to synchronize animations.
In Web Animations, timing is based on a hierarchy of time relationships between timing nodes. Parent nodes provide timing information to their child nodes in the form of time values. A time value is a real number which nominally represents a number of milliseconds from some moment. The connection between time values and wall-clock milliseconds may be obscured by any number of transformations applied to the value as it passes through the time hierarchy.
In the future we may have timelines that are based on UI gestures in which case the connection between time values and milliseconds will be weakened even further.
Periodically, the user agent will trigger an update to the timing model in a process called sampling. On each sample the time values of each timing node are updated.
A more precise definition of when the model is updated when scripting is involved is provided in section 5.23 Script execution and live updates to the model.
At the root of the Web Animations timing hierarchy is the global clock.
The global clock is a source of monotonically increasing time values unaffected by adjustments to the system clock. The time values produced by the global clock represent wall-clock milliseconds from an unspecified historical moment. Because the zero time of the global clock is not specified, the absolute values of the time values produced by the global clock are not significant, only their rate of change.
Note that the global clock is not exposed in the programming interface and nor is it expected to be exposed by markup. As a result the moment from which global clock time values are measured, that is, the zero time of the clock, is implementation-dependent. One user agent may measure the number of milliseconds since the the user agent was loaded whilst another may use the time when the device was started. Both approaches are acceptable and produce no observable difference in the output of the model.
A timeline provides a source of time values for the purpose of synchronization.
Typically, a timeline is tied to the global clock such that its absolute time is calculated as a fixed offset from the time of the global clock. This offset is established by designating some moment as the timeline's zero time and recording the time value of the global clock at that moment. At subsequent moments, the time value of the timeline is calculated as the difference between the current time value of the global clock and the value recorded at the zero time.
Note that we anticipate that other types of timelines may be introduced in the future that are not tied to the global clock. For example, a timeline whose time values are related to the progress of a UI gesture.
Since a timeline may be defined relative to a moment that has yet to occur, it may not always be able to return a meaningful time value. A timeline is considered to be not started when it is in such a state that it cannot produce a time value.
Should this be renamed to something like “inactive” so we can accommodate possible future timelines that may, after starting, become unable to return a meaningful time value?
Each document has a timeline called the document
timeline.
The time values of the document timeline are calculated
as a fixed offset from the global clock such that the zero
time corresponds to
the navigationStart
moment [NAVIGATION-TIMING].
Prior to this moment, the document timeline is not
started.
This section is non-normative.
Since the document timeline is tied to the global clock by a fixed offset, time values reported by the document timeline increase monotonically. Furthermore, since no scaling is applied, these time values are proportional to wall-clock milliseconds.
Since the time values of the document timeline are
relative to the navigationStart
time,
document.timeline.currentTime
will roughly correspond
to
Performance.now()
[HR-TIME] with the exception that
document.timeline.currentTime
does not change within
a script execution block as defined in section 5.23 Script execution and live updates to the model.
This section is non-normative.
The children of a timeline are called players. A player takes an animation node which is a static description of some timed behavior and binds it to a timeline so that it runs. A player also allows run-time control of the connection between the animation node and its timeline by providing pausing, seeking, and speed control. The relationship between a player and an animation node is analogous to that of a DVD player and a DVD.
A player connects a single animation node, called its source content, to a timeline and provides playback control.
A player's start time is the time value of its timeline when its source content is scheduled to begin playback.
When a player is created, it is assigned a globally unique sequence number called the player sequence number. This number is used to resolve the sort order of players for a variety of situations such as combining animations, queuing events, and returning the list of current players.
Players provide a time value to their source content called the player's current time.
The calculation of the current time is as follows:
current time = (timeline time - start time) × playback rate
unless the hold time is not null, in which case the current time is equal to the hold time.
Where:
The procedure for performing manual updates to the current time is defined in section 3.5.2.9 Performing a seek.
If the timeline with which the player is associated is not started, then the current time is null.
It is often useful to manipulate the current time of a player even when its associated timeline is not started. For example, this is useful for pre-seeking a player. For this purpose, we have the following additional definitions:
Seeking, pausing and limiting a player are closely related and are described here together.
This section is non-normative.
Changing the current playback position of a player, that is, its current time, can be used to rewind its source content to its start point, fast-forward to a point in the future, or to provide ad-hoc synchronization between players.
Changing the current time of a player has the side effect of shifting its start time as illustrated below.
It is possible to seek a player even if its timeline is not started. Once the timeline begins, the player will begin playback from the seeked time.
This section is non-normative.
Pausing can be used to temporarily suspend a player. Like seeking, pausing controls the current time of a player by updating its start time. The result is illustrated below.
This section is non-normative.
Players in the real world such as DVD players or cassette players typically continue playing until they reach the end of their media at which point they stop. If such players are able to play in reverse, they typically stop playing when they reach the beginning of their media. In order to emulate this behavior and to provide consistency with HTML's media elements [HTML5], the current time of Web Animations' players do not play forwards beyond the end time of their source content or play backwards past time zero. This behavior is called limiting.
Graphically, the effect of limiting is shown below.
It is possible, however, to seek the current time of a player to a time past the end of the source content. When doing so, the current time will not progress but the player will act as if it had been paused at the seeked time.
This allows, for example, seeking the current time of a player with no source content to 5s. If source content with an end time later than 5s is later associated with the player, playback will begin from the 5s mark.
Similar behavior to the above scenarios may arise when the length of a player's source content changes.
When the player playback rate is negative, the current time does not progress past time zero although it may be seeked to a negative time.
Limiting the current time acts like a sort of automatic pausing and is accomplished using the same machinery as pausing.
Players track two properties related to seeking, pausing and limiting.
In addition to these properties, implementations are required to keep track of the last calculated value of the current time in order to produce correct limiting behavior (see section 3.5.2.7 Automatically updating the hold time).
The player start time value is both a stored and a calculated value. When a player is paused, the value is calculated from the hold time. When a player is not paused, the stored value is used.
The value of the player start time at a given moment is based on the paused state as follows:
effective timeline time
- hold time / player playback rate
.The start time of a player is updated to a new time, new start time, as follows:
timeline time - new start time
× player playback rate
.The hold time is updated prior to each time the current time is calculated when all of the following conditions are true:
When all the above conditions are satisfied, the following steps are performed:
timeline
time - hold time
/ player playback rate
.
The procedure for updating the paused state is as follows:
Seeking is the process of updating a player's current time to a desired value. It is achieved using the following procedure:
effective timeline
time - seek time / player
playback rate
.
Since seeking effectively updates the player's current time it also causes the “previously calculated value of current time” as used by the procedure for updating the hold time to be updated (see section 3.5.2.7 Automatically updating the hold time).
A player is said to be limited when either of the following conditions are true:
This section is non-normative.
The rate of play of a player can be controlled by setting its playback rate. For example, setting a playback rate of 2 will cause the player's current time to increase at twice the rate of its timeline. Similarly, a playback rate of -1 will cause the player's current time to decrease at the same rate as the time values from its timeline increase.
Note that animation nodes also have a playback rate associated with them that behaves differently to that defined here.
Players have a playback rate that provides a scaling factor from the rate of change of the associated timeline's time values to the player's current time. The playback rate is initially 1.
Setting a player's playback rate to zero effectively pauses the player but without affecting the player's paused state.
Changes to the playback rate trigger a compensatory seek so that that the player's current time is unaffected by the change to the playback rate.
The procedure is as follows:
As players play they report changes to their status through player events.
Player events are a property of the Web Animations timing model. As a result they are dispatched even when the source content of the player is absent or has no observable result.
Queued whenever a sample occurs that causes a player's finished flag to be newly true.
To assist dispatching finish events, players maintain a finished flag that is initially false when the player is created.
During each sample, the finished flag is updated such that it is set to true if the player is limited and false otherwise.
Player events have an associated event current time and event timeline time.
The event current time is the current time of the player that generated the event at the moment the event is queued. This will be null if the player was not associated with a timeline at the time the event was generated.
The event timeline time is the time value of the timeline with which the player that generated the event is associated at the moment the event is queued. This will be null if the player was not associated with a timeline at the time the event was generated.
The propagation path for a player event generated by player, is simply player itself.
The sequence in which player events are queued is in ascending order by event timeline time. If two player events have the same event document time, the player events are queued in ascending order by player sequence number of the players that generated the events.
Events are queued whenever sampling regularly occurs (that is, not when the timing model is evaluated due to seeking or structural changes to the hierarchy of animation nodes).
As a result, seeking a player to the limit of its source content and back to a point within its source content within the same script execution block will not trigger a finish event.
An animation node is an abstract term referring to an item in the timing hierarchy.
The source content of a player, if set, is a type of animation node. The source content of a player is said to be directly associated with that player.
Animation nodes can be combined together into a hierarchy using animation groups (see section 3.13 Grouping and synchronization). Only the root animation node of such a hierarchy can be directly associated with a player. If an animation node that has a parent animation group is designated as the source content of a player, the animation node is removed from its parent animation group before being associated with the player.
An animation node is associated with a player if it is directly associated with a player or if it has an ancestor animation group that is directly associated with a player. At a given moment, an animation node can be associated with at most one player.
An animation node, node, is associated with a timeline, timeline, if node is associated with a player which, in turn, is associated with timeline.
This specification defines two types of animation nodes:
All types of animation nodes define a number of common properties which are described in the following sections.
This section is non-normative.
The period that an animation node is scheduled to run is called its active interval. Each animation node has only one such interval.
The lower bound of the active interval is determined by the start time of the animation node but may be shifted by a start delay on the animation node.
The upper bound of the interval is determined by the active duration.
The relationship between the start time, start delay, and active duration is illustrated below.
An end delay may also be specified but is primarily only of use when sequencing animations such as by using a sequence animation group.
Animation nodes define an active interval which is the period of time during which the node is scheduled to produce its effect with the exception of fill modes which apply outside the active interval.
The lower bound of the active interval is defined by the combination of the animation node's start time and start delay.
An animation node's start time is the moment at which the parent animation group, if any, has scheduled the animation node to begin. It is expressed in inherited time. In most cases, including the case when the animation node has no parent animation group, the start time is zero. The singular exception is sequence animation groups which set the start times of their children as described in section 3.13.4.1 The start time of children of an animation sequence.
In addition to the start time, an animation node also has a start delay which is an offset from the start time. Unlike the start time which is determined by the parent animation group, the start delay is a property of the animation node itself.
The lower bound of the active interval of an animation node, expressed in inherited time space, is the sum of the start time and the start delay.
These definitions are incorporated in the calculation of the local time (see section 3.6.4 Local time and inherited time) and active time.
The length of the active interval is called the active duration, the calculation of which is defined in section 3.10.2 Calculating the active duration.
Similar to the start delay, an animation node also has an end delay which may be used to delay the start time of the next sibling in a sequence animation group.
This section is non-normative.
In Web Animations all times are relative to some point of reference. These different points of reference produce different time spaces.
This can be compared to coordinate spaces as used in computer graphics. The zero time of a time space is analogous to the origin of a coordinate space.
Just as with coordinate spaces, time spaces can also be nested. Animation groups typically perform some transformations on the time values they receive from their parent or player before passing on the transformed time values to their children. Child animation nodes then operate within that transformed time space.
Children take the transformed time values from their parent—called the inherited time— and add their start time to establish their own local time space as illustrated below.
For an animation node, the inherited time at a given moment is based on the first matching condition from the following:
null
.
The local time of an animation node is the
animation node's inherited time minus its start time.
If the inherited time is null
then the local time
is also null
.
This section is non-normative.
At a given moment, an animation node may be in one of three
possible phases.
If an animation node has a null
local
time it will not be in any phase.
The different phases are illustrated below.
The phases are as follows:
In addition to these phases, an animation node may also be described as being in one of several overlapping states. These states are only established for the duration of a single sample and are primarily a convenience for describing stative parts of the model.
These states and their useage within the model are summarised as follows:
Corresponds to an animation node whose active time is changing on each sample. This occurs when the animation node and all its ancestors are in the active phase. Animations only “move” when they are in play.
It is possible for an animation node to be in the active phase but not in play. For example, if an animation node has a parent animation group that causes the animation node's active interval to be clipped and both parent and child apply the same fill mode, the child animation node may be effectively be snapshotted within the active phase despite no longer being in play.
Corresponds to an animation node that is either in play or may become in play in the future. This will be the case if the animation node is in play or in its before phase, or it has an ancestor for which this is true thereby opening up the possibility that this animation node might play again (e.g. due to repeating).
This state is used in the programming interface to identify all animations and players that are likely to be of interest.
Furthermore, the current state provides an important definition for managing the amount of memory required by implementations. Assuming a monotonically increasing timeline an implementation can safely discard all animation nodes that are not current and not referenced elsewhere provided they take care to preserve any fill values. This is because such animation nodes will no longer have any dynamic effect.
The normative definition of each of these states follows.
An animation node is in the before phase if the
animation node's local time is not null
and is
less than the node's start delay.
An animation node is in the active phase if all of the following conditions are met:
null
, and
An animation node is in the after phase if the
animation node's local time is not null
and is
greater than or equal to the sum of its start delay
and active duration.
An animation node is in play if all of the following conditions are met:
An animation node is current if it any of the following conditions is true:
An animation node is in effect if its active time as
calculated according to the procedure in section 3.10.3.1 Calculating the active time is not
null
.
The effect of an animation node when it is not in play is determined by its fill mode.
The possible fill modes are:
The normative definition of these modes is incorporated in the calculation of the active time in section 3.10.3.1 Calculating the active time.
This section is non-normative.
The effect of each fill mode is as follows:
Some examples of the these fill modes are illustrated below.
Note that setting a fill mode has no bearing on the endpoints of the
active interval.
However, the fill mode does have an effect on various other
properties of the timing model since the active time of an
animation node is only defined (that is, not null
) inside
the active interval or when a fill is applied.
Currently timing functions that generate results outside the range [0, 1] will behave unexpectedly when applied to animation groups, as children will increase iterations or enter into fill mode rather than continuing to extrapolate along their defined behavior (which is what they would do if the timing function applied to them directly).
To fix this it is possible we will wish to introduce 'overflow' fill modes that respond to time values larger than or smaller than the active time range by extrapolating rather than filling.
See section 15 (Overflowing fill) of minuted discussion from Tokyo 2013 F2F.
It is possible to specify that an animation node should repeat a fixed number of times or indefinitely. This repetition occurs within the active interval. The span of time during which a single repetition takes place is called an iteration interval.
Unlike the active interval, an animation node can have multiple iteration intervals although typically only the interval corresponding to the current iteration is of interest.
The length of a single iteration is called the iteration duration. The initial iteration duration of an animation node is simply its intrinsic iteration duration.
The intrinsic iteration duration of an animation node is zero, however some specific types of animation node such as animation groups override this behavior and provide an alternative intrinsic duration (see section 3.13.3 The intrinsic iteration duration of an animation group and section 3.13.4.2 The intrinsic iteration duration of an animation sequence).
The iteration duration of an animation node may be set by the author to represent a value other than the intrinsic iteration duration.
This section is non-normative.
Comparing the iteration duration and the active duration we have:
The relationship between the iteration duration and active duration is illustrated below.
The number of times an animation node repeats is called its iteration count. The iteration count is a real number greater than or equal to zero. The iteration count may also be positive infinity to represent that the animation node repeats indefinitely.
In addition to the iteration count, animation nodes also have an iteration start property which specifies an offset into the series of iterations at which the animation node should begin. The iteration start is a finite real number greater than or equal to zero.
The behavior of these parameters is defined in the calculations in section 3.10 Core animation node calculations.
This section is non-normative.
The effect of the iteration count and iteration start parameters is illustrated below.
Unlike the iteration count parameter, the iteration start parameter does not effect the length of the active duration.
Note that values of iteration start greater than or equal to one are generally not useful unless used in combination with an animation effect that has an iteration composite operation of accumulate.
This section is non-normative.
We have already encountered different time spaces in describing local time and inherited time (see section 3.6.4 Local time and inherited time). Repetition introduces yet another time space: the iteration time space.
Iteration time space is a time space whose zero time is the beginning of an animation node's current iteration.
Within the Web Animations model we also refer to active time which is a time relative to the beginning of the active interval. This time space, however, is internal to the model and not exposed in the programming interface or in markup.
These time spaces are illustrated below.
Note that while the time spaces themselves are not bounded, Web Animations defines active time and iteration time such that they are clamped to a set range as shown in the diagram. For example, whilst a time of -1 second is a valid time in active time space, the procedure for calculating the active time defined in section 3.10.3.1 Calculating the active time will never return a negative value.
In addition to these time spaces we can also refer to the document time space which is time space of the time values of the document timeline of the active document.
This section is non-normative.
When an animation node repeats we must define the behavior at the
iteration boundaries.
For this and indeed for all interval-timing, Web Animations uses an
endpoint-exclusive timing model.
This means that whilst the begin time of an interval
is included in the interval, the end time time is not.
In interval notation this can written [begin, end)
.
This model provides sensible behavior when intervals are repeated and
sequenced since there is no overlap between the intervals.
In the examples below, for the repeated node, at local time 1s, the iteration time is 0. For the sequenced nodes, at inherited time 1s, only node B will be in play; there is no overlap.
An exception to this behavior is that when performing a fill, if the fill begins at an interval endpoint, the endpoint is used. This behavior falls out of the algorithm given in section 3.10.3.3 Calculating the iteration time and is illustrated below.
Like players, animation nodes also have a playback rate parameter. The playback rate of an animation node is a finite real number that acts as a multiplier when calculating the animation node's transformed time from its local time.
The effect of setting the playback rate of an animation node differs from the setting the playback rate on a player. Its behavior is defined in the timing calculations given in section 3.10 Core animation node calculations.
This section is non-normative.
In summary, the behavior of the playback rate of an animation node is as follows:
Changing the playback rate of an animation node whose local time is within its active interval will cause it to jump. This is because the active duration will be updated but the local time will not.
Furthermore, if other animation nodes depend on the animation node's active duration, such as sibling animation node in a sequence animation group, they too may jump as a result of setting the animation node's playback rate.
For runtime speed control the playback rate of the player should be used.
This section is non-normative.
At the core of the Web Animations timing model is the process that takes an inherited time value and converts it to an iteration time.
Following this further transformations are applied before resulting at a final transformed time.
The first step in this process is to calculate the bounds of the active interval which is determined by the active duration.
This process is illustrated below.
The process for calculating the active duration is normatively defined in section 3.10.2 Calculating the active duration.
Having established the active duration, the process for transforming an animation node's inherited time into its transformed time is illustrated below.
The first step, calculating the local time is described in section 3.6.4 Local time and inherited time. Steps 2 to 4 in the diagram are described in the following sections. Steps 5 and 6 are described in section 3.11.1 Calculating the directed time and section 3.12.5 Calculating the transformed time respectively.
In order to calculate the active duration we first define the repeated duration as follows:
repeated duration =iteration duration × iteration count
If either the iteration duration or iteration count are zero, the repeated duration is zero.
This clarification is needed since the result of infinity multiplied by zero is undefined according to IEEE 754-2008.
The active duration is calculated according to the following steps:
Infinity
.
repeated duration / abs(playback rate)
.
The active time is based on the local time and start delay. However, it is only defined when the animation node should produce an output and hence depends on its fill mode and phase as well as the phase of its parent animation group, if any, as follows,
null
.
null
.null
.
null
.
local time - start delay
.
null
.
null
.null
),null
.
Before the active time can be converted to an iteration time we must factor in the animation node's playback rate and iteration start. The result is called the scaled active time.
In order to calculate the scaled active time we first define the start offset as follows:
start offset =iteration start × iteration duration
If the iteration start is zero, the start offset is zero.
This clarification is needed since the iteration duration may be infinity and the result of infinity multiplied by zero is undefined according to IEEE 754-2008.
The scaled active time is calculated according to the following steps:
null
, return
null
.
(active time -
active duration)
× playback
rate
+ start offset
.
active time
× playback
rate + start offset
.
The iteration time is calculated according to the following steps:
null
,
return null
.
scaled active time - start
offset
is equal to the repeated duration,
and iteration count is not zero,
and (iteration count + iteration start)
% 1
is zero,
return the iteration duration.
scaled active time
% iteration duration
.
The current iteration can be calculated using the following steps:
null
, return
null
.
ceil(iteration start + iteration count) -
1
.
iteration start
+ iteration count - 1
.
floor(scaled active time /
iteration duration)
.
If the iteration duration is infinite, the
result of floor(scaled active time /
iteration duration)
will be zero as defined by
IEEE 754-2008.
Animation nodes may also be configured to run iterations in alternative directions using direction control. For this purpose, animation nodes have a playback direction parameter which takes one of the following values:
The semantics of these values are incorporated into the calculation of the directed time which follows.
This section is non-normative.
A non-normative definition of these values is as follows:
The directed time is calculated from the iteration time using the following steps:
null
, return
null
.
normal
,
reverse
,
alternate-reverse
increment
d by 1.
There used to be a step here which seemed to be adding special handling for filling when the node ends on a repeat boundary but it seems like that is taken care of by the calcuation of iteration time and current iteration. Is anything actually needed here?
d % 2 == 0
, let the
current direction be forwards, otherwise let
the current direction be reverse.
Otherwise, return the iteration duration - iteration time.
This section is non-normative.
It is often desirable to control the rate at which an animation node progresses. For example, easing the rate of animation can create a sense of momentum and produce a more natural effect. Conversely, in other situations such as when modelling a discrete change, a smooth transition is undesirable and instead it is necessary for the animation node to progress in a series of distinct steps.
For such situations Web Animations provides timing functions that scale the progress of an animation node.
Timing functions take an input time fraction and produce a scaled output time fraction.
Timing functions are applied to an iteration of an animation node.
A timing function takes an input time fraction in the range [0, 1] and produces an output time fraction whose range is unbounded (i.e. positive and negative infinity are permitted).
Animation nodes have one timing function associated with them. The default timing function is the linear timing function whose output is identical to its input. The linear timing function can be represented by the string “linear”.
The range of timing functions that may be applied to a given animation node depends on the type of the animation node.
Currently, the set of timing functions allowed on an animation group is not restricted. This has raised concern about complexity of implementation and also complexity of behavior with regards to fill modes. As a result, allowing the full set of timing functions on animation groups is considered at risk.
Alternatives are to either restrict timing functions on animation groups to the linear timing function or to a set of “simple” timing functions that have properties that alleviate some of the concerns with the more complex timing functions.
This section is non-normative.
A common method of producing easing effects is to use a cubic Bézier curve to scale the time. The endpoints of the curve are fixed at (0, 0) and (1, 1) while two control points P1 and P2 define the shape of the curve. Provided the x values of P1 and P2 lie within the range [0, 1] such a curve produces a function that is used to map input times (the x values) onto output times (the y values). This arrangement is illustrated below.
Some example cubic Bézier timing functions are illustrated below.
A cubic Bézier timing function is a type of timing function defined by four real numbers that specify the two control points, P1 and P2, of a cubic Bézier curve whose end points are fixed at (0, 0) and (1, 1). The x coordinates of P1 and P2 are restricted to the range [0, 1].
The evaluation of this curve is covered in many sources such as [FUND-COMP-GRAPHICS].
A cubic Bézier timing function may be specified as a string using the following syntax (using notation from [CSS3-VALUES]):
<cubic-bezier-timing-function> = ease | ease-in | ease-out | ease-in-out | cubic-bezier(<number> <number> <number> <number>)
The meaning of each value is as follows:
It has been proposed to extend cubic-bezier
to allow
multiple segments, using syntax such as the following:
cubic-bezier( [ <number>{6} ; ]* <number>{4} )
(i.e. the curve starts at (0, 0); each segment is defined by six numbers where the start point is the end of the previous segment and the numbers define the two control points and the end point. The last segment is defined by four numbers since the end point is fixed at (1, 1).)
This would provide a simple and compact syntax for tools trying to map arbitrary curves (e.g. bounce functions) to timing functions.
This section is non-normative.
It is possible to scale an animation node's timing so that the animation node occurs in a series of discrete steps using a stepping function.
Some example step timing functions are illustrated below.
A step timing function is a type of timing function that divides the input time into a specified number of intervals that are equal in duration. The output time, starting at zero, rises by an amount equal to the interval duration once during each interval at the transition point which may be either the start, midpoint, or end of the interval.
In keeping with Web Animations' model of endpoint exclusive interval timing (see section 3.8.4 Interval timing), the output time at the transition point is the time after applying the increase (i.e. the top of the step) with the following exception.
When a transition point coincides with the end of the active interval extra care must be taken to produce the correct result when performing a fill. To achieve this, when a step timing function is applied to an animation node or applied to an animation effect associated with an animation node, an additional before flag is passed. The value of the before flag is determined as follows:
When a step timing function is evaluated at a transition point, if the before flag is set the result is the value before applying the increase.
A step timing function may be specified as a string using the following syntax:
<step-timing-function> = step-start | step-middle | step-end | steps(<integer>[, [ start | middle | end ] ]?)
The meaning of each value is as follows:
The transformed time is calculated from the directed time using the following steps:
null
,
return null
.
directed time / iteration
duration
unless iteration duration is
zero, in which case let iteration fraction be
zero.
scaled
fraction × iteration duration
.
If the scaled fraction is zero, let the result be
zero.
This clarification is needed since the iteration duration may be infinity and the result of infinity multiplied by zero is undefined according to IEEE 754-2008.
This section is non-normative.
While it is possible to set the timing properties of animation nodes individually, it is often useful to synchronize animation nodes so that they share common timing properties and maintain their temporal relationship. This is achieved using an animation group.
A simple example is illustrated below.
When an animation group is directly associated with a player, the animation nodes associated with the animation group can be seeked, paused, and stopped as a unit.
An animation group is a type of animation node that contains an ordered sequence of zero or more animation nodes known as child animation nodes.
At a given moment, an animation node may be a child animation node of at most one animation group known as the parent animation group. The parent animation group cannot be the same animation node as the child animation node itself.
By nesting animation groups it is possible to create hierarchical tree structures. The following terms are used to describe the parts and properties of such structures and are defined in [DOM4]:
Note that in applying these definitions to animation nodes, the term parent refers exclusively to a parent animation group and does not include the player which with an animation node may be directly associated despite the fact that conceptually the player acts as a parent time source.
The temporal relationship between a child animation node and its parent animation group is incorporated in the definition of inherited time (see section 3.6.4 Local time and inherited time).
This section is non-normative.
The timing of the children of an animation group is based on the timing of the group. Specifically, times for the children are based on the parent's transformed time. With regards to repetition, this means the children operate inside an iteration of the parent.
For example, if an animation group has an iteration count of 2, then the children of of the group will all play twice since they effectively play inside the group's iterations.
Note that even in this case, the child animation nodes still have only one active interval. However, as a result of the parent's timing, the active interval is played twice.
If an iteration count is specified for the children of a group as well as for the group itself, the effect is as if the iteration count of the group was multiplied with the iteration count of the children.
A further result of the children of an animation group basing their timing on the group's transformed time is that they cannot animate outside of the group's active interval. This is because the transformed time of a group will not change outside its active interval. This allows groups to clip the playback of their children.
Some further consequences of animation group children basing their timing on their parent group's transformed time are:
The start time of a child animation node of an animation group is zero.
Note that specific types of animation groups may override this definition to provide other kinds of synchronization behavior.
The intrinsic iteration duration of an animation group is based on the time when the last child animation node completes its active interval and is calculated using the following procedure.
Define the end time of an animation node as :
end time =
start time +
start delay + active duration + end
delay
The intrinsic iteration duration depends on the number of child animation nodes as follows,
max(0, maximum end
time)
.This definition of the intrinsic iteration duration may be overridden by specific types of animation groups.
This section is non-normative.
Specific types of animation groups can be used to provide different kinds of synchronization behavior for their children. This specification defines one additional type of animation group: an animation sequence. Animation sequences arrange the start times of their children so that they run one at a time, in turn.
Compare the two arrangements illustrated below:
Since animation groups can also contain other animation groups, complex synchronization is possible by combining different types of groups as illustrated below.
An animation sequence is a type of animation group that schedules its child animation nodes such that they play in turn following their order in the group. This sequencing is achieved by adjusting the start time of each child animation node in the group.
The start time of a child animation node of an animation sequence is the end time of the child's previous sibling. If the child has no previous sibling the start time is zero.
When the active duration is positive infinity the behavior for calculating the end time of an animation node and the start time of subsequent children follows the usual behavior defined by IEEE 754-2008. As a result, if any of the children of an animation sequence has an infinite active duration, any children that occur later in the sequence will not play.
Similarly, the above definition does not restrict start times to positive values and hence some children may not play due to a negative start delay on children that occur earlier in the group since their active interval may end before the group's start time.
This section is non-normative.
Because the start of the active interval is based on the sum of an animation node's start time and start delay, the active intervals of children of an animation sequence need not run in strict sequence but can be shifted back and forth by using the start delay as shown in the following diagram.
A negative start delay can be used to cause the active interval of two children to overlap. Note that the start delay affects the start time of subsequent children in the group.
The intrinsic iteration duration of an animation sequence is equivalent to the start time of a hypothetical child animation node appended to the group's children calculated according to the definition in section 3.13.4.1 The start time of children of an animation sequence unless that produces a negative value, in which case the intrinsic iteration duration is zero.
As a result, if the animation sequence has no child animation nodes the intrinsic iteration duration will be zero.
Animations are a kind of animation
node that apply an animation effect or a custom effect
to an element or pseudo-element such as ::before
and
::first-line
[SELECT] referred to as the animation
target.
Before passing the transformed time of an animation to its animation effect it is converted to a time fraction. The time fraction of an animation node is calculated according to the following steps:
the time fraction is as follows,
start
delay + normalized active duration
and an iteration duration of 1.
null
, in which case return
null
.
Since timing functions are allowed to produce output times outside the range [0, 1] it is possible that the value calculated for a time fraction also lies outside this range.
This section is non-normative.
The Web Animations animation model takes the time fractions and current iteration values produced by the timing model for a given animation and applies it as the input to the animation's animation effect.
The output of each animation effect is then combined with other animation effects using an animation stack before being applied to the target properties (see section 4.2 Combining animations).
An animation effect takes a time fraction and a current iteration value and uses them to calculate an intermediate animation value for its target properties. Each animation may have at most one animation effect associated with it.
Since the result of an animation effect is based on the time fraction and current iteration value, it is updated whenever the timing model is sampled.
Each animation effect can have zero or more associated target properties.
Target properties may be CSS properties or DOM attributes. If a given animation target has an attribute with the same name as a CSS property, any target property of that name is taken to refer to to the CSS property.If there ever exists a situation where we need to animate an attribute with the same name as a property (other than a presentation attribute [SVG2]) then we will need to introduce a disambiguation strategy. Generally, however, such naming should be avoided.
In order to animate a target property, the following procedures must be defined.
This section is non-normative.
While addition can often be expressed in terms of the same weighted sum function used to define interpolation, this is not always the case. For example, interpolation of transform matrices involves decomposing and interpolating the matrix components whilst addition relies on matrix multiplication.
This section is non-normative.
For many types of animation such as numbers or lengths, accumulation is defined to be identical to addition.
A common case where the definitions differ is for list-based types where addition may be defined as appending to a list whilst accumulation may be defined as component-based addition. For example, the filter list values "blur(2)" and "blur(3)", when added together may produce "blur(2) blur(3)", but when accumulated, may produce "blur(5)".
The specific procedures used for animating a given target property are referred to as the property's animation behavior.
The animation behavior of CSS properties is defined by the "Animatable:" line in the summary of the property's definition or in [CSS3-TRANSITIONS] for properties that lack a such a line.
The default animation behavior for CSS properties is "as string". Should this be defined here or in CSS Animations Level 4?
For DOM attributes, the animation behavior is defined alongside the attribute definition. Unlike CSS properties, if such a definition is not provided the default animation behavior is “not animatable”.
Following is a series of pre-defined animation behaviors. [CSS3-TRANSITIONS] provides further CSS-specific animation behaviors.
For animation behaviors that do not define a specific procedure for addition or which are defined as not additive, the addition procedure is simply Vres = Vb.
For animation behaviors that do not define a specific procedure for accumulation, the accumulation procedure is identical to the addition procedure for that behavior.
For animation behaviors that do not define a specific procedure for distance computation or which are defined as not paceable, the distance computation procedure is simply distance = 1.
Some properties are specifically defined as not animatable. For example, properties defining animation parameters are not animatable since doing so would create complex recursive behavior.
Unlike other animation behaviors, no procedures for interpolation, addition and distance computation are defined for properties whose animation behavior is not animatable since these properties should not be modified.
An animation effect that targets a property that is not animatable will still exhibit the usual behavior for an animation node such as occupying time in an animation sequence and delaying the firing of a player's finish event.
A target property that is animatable as string has the following animation behavior:
A target property that is animatable as real number has the following animation behavior:
A target property that is animatable as length, percentage, or calc has the following animation behavior:
calc()
functions are expanded when
determining the computed value as defined in CSS
Values and Units [CSS3-VALUES].)
A target property that is animatable as color has the following animation behavior:
Since negative color is not currently supported, clamping of the channel values may be performed upon each addition or once when composition is complete.
sqrt((Rend - Rstart)^2 + (Gend - Gstart)^2 + (Bend - Bstart)^2 + (Aend - Astart)^2)
Should we call this “animatable as premultiplied RGBA additive color in sRGB color space” instead?
A target property that is animatable as transform list has the following animation behavior:
We should probably expand 2d functions to their 3d equivalents before matching?
This needs to be more specific, e.g. when combining
translate(20px)
and translate(30px
10px)
we have to expand the first function to
translate(20px 0px)
first.
Probably need to define unit conversion too.
For distance computation we previously defined it as follows:
This seems really arbitrary, especially part 5.
Also, looking at only the first component seems odd. Going through each component, working out the distance and then getting the square of the distance also seems much more consistent with what we do elsewhere.
The set of animation behaviors defined here may be extended by other specifications. For example, properties with using the <image> type are animated using the interpolation behavior defined in CSS Image Values and Replaced Content [CSS4-IMAGES].
There are a bunch of CSS properties for which distance (and in some cases addition) is not defined or which need special handling.
For example,
Should we define these here or in the CSS Animation 4 spec?
Given a time fraction, a current iteration, and an underlying value, an animation effect produces an intermediate animation value for each animatable target property. The procedure for calculating this value depends on the specific type of animation effect and is defined subsequently (see section 4.3.2 The intermediate animation value of a keyframe animation effect and section 4.4.4 The intermediate animation value of a motion path animation effect).
Before being applied to the target properties, these intermediate animation values are composed together using the process defined in section 4.2 Combining animations.
This section is non-normative.
After calculating the intermediate animation values for an animation effect, they are applied to the animation effect's target properties.
Since it is possible for multiple in effect animations to target the same property it is often necessary to combine the results of several animation effects together. This process is called compositing and is based on establishing an animation stack for each property targetted by an in effect animation effect.
After compositing the results of animation effects together, the composited result is combined with other values specified for the target property.
For a CSS target property the arrangement is illustrated below:
For a target property that specifies a DOM attribute, the composited result is combined with the value of the attribute specified in the DOM or the lacuna value for that attribute if it is not specified.
For the first part of this operation—combining intermediate animation values that target the same property— it is necessary to determine both how the animation effects associated with the animations are combined with one another, as well as the order in which they are applied, that is, their relative priority.
The matter of how intermediate animation values are combined is governed by the composite operation of the corresponding animation effects.
The relative priority of intermediate animation values is determined by an animation stack established for each animated property.
Associated with each property targetted by one or more animation effects is an animation stack that establishes the relative priority of the animation effects.
The relative priority of any two animation effects, A and B, within an animation stack is established by comparing the properties of the animations applying A and B as follows:
Animation effects that sort earlier have lower priority.
Each player has an associated numeric custom player priority that is used to provide high-level control of animation priority for specifications layered on top of Web Animations. The initial value of the custom player priority is zero.
Note that the custom player priority is primarily intended to be used to prioritize animations at a high-level, such as to prioritize animations by type. For example, it can be used to ensure that CSS Animations always override CSS Transitions.
It is possible to control animation priority at a lower-level by setting the player start time appropriately, (possibly after making compensatory adjustments to the start delay of the source content) or influencing the player sequence number by controlling when players are created.
In order to calculate the final value of an animation stack, the intermediate animation values of each animation effect in the stack are combined in order of priority from lowest to highest priority.
Each step in the process of evaluating an animation stack takes an underlying value as input.
For each animation effect in the stack, the appropriate intermediate animation value from the animation effect is combined with the underlying value to produce a new value. This resulting value becomes the underlying value for combining the next animation effect in the stack.
The final value of an animation stack, called the composited value, is simply the result of combining the intermediate animation value of the final (highest priority) animation effect in the stack with the underlying value at that point.
The specific operation used to combine an intermediate animation value with an underlying value is determined by the composite operation of the animation effect that produced the intermediate animation value.
This specification defines three composite operations as follows:
The intermediate animation value is added to the underlying
value.
For animation behaviors where the
addition operation is defined
such that it is not commutative, the order of the operands is
underlying value + intermediate animation
value
.
The intermediate animation value is accumulated onto the underlying value. For animation behaviours where the accumulation operation is defined such that it is not commutative, the order of the operands is underlying value followed by intermediate animation value.
The process for a applying a composited value depends on if the target property refers to a CSS property or a DOM attribute.
Applying a composited value to a CSS target property depends on establishing an animation stylesheet.
The animation stylesheet contains
composited animation values
and acts with a higher priority than all other stylesheets.
However, !important
rules from all other stylesheets
act with a higher priority than the animation stylesheet.
The animation stylesheet is regenerated each time the
animation model is updated (see section 4.1 Animation effects).
The composited value calculated for a CSS target property is applied using the following process.
DOM attributes are, unless otherwise specified, not animatable. For each attribute that has a specific animation behavior associated with it, an attribute value to use when the attribute is not specified or in error must be defined, referred to as the lacuna value. For example, SVG2 ([SVG2]) defines lacunae values for its attributes.
The composited value calculated for a DOM attribute target property is applied using the following process.
The animated attribute value does not replace the value of the attribute in the DOM although it may be accessible via some other interface. For all intents and purposes other than interaction with DOM interfaces, user agents must treat the animated attribute value as the attribute value.
Similar to the compositing performed between intermediate animation values (see section 4.2.3 Animation composition), the iteration composite operation determines how values are combined between successive iterations of the same animation.
This specification defines two iteration composite operations as follows:
The application of the iteration composite operation is incorporated in the calculation of the intermediate animation value for each type of animation effect.
A keyframe animation effect is an animation effect that produces intermediate animation values for its target properties by interpolating between a series of property values positioned at fractional offsets.
Each set of property values indexed by an offset is called a keyframe.
The offset of a keyframe is a value in the range [0, 1] or the special value null. The list of keyframes for a keyframe animation effect is loosely sorted by offset which means that for each keyframe in the list that has a keyframe offset that is not null, the offset is greater than or equal to the offset of the previous keyframe in the list with a keyframe offset that is not null, if any.
The behavior when keyframes overlap or have unsupported values is defined in section 4.3.2 The intermediate animation value of a keyframe animation effect.
Each keyframe also has a timing function associated with it that is applied to the period of time between the keyframe on which it is specified and the next keyframe in the list. The timing function specified on the last keyframe in the list is never applied.
In addition to the composite operation specified on the animation effect, each keyframe may also have an associated composite operation that is applied to all values specified in that keyframe. If no composite operation is specified for a keyframe, the composite operation specified for the animation effect is used.
This section is non-normative.
It is often useful to be able to provide a series of property values without having calculate the keyframe offset of each value in time but instead to rely on some automatic spacing.
For example, rather than typing:
elem.animate([ { color: 'blue', offset: 0 }, { color: 'green', offset: 1/3 }, { color: 'red', offset: 2/3 }, { color: 'yellow', offset: 1 } ], 2000);
It should be possible to type the following and allow the user agent to calculate the offset of each keyframe:
elem.animate([ { color: 'blue' }, { color: 'green' }, { color: 'red' }, { color: 'yellow' } ], 2000);
Web Animations provides spacing modes for this purpose. The default spacing mode for keyframe animation effects is “distribute” which produces the result described above.
The other spacing mode, “paced”, is useful when it is desirable to maintain an even rate of change such as for motion path animation.
For example, consider the following animation:
elem.animate([ { left: '0px' }, { left: '-20px' }, { left: '100px' }, { left: '50px' } ], 1000);
The resulting value of the left property is illustrated below:
We can use the paced spacing mode as follows:
elem.animate( new KeyframeEffect([ { left: '0px' }, { left: '-20px' }, { left: '100px' }, { left: '50px' } ], { spacing: "paced" }), 1000);
The result is illustrated below:
It is also possible to combine fixed keyframe offsets with spacing modes as follows:
elem.animate( new KeyframeEffect([ { left: '0px' }, { left: '-20px' }, { left: '100px', offset: 0.5 }, { left: '50px' } ], { spacing: "paced" }), 1000);
The result is illustrated below:
Before calculating animation values from a keyframe animation effect, an absolute value must be computed for the keyframe offset of each keyframe with a null offset. The values computed depend on the keyframe spacing mode specified for the keyframe animation effect. The keyframe spacing modes are:
We define a generic procedure for evenly distributing a keyframe, keyframe, between two reference keyframes, start and end, whose keyframe offsets are not null, as follows:
The computed keyframe offset values of each keyframe with a null keyframe offset are determined using the following procedure.
calculate the keyframe offset of each keyframe between A and B depending on the keyframe spacing mode as follows:
Note that although the above procedure defines computing keyframe
offsets in terms of overwriting null values, user agents that
implement the programming
interface are required to maintain the original null values as
well as calculating the computed offsets.
This is because the getFrames
method of the
KeyframeEffect
interface returns keyframe offsets both
before and after applying spacing.
The above algorithm is quite complex. It attempts to cover all possible combinations of input where keyframe offsets and or paced property values may be missing. Furthermore, it attempts to do this in a way that degenerates consistently and also allows the author to combine fixed offsets with either pacing or distribute spacing. We await implementation experience to determine if the complexity is justified.
The intermediate animation value of a single property referenced by a keyframe animation effect as one of its target properties, for a given time fraction, current iteration and underlying value is calculated as follows.
It seems like this could be done as a separate step at the end and applied to all types of animation effects consistently.
(time fraction - start offset) /
(end offset - start offset)
Note that this procedure assumes the following about the list of keyframes specified on the effect:
It is the responsibility of the user of the model (for example, a declarative markup or programming interface) to ensure these conditions are met.
For example, for the programming
interface defined by this specification, these conditions are
met by applying the normalization defined in section 5.14.6 Normalizing a sequence of keyframes
and resolving null
keyframe offsets by
applying spacing behavior.
Note that this procedure permits overlapping keyframes. The behavior is that at the point of overlap the output value jumps to the value of the last defined keyframe at that offset. For overlapping frames at 0 or 1, the output value for time fractions less than 0 or greater than or equal to 1 is the value of the first keyframe or the last keyframe in keyframes respectively.
In the presence of certain timing functions, the input time fraction to an animation effect is not limited to the range [0, 1]. Currently, however, keyframe offsets are limited to the range [0, 1] and property values are simply extrapolated for input time fractions outside this range.
We have considered removing this restriction since some cases exist where it is useful to be able to specify non-linear changes in property values at time fractions outside the range [0, 1]. One example is an animation that interpolates from green to yellow but has an overshoot timing function that makes it temporarily interpolate ‘beyond’ yellow to red before settling back to yellow.
While this effect could be achieved by modification of the keyframes and timing function, this approach seems to break the model's separation of timing concerns from animation effects.
It is not clear how this effect should be achieved but we note that allowing keyframe offsets outside [0, 1] may make the currently specified behavior where keyframes at offset 0 and 1 are synthesized as necessary, inconsistent.
See section 4 (Keyframe offsets outside [0, 1]) of minuted discussion from Tokyo 2013 F2F.
A motion path animation effect is an animation effect that produces animation values for the transform target property of an animation target such that it follows a geometric curve commonly referred to as a “motion path”.
The motion path of a motion path animation effect is defined by an SVG Path, as specified by SVG [SVG2]. A motion path consists of a list of path commands (see path data [SVG2]).
Amongst the different types of path commands, we define orientation path commands as moveto commands and bearing commands. All types of path commands that are not orientation path commands are referred to as drawing path commands.
The automatic rotation flag of a motion path animation effect, if set, specifies that the intermediate animation value generated by the motion path animation effect produces a rotation that matches the directional tangent vector of the motion path.
The rotation angle parameter of a motion path animation effect specifies a constant rotation that applies to the target transform in addition to any rotation generated by setting the automatic rotation flag.
The procedure used for calculating the length of a path or a subsection is provided by the definition of distance along a path in SVG [SVG2].
The following properties control the rate of progress of a motion path animation effect:
Specifies the strategy used for determining the offset of each spacing point or path command when not specified by a point offset. The possible spacing modes are identical to those defined for keyframe animation effects (see section 4.3.1 Spacing keyframes).
Note that a spacing mode of distribute has no effect if point offsets are specified. This is because spacing between point offsets always uses paced spacing mode.
An optional sequence of real numbers in the range [0.0, 1.0] that correspond to fractions of the total path length. The animation effect produces animation values such that the animation target moves backwards and forwards along the motion path following the sequence indicated by these points.
Furthermore, the point on the motion path indicated by each such number forms a handle that may be associated with a point offset or positioned by the spacing mode.
An optional ordered sequence of real numbers in the range [0.0, 1.0] that specifies the time fraction when the corresponding spacing point, or, if spacing points are not provided, drawing path command, should be visited.
If specified, the first value in the sequence must be 0.0 and the last value must be 1.0. There must be as many items in the sequence of point offsets as in the sequence of spacing points, if provided. If a sequence of spacing points is not provided, the number of items in point offsets must equal the number of drawing path commands in the motion path plus one.
An optional ordered sequence of timing functions that specify the easing behavior between each pair of spacing points, or, if spacing points are not provided, between each pair of drawing path commands.
If specified, there must be as many items as in the sequence of spacing points minus one, if provided. If a sequence of spacing points is not provided, the number of items in point easing must equal the number of drawing path commands in the motion path.
Note that the above descriptions of the length of each list represent the requirements of the model. Users of the model such as markup or programming interfaces may fulfil these requirements, for example, by defining padding behavior or error handling.
The end result of applying spacing is:
The sequence of effective spacing points is determined by following the steps associated with the first matching condition from below:
Having determined the effective spacing points, the sequence of effective point offsets is determined by following the steps associated with the first matching condition from below:
The effective point easing is simply the specified point easing. If point easing is not set, the effective point easing is a sequence of linear timing functions equal in length to the number of drawing path commands in the motion path.
The path fraction for a given time fraction, progress, is determined using the following procedure:
scaled interval fraction *
(segment end - segment start) +
segment start
.
The intermediate animation value of a motion path animation effect for a given time fraction, current iteration, and underlying value is given by the following process:
If distance indicates a point on the path that is coincidental with one or more orientation path commands, displacement is the point after all orientation path commands (this will be the start of the next drawing path command if there is one).
When calculating the angle of the tangent vector, if there are no drawing path commands in the motion path, the the angle should be taken to be zero.
The original text for this section contained the following qualifications but I'm not sure how meaningful they are:
This section is non-normative.
In some situations the animation
effects provided by Web Animations may be insufficient.
For example, the animation effects
defined here are only able to target certain CSS properties.
They are unable, therefore, to modify the currentScale
property of an SVG element to smoothly zoom the viewport without
affecting the document content.
In such cases, where the provided animation effects do not provide needed functionality, an effect defined by script may be used. Such custom effects receive a time fraction and current iteration from the timing model and are responsible for producing an effect corresponding to the specified time.
Using an effect defined in script it is possible to animate not only otherwise un-animatable attributes and properties, but potentially anything that is accessible via script, including even producing audio or creating vibrations.
For example, using a custom effect that draws to a canvas
element, it is possible to produce a complex animated effect
featuring patterns that may be difficult to create using CSS or
SVG.
Compared to using Timing control for
script-based animations,
this approach ensures the animation is frame-rate
independent and can be paused, reversed, eased with timing effects,
accelerated, synchronized with other animations, and be controlled
in the same manner as any other Web Animations animation without any
additional programming.
A custom effect is an author-defined programming callback that is passed timing information when sampling is performed.
Custom effects are called for each referencing animation when a sample is performed based on the following criteria.
Call the callback passing a null time fraction and the animation target from the previous sample as parameters to the callback.
There may be use cases where an action needs to be triggered at a specific point in an animation tree. In many cases this can be achieved by inserting a custom effect with a step-start easing that spans the period during which the action should be triggered. However, this can impose additional layout requirements on the content which might be cumbersome to accomodate.
Some alternatives under consideration:
Since custom effects, unlike animation effects, are not limited to a single target property, the steps for assessing their order of execution differs from animation effects.
Custom effects are executed after all animation effects have completed and applied their result to their targets (see section 4.2.4 Applying the composited result).
Need to define this more precisely. Are styles flushed? Presumably they are. Can we suspend reflow for the duration of executing the script-based animation effects and just do it once afterwards?
Within the set of custom effects, the order of execution is the same as that defined for animation effects in section 4.2.1 The animation stack. Items sorted earlier are executed before those sorted later.
This section is non-normative.
In addition to the abstract model described above, Web Animations also defines a programming interface to the model. This interface can be used to inspect and extend animations produced by declarative means or for directly producing animations when a procedural approach is more suitable.
AnimationTimeline
interface
Timelines, including the document
timeline are represented in the Web Animations API by the
AnimationTimeline
interface.
interface AnimationTimeline {
readonly attribute double? currentTime;
AnimationPlayer
play (optional AnimationNode
? source = null);
sequence<AnimationPlayer
> getAnimationPlayers ();
};
currentTime
of type double, readonly, nullable
Returns the time value for this timeline or
null
if this timeline is not started.
play
Creates a new AnimationPlayer
object
associated with this timeline that is scheduled to start
at currentTime
.
The timeline
attribute of the newly-created
AnimationPlayer
object will be set to this object.
Similarly, the start time of the
newly created player will be set to the value of this
object's currentTime
attribute at the moment the
method was called.
The setting of the source
attribute is described
below under the description of the source parameter.
The currentTime
attribute of the
AnimationPlayer
object is a calculated value described in
section 3.5.1 The current time of a player.
The playbackRate
and paused
attributes
take on their default values as described in the definitions of
the playback rate and
paused state properties of player objects.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
source |
| ✔ | ✔ (null ) |
The source content to assign to the newly-created
The |
AnimationPlayer
getAnimationPlayers
Returns the set of AnimationPlayer
objects
associated with this timeline that have associated
source content which is current.
The returned list is sorted in increasing order by player sequence number.
sequence<AnimationPlayer
>
AnimationPlayer
interface
Players are represented in the Web Animations
API by the AnimationPlayer
interface.
interface AnimationPlayer : EventTarget {
attribute AnimationNode
? source;
readonly attribute AnimationTimeline
timeline;
attribute double startTime;
attribute double currentTime;
attribute double playbackRate;
readonly attribute boolean paused;
readonly attribute boolean finished;
void cancel ();
void finish ();
void play ();
void pause ();
void reverse ();
// Event callbacks
attribute EventHandler onfinish;
};
source
of type AnimationNode
, nullableThe source content associated with this player.
A player can only be associated with at most one animation node, and likewise, an animation node can only be associated with at most one player. In order to maintain these invariants, on setting this value, the following procedure is performed:
source
attribute.null
,
disassociate old value from this player.null
,
perform the steps associated with the first matching condition
of the following:
new value.remove()
.source
attribute to new
value.timeline
of type AnimationTimeline
, readonlystartTime
of type doublecurrentTime
of type doubleplaybackRate
of type doublepaused
of type boolean, readonlyfinished
of type boolean, readonlyonfinish
of type EventHandlerThe event handler for the finish event.
Note that the EventHandler callback interface type is defined in [HTML5].
cancel
source
to null and clears all effects associated
with the previous source content.
source
to null as
well so we should define this behavior there.
void
finish
Seeks the player to the end of the source content in the current direction as follows:
Exceptions:
InvalidStateError
void
play
Unpauses the player and rewinds if it has finished playing using the following procedure:
void
pause
void
reverse
Inverts the playback rate of this player and seeks to the start of the source media if it has finished playing in the reversed direction using the following procedure.
-player
playback rate
following the steps in section 3.5.3.1 Updating the playback rate.
Is this unpausing behavior correct?
Note that unlike play()
, the player's finished
flag is not explicitly reset here since that behavior is
performed by the procedure for updating the player playback
rate defined in section 3.5.3.1 Updating the playback rate.
void
AnimationNode
interface
Animation nodes are represented in the Web
Animations API by the AnimationNode
interface.
interface AnimationNode {
// Playback state
readonly attribute double? localTime;
readonly attribute unsigned long? currentIteration;
// Specified timing
readonly attribute AnimationTiming
timing;
// Calculated timing
readonly attribute double startTime;
readonly attribute unrestricted double duration;
readonly attribute unrestricted double activeDuration;
readonly attribute unrestricted double endTime;
// Timing hierarchy
readonly attribute AnimationGroup
? parent;
readonly attribute AnimationNode
? previousSibling;
readonly attribute AnimationNode
? nextSibling;
void before (AnimationNode... nodes);
void after (AnimationNode... nodes);
void replace (AnimationNode... nodes);
void remove ();
// Associated player
readonly attribute AnimationPlayer
? player;
};
localTime
of type double, readonly, nullableThe local time of this animation node.
localTime
will be null
if this
animation node is not associated with a player or if it has
a parent animation group that is not in effect.
currentIteration
of type unsigned long, readonly, nullabletiming
of type AnimationTiming
, readonly
Returns the input timing properties specified for this
animation node.
This is comparable to the specified style on an Element,
elem.style
.
Should we make this writeable? Then you could do:
animA.timing = animB.timing;
Doing so would probably also involve defining
AnimationTiming.clone
and a constructor for
AnimationTiming
.
Representing these parameters has been a particularly contentious topic.
The current arrangement:
AnimationTiming
interface
and an AnimationTimingInput
dictionary type which
increases the API surface area somewhat
anim.timing.duration
) to reading
the value (typically, anim.duration
)
AnimationTiming
objects should be share-able or not
"3s"
should be allowed (and allowing
them makes walking the tree more complex).
However, it separates "specified" timing from "computed" timing which some consider advantageous.
The only situation where calculated values and input values
differ is for duration
.
One alternative that has been proposed is to introduce
a Duration
interface as follows:
interface AnimationNode { // AnimationTiming attribute double delay; attribute FillMode fill; attribute Duration duration; attribute double playbackRate; // ... // Scheduled time readonly attribute double startTime; readonly attribute unrestricted double endTime; }; interface Duration { double ms; DOMString string; }
Usage is as follows:
var specifiedDur = anim.duration.string; // "auto" var calculatedDur = anim.duration.ms; // 5000 // Update duration to 3s anim.duration.ms = 3000; // anim.duration.string -> "3s" // Update duration to 3s (alt.) anim.duration.string = "3s"; // anim.duration.ms -> 3000 // Reset to auto anim.duration.string = "auto"; // anim.duration.ms -> 5000
Your feedback is most welcome at public-fx@w3.org, subject [web-animations] ….
startTime
of type double, readonlyThe start time of this animation node in milliseconds. This is the time at which the parent animation group, if any, has scheduled this child to run within its transformed time space, that is, the animation node's inherited time space.
The start of the active interval is based on the sum of the start time and start delay.
duration
of type unrestricted double, readonlyThe iteration duration of this animation node.
Unlike the duration
attribute of
the AnimationTiming
interface or
AnimationTimingInput
dictionary,
this attribute returns the calculated value of the iteration
duration.
If timing.duration
is the
string auto
or any unsupported value, this attribute
will return the current calculated value of the intrinsic
iteration duration.
This value may be changed by setting the
duration
attribute of the
timing
member of this interface.
activeDuration
of type unrestricted double, readonlyThe active duration of this animation node.
endTime
of type unrestricted double, readonlyThe end time of the animation node expressed in milliseconds in inherited time space. This corresponds to the end of the animation node's active interval plus any end delay.
parent
of type AnimationGroup
, readonly, nullable
The parent animation group of this animation node or
null
if this animation node does not have
a parent animation group.
parentGroup
?
previousSibling
of type AnimationNode
, readonly, nullablenextSibling
of type AnimationNode
, readonly, nullableplayer
of type AnimationPlayer
, readonly, nullableThe player with which this animation node is associated, if any. This object can be used to perform play control such as pausing or rewinding on this animation node and all other animation nodes in the same hierarchy.
This will be null
if this animation node is
not associated with a player.
Feedback has been provided that suggests this reference causes the relationship between AnimationPlayers and AnimationNodes to be circular, which confuses the model. The player attribute should be considered at risk unless a strong use case for the reference arises.
before
Inserts nodes before this animation node.
HierarchyRequestError
exception and
terminate these steps.
Note that this definition precludes the following usage since
node
is an inclusive ancestor of itself:
node.before(node); // throws HierarchyRequestError
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
nodes | AnimationNode... | ✘ | ✘ |
void
after
Inserts nodes after this animation node.
HierarchyRequestError
exception and
terminate these steps.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
nodes | AnimationNode... | ✘ | ✘ |
void
replace
Replaces this AnimationNode
with the passed in
nodes.
HierarchyRequestError
exception and
terminate these steps.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
nodes | AnimationNode... | ✘ | ✘ |
void
remove
void
AnimationTiming
interface
Timing parameters for an AnimationNode
are collected together
under the AnimationTiming
type.
interface AnimationTiming {
attribute double delay;
attribute double endDelay;
attribute FillMode
fill;
attribute double iterationStart;
attribute unrestricted double iterations;
attribute (unrestricted double or DOMString) duration;
attribute double playbackRate;
attribute PlaybackDirection
direction;
attribute DOMString easing;
};
delay
of type doubleThe start delay which represents the number of milliseconds from an animation node's start time to the start of the active interval.
Now that we have endDelay
, should we change this back
to startDelay
?
endDelay
of type doubleThe end delay which represents the number of milliseconds from the end of an animation node's active interval until the start time of any animation node that may follow, for example, in an animation sequence.
fill
of type FillMode
The fill mode as specified by one of the FillMode
enumeration values.
When performing timing calculations the special value auto is expanded to one of the fill modes recognized by the timing model as follows,
iterationStart
of type doubleThe animation node's iteration start property.
A finite real number greater than or equal to zero representing the number of iterations into the animation node at which to begin. For example, a value of 0.5 would cause the animation node to begin half-way through the first iteration.
Values less than zero are clamped to zero for the purpose of timing model calculations.
Note that the value of iterations
is effectively
added to the iterationStart
such that
an animation node with an iterationStart
of
‘0.5’ and iterations
of
‘2’ would still repeat twice however it would begin
and end half-way through the animation node's iteration
interval.
Setting the iterationStart
to a value greater than
or equal to one is typically only useful in combination with an
animation effect that has an iteration composite
operation of ‘accumulate’.
iterations
of type unrestricted doubleThe animation node's iteration count property.
A real number greater than or equal to zero (including positive infinity) representing the number of times to repeat the animation node.
Values less than zero and NaN
values are treated as
the value 1.0 for the purpose of timing model calculations.
duration
of type (unrestricted double or DOMString)The iteration duration which is a real number greater than or equal to zero (including positive infinity) representing the time taken to complete a single iteration of the animation node.
The string value auto
is used to indicate that the
iteration duration reflects the animation node's
intrinsic iteration duration.
Real numbers less than zero, NaN
values, and strings
other than the lowercase value auto
are treated
the same as auto
for the purpose of timing model
calculations.
Should we allow strings such as "3s"
here?
i.e. a CSS <time>.
It might be useful for readability but introduces complexity when
handling this member (need to test the type, then possibly parse
the string).
It also introduces the issue of whether we should parse a full
clock
value.
playbackRate
of type doubleThe animation node's playback rate property.
This is a multiplier applied to the local time potentially causing the node to run at a different rate to its natural speed.
direction
of type PlaybackDirection
The playback direction of the animation node as
specified by one of the PlaybackDirection
enumeration
values.
easing
of type DOMStringThe timing function used to scale the time to produce easing effects.
The syntax of the string is defined by the following production:
"linear" | <cubic-bezier-timing-function> | <step-timing-function>
Unrecognized string values or values that correspond to
a timing function that is not supported for the type of
animation node to which this property is applied
are treated as if the linear
keyword was specified
for the purpose of timing model calculations.
easingList
similar to HTML's classList
.
AnimationTimingInput
dictionary
The AnimationTimingInput
dictionary is used as a convenience
for specifying the timing properties of an AnimationNode
in
bulk.
dictionary AnimationTimingInput {
double delay = 0;
double endDelay = 0;
FillMode
fill = "auto";
double iterationStart = 0.0;
unrestricted double iterations = 1.0;
(unrestricted double or DOMString) duration = "auto";
double playbackRate = 1.0;
PlaybackDirection
direction = "normal";
DOMString easing = "linear";
};
AnimationTimingInput
Membersdelay
of type double, defaulting to 0
The specified start delay.
See the description of the delay
attribute on
the AnimationTiming
interface.
endDelay
of type double, defaulting to 0
The specified end delay.
See the description of the endDelay
attribute on
the AnimationTiming
interface.
fill
of type FillMode
, defaulting to "auto"
The fill mode as specified by one of the FillMode
enumeration values.
iterationStart
of type double, defaulting to 0.0
The animation node's iteration start property.
See the description of the iterationStart
attribute
on the AnimationTiming
interface.
iterations
of type unrestricted double, defaulting to 1.0
The animation node's iteration count property.
See the description of the iterations
attribute
on the AnimationTiming
interface.
duration
of type (unrestricted double or DOMString), defaulting to "auto"
The iteration duration of the animation node.
See the description of the duration
attribute on the AnimationTiming
interface.
playbackRate
of type double, defaulting to 1.0
The animation node's playback rate property.
See the description of the playbackRate
attribute
on the AnimationTiming
interface.
direction
of type PlaybackDirection
, defaulting to "normal"
The playback direction of the animation node.
See the description of the direction
attribute
on the AnimationTiming
interface.
easing
of type DOMString, defaulting to "linear"
The timing function used to scale the time to produce easing effects.
See the description of the easing
attribute
on the AnimationTiming
interface.
FillMode
enumerationenum FillMode { "none", "forwards", "backwards", "both", "auto" };
none
forwards
backwards
both
auto
AnimationGroup
and no fill when applied to an
Animation
.
PlaybackDirection
enumerationenum PlaybackDirection { "normal", "reverse", "alternate", "alternate-reverse" };
normal
reverse
alternate
alternate-reverse
AnimationGroup
interface
Animation groups are represented by the AnimationGroup
interface.
[Constructor (sequence<AnimationNode
>? children,
optional (unrestricted double or AnimationTimingInput
) timing)]
interface AnimationGroup : AnimationNode
{
readonly attribute AnimationNodeList
children;
readonly attribute AnimationNode
? firstChild;
readonly attribute AnimationNode
? lastChild;
void prepend (AnimationNode... nodes);
void append (AnimationNode... nodes);
AnimationGroup
clone ();
};
AnimationGroup
Creates a new AnimationGroup
object using the following
procedure:
AnimationGroup
object,
group.AnimationTimingInput
object,double
,AnimationTimingInput
object with all members set to
their default values and duration
set to
timing.
AnimationTimingInput
object with all members set to
their default values.
group.timing
to a new
AnimationTiming
object whose attributes are assigned the
value of the member of the same name on timing input.
The above two steps are identical with the constructor for Animation
and should be
factored out somewhere.
null
.
Note that since AnimationTiming
objects have the same
member names as AnimationTimingInput
dictionaries, it is
also possible to pass the timing
member of another
AnimationNode
as the timing parameter.
Doing so will cause the AnimationTiming
object to be
treated as an AnimationTimingInput
dictionary and thus it
will effectively be cloned, not shared.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
children | sequence< | ✔ | ✘ |
A sequence of animation nodes to add as children of this group.
These children are appended in sequence using the same
semantics as the |
timing | (unrestricted double or | ✘ | ✔ |
The timing properties or iteration duration of the new animation group. |
children
of type AnimationNodeList
, readonlyfirstChild
of type AnimationNode
, readonly, nullablelastChild
of type AnimationNode
, readonly, nullableprepend
HierarchyRequestError
exception and
terminate these steps.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
nodes | AnimationNode... | ✘ | ✘ |
void
append
HierarchyRequestError
exception and
terminate these steps.
null
.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
nodes | AnimationNode... | ✘ | ✘ |
void
clone
Creates a deep copy of this AnimationGroup
object using the
following procedure.
AnimationGroup
object,
the object to be cloned.
AnimationTimingInput
object whose members are assigned
the value of the attribute with the same name on
source.timing
.
AnimationNode
objects.
source.children
, append the result
of calling child.clone()
to cloned children.
AnimationGroup
object created by
calling the AnimationGroup
constructor with parameters
AnimationGroup(cloned children,
cloned timing)
.
AnimationGroup
The next sibling of node not included in a set of animation nodes, nodes is determined using the following steps:
null
perform the following steps:
null
.
To remove a node from its parent animation group or player, perform the steps corresponding to the first matching condition from below, if any:
To insert a series of zero or more animation nodes, nodes, to parent's list of child animation nodes before reference child perform the following steps for each node in nodes:
AnimationNodeList
interface
A list of animation nodes may be represented by
an AnimationNodeList
.
The AnimationNodeList
interface supports indexed
properties with indices in the range 0 ≤ index <
length
.
The only reason this interface exists is to provide a familiar
experience for authors familiar with DOM interfaces where child nodes
are accessed via a children
member.
interface AnimationNodeList {
readonly attribute unsigned long length;
getter AnimationNode
? item (unsigned long index);
};
length
of type unsigned long, readonlyitem
[index]
Returns the animation node at index
.
If index
is greater than or equal to
length
returns null
.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
index | unsigned long | ✘ | ✘ |
AnimationNode
, nullableAnimationSequence
interface
Animation sequences are represented by the
AnimationSequence
interface.
[Constructor (sequence<AnimationNode
>? children,
optional (unrestricted double or AnimationTimingInput
) timing)]
interface AnimationSequence : AnimationGroup
{
AnimationSequence
clone ();
};
AnimationSequence
AnimationGroup
.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
children | sequence< | ✔ | ✘ | |
timing | (unrestricted double or | ✘ | ✔ |
clone
Creates a deep copy of this AnimationSequence
object using
the same procedure as defined for AnimationGroup.clone
except that a new AnimationSequence
object is created.
AnimationSequence
Animation
interface
Animations are represented by the
Animation
interface.
[Constructor (Animatable
? target, object? effect,
optional (unrestricted double or AnimationTimingInput)
timing)]
interface Animation : AnimationNode
{
attribute (AnimationEffect
or EffectCallback
)? effect;
attribute Animatable
? target;
Animation
clone ();
};
Animation
Creates a new Animation
object
using the following procedure:
Animation
object, animation.AnimationTimingInput
object,double
,AnimationTimingInput
object with all members set to
their default values and duration
set to
timing.
AnimationTimingInput
object with all members set to
their default values.
animation.timing
to a new
AnimationTiming
object whose attributes are assigned the
value of the member of the same name on timing input.
animation.effect
to
the result of applying the procedure for converting an effect
to an IDL value to effect.
Examples of the usage of this constructor are given in section 5.9.5 Creating a new Animation object.
Note that as with the
constructor for AnimationGroup
s
it is possible to pass in an AnimationTiming
object here
(e.g. the timing
member of another
AnimationNode
) in which case it will be cloned.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
target |
| ✔ | ✘ |
The animation target or target pseudo-element.
This may be null for animations that do not target
a specific element.
|
effect | object | ✔ | ✘ |
The animation effect used to set the The processing of this parameter is defined normatively in section 5.9.4 Processing the effect parameter. Following is a non-normative summary of this handing. effect may be one of the following:
If this parameter is an
If this parameter is of type
If this parameter is |
timing | (unrestricted double or AnimationTimingInput)
| ✘ | ✔ |
The timing properties or iteration duration of the new animation. |
effect
of type (AnimationEffect
or EffectCallback
), nullable
The animation effect or custom effect to apply.
May be null
in which case the animation will produce
no observable effect.
On setting, if the previous value was an EffectCallback
, we
should call the old callback with a null time fraction so it can
clear its result.
target
of type Animatable
, nullable
The element or pseudo-element being animated by this object.
This may be null
for animations that do not target
a specific element such as an animation that produces a sound
using an audio API.
clone
Creates a copy of this Animation
object using the following procedure.
Animation
object to
clone, that is, this object.AnimationTimingInput
object whose members are assigned
the value of the attribute with the same name on
source.timing
.AnimationEffect
is cloned depending on the type of
source.effect
as follows,
source.effect
is an
Animation object,source.effect.clone()
.
source.effect
is an
EffectCallback
object,source.effect
.
null
.
Animation(source.target, cloned
effect, cloned timing)
.Animation
The effect parameter, an ECMAScript value passed to the
Animation
constructor or to the
animate
operation of the Animatable
interface,
may specify an EffectCallback
, an AnimationEffect
,
a Keyframe a sequence of Keyframes, or null.
However, since callback functions and dictionaries are not
distinguishable in WebIDL, we define the processing of this
parameter for ECMAScript here in prose.
The procedure for converting an effect to an IDL value with parameter effect is as follows:
AnimationEffect
,EffectCallback
as the
callback function type.
KeyframeEffect
object constructed passing
effect as the frames parameter.
Note that since the processing of this parameter is defined in prose, the above steps will take place after any coercion is applied to other parameters passed to the same operation.
Animation
objectThis section is non-normative.
The Animation constructor offers a number of approaches to creating a new Animation object. At its simplest, an Animation object that changes the ‘left’ property of elem to 100px over three seconds can be achieved as follows:
var anim = new Animation(elem, { left: '100px' }, 3000);
The second parameter, representing the animation effect, may
specify multiple properties, an AnimationEffect
object, or
even a callback function.
// Specify multiple properties at once var animA = new Animation(elem, { left: '100px', top: '300px' }, 3000); // Specify multiple frames var animB = new Animation(elem, [ { left: '100px' }, { left: '300px' } ], 3000); // Share the animation effect of another animation var animC = new Animation(elem, animB.effect, 3000); // Supply a specialized animation effect var animD = new Animation(elem, new MotionPathEffect("M100 250C100 50 400 50 400 250"), 3000); // Supply a custom script-based animation effect var animE = new Animation(elem, function(time) { // (Normally we should check for time===null, but in this case it produces // the correct result anyway) document.documentElement.currentScale = 1.0 + time * 2.0; }, 3000);
The third parameter representing the animation's timing, may
simply be a number representing the iteration duration in
milliseconds as above, or, to specify further timing properties such
as the playback rate,
an AnimationTimingInput
object can be used as follows:
var anim = new Animation(elem, { left: '100px' }, { duration: 3000, playbackRate: 2 });
If the duration is not specified, the intrinsic iteration duration is used which, for an animation is zero. It is possible to create an animation that simply sets a property without any interpolation as follows:
new Animation(elem, { display: 'none' }, { fill: 'forwards' });
This is particularly useful in combination with other animations or animation nodes. For example, fading an element before switching ‘display’ to ‘none’ can be achieved as follows,
new AnimationSequence( [ new Animation(elem, { opacity: 0 }, 1000), new Animation(elem, { display: 'none' }, { fill: 'forwards' }) ] );
Having created an Animation
, it
can be played using
document.timeline.play(anim)
.
For simple effects, however, the Element.animate
shortcut is more convenient since it performs this last step
automatically. For example,
elem.animate({ left: '100px' }, 3000);
Animatable
interface
Objects that may be the target of an Animation
implement the
Animatable
interface.
[NoInterfaceObject]
interface Animatable {
AnimationPlayer
animate (object? effect,
optional (double or AnimationTimingInput
) timing);
sequence<Animation
> getCurrentAnimations ();
sequence<AnimationPlayer
> getAnimationPlayers ();
};
animate
Creates a new Animation
object
whose animation target is the object on which the method is
called, and calls
the play
method of the AnimationTimeline
object of
the document timeline of the node
document [DOM4] of the element passing the newly created
Animation
as the argument to
the method.
The following code fragment:
var anim = elem.animate({ opacity: 0 }, 2000);
is equivalent to:
var anim = new Animation(elem, { opacity: 0 }, 2000); elem.ownerDocument.timeline.play(anim);
Returns the AnimationPlayer
object returned by the
play
method of the AnimationTimeline
.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
effect | object | ✔ | ✘ | The effect to apply. This value is passed to the Animation constructor as the effect parameter and has the same interpretation as defined for that constructor. |
timing | (double or | ✘ | ✔ | The timing parameters of the animation. This value is passed to the Animation constructor as the timing parameter and has the same interpretation as defined for that constructor. |
AnimationPlayer
getCurrentAnimations
Returns the set of current Animation
objects that have an animation
effect whose animation target is this object.
The returned list of Animation
objects is sorted by their associated animation effect
using the procedure defined for sorting animation effects
in section 4.2.1 The animation stack.
Note that the definition of a current animation does not include those animations whose local time falls after the active interval but which are still in effect due to a fill mode. As a result such animations are not returned by this method.
This is because in order to return such animations, user agents would be required to maintain all animations with a forwards fill indefinitely. As a result the resources consumed by an animated document would steadily accumulate over time.
Note that when called on Element
objects, the list of
returned Animation
s will
not include those animations whose target is
a PseudoElement
associated with the
Element
since PseudoElement
and
Element
are treated as independent Animatable
objects.
Feedback has been provided that suggests direct references from AnimationNode objects to AnimationPlayers generate circular reference and confuse the model. Without this reference, getCurrentAnimations is not very useful, as the returned AnimationNodes can't be used to effect play control. In the absence of a strong use case for a reference from AnimationNode to AnimationPlayer, this feature should be considered at risk.
sequence<Animation
>
getAnimationPlayers
Returns the set of AnimationPlayer
objects
whose source content is current and contains at
least one animation whose animation target is this
object.
If this object is the animation target of two or more animations which are associated with the
same player, the corresponding AnimationPlayer
object will still only appear in the returned list once.
The returned list is sorted in increasing order by player sequence number.
sequence<AnimationPlayer
>
AnimationEffect
interface
Animation effects are represented by
the AnimationEffect
interface.
AnimationEffect
is an abstract interface of which several
concrete subinterfaces are provided.
interface AnimationEffect {
attribute IterationCompositeOperation
iterationComposite;
attribute CompositeOperation
composite;
AnimationEffect
clone ();
};
iterationComposite
of type IterationCompositeOperation
The iteration composite operation property of this
animation effect as specified by one of the
IterationCompositeOperation
enumeration values.
composite
of type CompositeOperation
The composite operation used to composite this
animation effect with the animation stack, as
specified by one of the CompositeOperation
enumeration
values.
clone
Creates and returns a new object of the same type as this object's most-derived interface such that it will produce the same output as this object.
We either need a more rigorous definition here or (probably better) a sets of steps on a per-subclass basis.
AnimationEffect
any sample (double? timeFraction,
double currentIteration, Animatable? target, any
underlyingValue)
so that the animation effects can be driven
apart from the timing model.
IterationCompositeOperation
enumeration
The possible values of an animation effect's
iteration composite operation are represented by the
IterationCompositeOperation
enumeration.
enum IterationCompositeOperation { "replace", "accumulate" };
replace
accumulate
CompositeOperation
enumeration
The possible values of an animation effect's
composition behavior are represented by the
CompositeOperation
enumeration.
enum CompositeOperation { "replace", "add", "accumulate" };
replace
add
accumulate
KeyframeEffect
interface
Keyframe animation effects are represented by the
KeyframeEffect
interface.
[Constructor (object frames, optional KeyframeEffectOptions
options)]
interface KeyframeEffect : AnimationEffect
{
attribute DOMString spacing;
sequence<ComputedKeyframe
> getFrames ();
void setFrames (object frames);
};
KeyframeEffect
Creates a new KeyframeEffect
object for the
given set of keyframes.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
frames | object | ✘ | ✘ |
A Keyframe object or sequence
of Keyframe objects used for
calculating animation values for this animation effect.
The constraints on this parameter and its processing are
identical to those for setFrames .
|
options |
| ✘ | ✔ |
A KeyframeEffectOptions dictionary defining other aspects
of the animation effect's behavior.
If this parameter is not provided, the default values of the
dictionary are used.
|
spacing
of type DOMStringThe spacing mode to use for this animation effect.
Recognized values are defined by the following grammar:
distribute | paced({ident}) | paced
{ident}
here is an identifier
as defined by CSS3 Values [CSS3-VALUES].
The meaning of each value is as follows:
Use the paced keyframe spacing mode with the property
name indicated by {ident}
as the paced
property.
For example, paced(transform)
would indicate that
the keyframes should be spaced such that changes to the transform property occur at
a constant rate.
Use the paced keyframe spacing mode.
The paced property to use is the first property specified in the first keyframe in the list of keyframes associated with this animation effect when sorting the CSS property names in ascending order by Unicode codepoint.
As a result, changes to the keyframes may cause the paced property to change.
MotionPathEffect
and as a convenience for keyframe animation effects
that specify only one property.
All other values are treated as "distribute" for the purpose of animation model calculations.
getFrames
Returns the keyframes that make up this effect as
a sequence of ComputedKeyframe
objects.
The value returned differs from the frames parameter
passed into setFrames
or the constructor for this
interface in the following ways:
Keyframe
object to be replaced
with a sequence.
computedOffset
member of each frame.
sequence<ComputedKeyframe
>
setFrames
A Keyframe
object or sequence
of Keyframe
objects used to
replace the set of keyframes that make up this effect.
The processing of the frames parameter is defined in section 5.14.4 Processing a sequence of Keyframe objects or a single item.
Subsequently, the resulting sequence of Keyframe
objects is normalized
using the procedure in section 5.14.6 Normalizing a sequence of keyframes before storing.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
frames | object | ✘ | ✘ |
void
Keyframe
objects or a single item
WebIDL does not currently make a dictionary and a sequence
distinguishable but it was felt that allowing both was important
for useability of the animate
operation on
Animatable
.
Therefore, we define the processing for handling a parameter
that may be either a single Keyframe
dictionary object, or
a sequence of such objects.
The procedure for converting an ECMAScript value into an IDL keyframe or sequence of keyframes with parameter keyframeOrKeyframeList is as follows:
Array.isArray
[ECMA-262],
Array.isArray(keyframeOrKeyframeList) is
true,
Should this be defined in terms of IsIterable
instead?
KeyframeEffectOptions
dictionary
Additional parameters may be passed to the KeyframeEffect
constructor by providing a KeyframeEffectOptions
object.
dictionary KeyframeEffectOptions {
IterationCompositeOperation
iterationComposite = "replace";
CompositeOperation
composite = "replace";
DOMString spacing = "distribute";
};
KeyframeEffectOptions
MembersiterationComposite
of type IterationCompositeOperation
, defaulting to "replace"
composite
of type CompositeOperation
, defaulting to "replace"
CompositeOperation
enumeration values.
This is used for all keyframes that do not specify
a composite operation.
spacing
of type DOMString, defaulting to "distribute"
The spacing mode to apply to this animation effect's keyframes.
See the description of the spacing
attribute of the
KeyframeEffect
interface for the recognized values and
their meaning are described
Unrecognized values are set on the created KeyframeEffect
object, but are treated as "distribute" for the purpose of
animation model calculations.
For each call to setFrames
or the KeyframeEffect
constructor, the following normalization is performed on the passed
in frames parameter before storing its value.
Note that the processing of the ECMAScript value into a suitable IDL value defined in section 5.15.2 Processing a Keyframe object is performed before this operation is initiated.
Keyframe
object, replaces frames with
a new sequence with a single item that is the previous value of
frames.
Keyframe
has
a non-null offset
,offset
.InvalidModificationError
.Keyframe
objects in frames whose offset
member is
non-null and less than zero, remove all keyframes
objects from the start of frames up to and including
the keyframe with the largest non-null offset
that is still less than zero.
Keyframe
objects in
frames whose offset
member is non-null
and greater than one, remove all keyframes from
the keyframe with the smallest non-null offset
that is still greater than one until the end of
frames.
Need to define what invalid means here.
Keyframe
dictionary
Individual keyframes are represented by a special kind of
Keyframe
dictionary type whose
members map to the properties to be animated.
At the time of writing, this kind of open-ended dictionary cannot
be represented using WebIDL and hence special
ECMAScript-specific handling for this type is defined in
section 5.15.2 Processing a Keyframe object.
No handling is defined for other languages.
dictionary Keyframe {
// ... property-value pairs ...
double? offset = null;
DOMString easing = "linear";
CompositeOperation
? composite = null;
};
Keyframe
Membersoffset
of type double, nullable, defaulting to null
The keyframe offset of the keyframe specified as
a number between 0.0 and 1.0 inclusive or null
.
Keyframes with offsets outside the range [0.0, 1.0] are ignored when calculating animation values as defined in section 5.14.6 Normalizing a sequence of keyframes.
A null
value indicates that the keyframe
should be positioned using the keyframe animation effect's
keyframe spacing mode.
easing
of type DOMString, defaulting to "linear"
The timing function used to transform the progress of time from this keyframe until the next keyframe in the series.
The syntax and error-handling associated with parsing this string
is identical to that defined for the easing
attribute
of the AnimationTiming
interface.
composite
of type CompositeOperation
, nullable, defaulting to null
The composite operation used to combine the values specified in this keyframe with the underlying value.
If null
, the composite operation
specified on the AnimationEffect
will be used.
Keyframe
object
Since accessing the properties of an ECMAScript user object can
have side effects, the manner in which these properties is
accessed is important.
In light of this consideration the procedure for converting an
ECMAScript object into an IDL Keyframe
object has the following
properties:
The procedure for converting an ECMAScript value to an IDL Keyframe object with parameter keyframe input is as follows:
Keyframe
object with the
offset
, easing
and
composite
attributes set to the default dictionary
values.
offset
member of keyframe
result to the result of applying the procedure for
converting an ECMAScript value into an IDL double
[WEBIDL] to the result of calling the [[Get]]
internal method on keyframe input with property
name 'offset'.
Set the easing
member of keyframe
result to the result of applying the procedure
for converting an ECMAScript value to an IDL
DOMString value [WEBIDL] with the [TreatNullAs=EmptyString]
annotation in effect, to the result of calling
the [[Get]] internal method of keyframe
input with property name 'easing'.
If the resulting string does not conform to the
grammar defined for the easing
attribute of the AnimationTiming
interface or
is not supported by the implementation, then
set the easing
of keyframe result
to the string “linear”.
composite
member of keyframe
result to the result applying the
procedure for converting an ECMAScript value to an IDL
enumeration type [WEBIDL] with
CompositeOperation
as the enumeration type, to
the result of calling the [[Get]] internal method on
keyframe input with property name 'composite'.
I'd like to remove this step. Prefixes are history.
ToString
on the value returned from the
[[Get]] method of keyframe input with property
name, name.
If [[Get]] returns null or undefined, let the member
value be an empty string.
The above algorithm gives special meaning to the property names 'offset', 'computedOffset', 'easing', and 'composite'. If a CSS property called 'offset' or 'composite' is ever introduced it will clash with the meaning here.
We have a few options:
cssOffset
.
ComputedKeyframe
dictionary
Keyframes returned by
are represented using
KeyframeEffect
.getFramesComputedKeyframe
dictionary objects.
dictionary ComputedKeyframe : Keyframe
{
double computedOffset;
};
ComputedKeyframe
MemberscomputedOffset
of type doubleMotionPathEffect
interface
Motion path animation effects are
represented by the MotionPathEffect
interface.
[Constructor ((DOMString or SVGPathSegList) path, optional MotionPathEffectOptions
options)]
interface MotionPathEffect : AnimationEffect
{
attribute SVGPathSegList segments;
attribute AutoRotationMode
autoRotate;
attribute double angle;
attribute DOMString spacing;
};
MotionPathEffect
Creates a new MotionPathEffect
object with the specified
parameters.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
path | (DOMString or SVGPathSegList) | ✘ | ✘ |
The motion path which defines the course the animation target follows. A string may be provided specifying the path using the syntax for SVG path data [SVG2].
If a string is provided, it is converted into an
The resulting SVGPathSegList is assigned to the
|
options |
| ✘ | ✔ |
A MotionPathEffectOptions dictionary defining other
aspects of the animation effect's behavior.
If this parameter is not provided, the default values of the
dictionary are used.
|
segments
of type SVGPathSegListautoRotate
of type AutoRotationMode
angle
of type doublespacing
of type DOMStringThe motion path spacing mode to use for this animation effect.
Recognized values are defined by the following grammar:
distribute | paced
The meaning of each value is as follows:
All other values are treated as "paced" for the purpose of animation model calculations.
MotionPathEffectOptions
dictionary
Additional parameters may be passed to the MotionPathEffect
constructor by providing a MotionPathEffectOptions
object.
dictionary MotionPathEffectOptions {
AutoRotationMode
autoRotate = "none";
double angle = 0;
IterationCompositeOperation
iterationComposite = "replace";
CompositeOperation
composite = "replace";
DOMString spacing = "paced";
};
MotionPathEffectOptions
MembersautoRotate
of type AutoRotationMode
, defaulting to "none"
angle
of type double, defaulting to 0
iterationComposite
of type IterationCompositeOperation
, defaulting to "replace"
composite
of type CompositeOperation
, defaulting to "replace"
CompositeOperation
enumeration
values.
spacing
of type DOMString, defaulting to "paced"
The spacing mode to apply to this motion path animation effect.
See the description of the spacing
attribute of the
MotionPathEffect
interface for the recognized values and
their meaning are described
Unrecognized values are set on the created
MotionPathEffect
object, but are treated as "paced" for
the purpose of animation model calculations.
AutoRotationMode
enumeration
The values of the automatic rotation flag of a motion path
animation effect are represented by the AutoRotationMode
enumeration.
enum AutoRotationMode { "auto-rotate", "none" };
auto-rotate
none
EffectCallback
callback function
Custom effects can be defined in script by providing an
EffectCallback
callback function.
callback EffectCallback = void (double? timeFraction, Animatable
currentTarget, Animation
animation);
An EffectCallback
is called each time an Animation
with which it is
associated is sampled.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
timeFraction | double | ✔ | ✘ |
The time fraction for which to produce an effect.
When this is null , the function should
remove the effect.
|
currentTarget |
| ✘ | ✘ |
The animation target on which this callback is expected to operate.
Note that currentTarget may differ from
If the animation target of animation is changed between samples, this method will be called once with a null timeFraction and the previous animation target as the currentTarget, then again with the current timeFraction and the updated animation target as the currentTarget. This allows the animation effect to be removed from the old animation target. |
animation |
| ✘ | ✘ |
The Animation object that is
being sampled.
|
void
AnimationPlayerEvent
interface
Player events are represented in the API by the
AnimationPlayerEvent
interface.
[Constructor (DOMString type, optional AnimationPlayerEventInit
eventInit)]
interface AnimationPlayerEvent : Event {
attribute double? currentTime;
attribute double? timelineTime;
};
AnimationPlayerEvent
AnimationPlayerEvent
object as described in
Constructing
events in [DOM4].
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
type | DOMString | ✘ | ✘ | The type of player event corresponding to one of the types defined in section 3.5.4.1 Types of player events. |
eventInit |
| ✘ | ✔ |
The parameters of the new AnimationPlayerEvent .
|
currentTime
of type double, nullabletimelineTime
of type double, nullable
The AnimationPlayerEventInit
dictionary type is used to specify
the parameters when constructing an AnimationPlayerEvent
object.
dictionary AnimationPlayerEventInit {
double? currentTime = null;
double? timelineTime = null;
};
AnimationPlayerEventInit
MemberscurrentTime
of type double, nullable, defaulting to null
timelineTime
of type double, nullable, defaulting to null
Document
interfaceThe following extensions are made to the Document interface defined in [DOM4].
partial interface Document {
readonly attribute AnimationTimeline
timeline;
};
timeline
of type AnimationTimeline
, readonlyAnimationTimeline
object representing
the document timeline.
Element
interfaceSince DOM Elements may be the target of an animation, the Element interface [DOM4] is extended as follows:
Element implements Animatable
;
This allows the following kind of usage.
elem.animate({ color: 'red' }, 2000);
PseudoElement
interface
Since animations may also target
pseudo-elements, the PseudoElement
interface [CSSOM] is also defined to be animatable.
PseudoElement implements Animatable
;
This interface is marked at-risk in the 5 December 2013 WD of CSSOM. If it is removed, we will need to provide an equivalent definition here.
The interaction between script execution and the state and effects of the Web Animations model is as follows:
Changes made to the Web Animations model via the programming interface are reflected immediately in the values returned by the interfaces defined in this specification.
Similarly, methods that operate on the current state of the model such as pausing or reversing are applied to a fully-updated timing model, that is, after all previous modifications have been incorporated.
This section is non-normative.
For example, if the AnimationPlayer
associated with an
Animation
is seeked via the programming interface,
the value returned when querying the
animation's startTime
will reflect updated state of
the model immediately.
// Initially player.src.localTime is 3000 player.currentTime += 2000; alert(player.src.localTime); // Displays '5000'
The same concept applies to more complex modifications of the
Web Animations model such as adding and removing children from
an AnimationGroup
.
Querying the computed style of a property affected by animation, or the value of an attribute affected by animation, returns the value based the current state of the model, that is, after incorporating any modifications made using the programming interface.
This section is non-normative.
For example, if the used style of an element is queried immediately after applying a new Animation to that element, the result of the new animation will be incorporated in the value returned.
// Set opacity to 0 immediately elem.animate({ opacity: 0 }, { fill: 'forwards' }); alert(window.getComputedStyle(elem).opacity); // Displays '0'
The means of querying the animated value of an attribute depends on the interface defined for the attribute. SVG 1.1 [SVG11] defines an additional interface for querying animated values.
// Set width to 0 immediately rect.animate({ width: '100px' }, { fill: 'forwards' }); alert(rect.width.animVal.value); // Displays '100'
Changes made to the model using the programming interface do
not cause any EffectCallback
functions to be
called.
This section is non-normative.
For example, in the following code, the callback function will not be called until after the script block has completed during regular sampling.
var timesCalled = 0; elem.animate(function() { timesCalled++; }, 10000); alert(timesCalled); // Displays '0'
Changes to specified style, specified attribute values, and the state of the Web Animations model made within the same execution block must be synchronized when rendering such that the whole set of changes is rendered together.
This section is non-normative.
For example, a user agent must not render only the changes to specified style made in a script execution block whilst ignoring changes to animations. This guarantees that the following usage will never produce a situation where only the change to specified style is rendered without the animation.
// Fade the opacity with fallback for browsers that don't // support Element.animate elem.style.opacity = '0'; elem.animate([ { opacity: 1 }, { opacity: 0 } ], 500);
Note that a user agent may render a frame with none of the changes made in a script execution block. This might happen, for example, if rendering occurs in a separate process that is scheduled to run shortly after a script execution block completes but before changes made via script can be communicated to the process.
The value returned by the currentTime
attribute of
a document timeline will not change within a script block.
This section is non-normative.
For example, querying the currentTime
twice within
a long block of code that is executed in the same script block
will return the same value as shown in the following example.
var a = document.timeline.currentTime; // ... many lines of code ... var b = document.timeline.currentTime; alert(b - a); // Displays 0
User agents that support Timing control for script-based animations [RAF], prior to sampling animation frame request callbacks for a given top-level browsing context, must perform a sample including executing any eligible custom effects (see section 4.5.1 Sampling custom effects) for all animation nodes associated with a timeline that is the document timeline of the active document of the top-level browsing context or of any of its descendant browsing contexts. When performing this sample, the time value of each document timeline must be equal to the time passed to animation frame request callbacks for that browsing context.
This section is non-normative.
As a result of this definition, the time passed to
a requestAnimationFrame
callback acts as
an alias for document.timeline.currentTime
.
window.requestAnimationFrame(function(sampleTime) { // Displays '0' alert(sampleTime - document.timeline.currentTime); });
The Media Fragments specification [MEDIA-FRAGMENTS] defines a means for addressing a temporal range of a media resource. The application of media fragments depends on the MIME type of the resource on which they are specified. For resources with the SVG MIME type [SVG11], the application of temporal parameters is defined in the Animation elements specification.
Note that media fragments are defined to operate on resources based on their MIME type. As a result, temporal addressing may not be supported in all situations where Web Animations content is used.
HTML permits user agents to store user-agent defined state along with a session history entry so that as a user navigates between pages, the previous state of the page can be restored including state such as scroll position [HTML5].
User agents that pause and resume media elements when the referencing document is unloaded and traversed, are encouraged to apply consistent handling to documents containing Web Animations content. If provided, this behavior should be achieved by adjusting the time values of any timelines bound to the global clock.
Is this at odds with those time values being relative to
navigationStart
and with requestAnimationFrame
using the same time as document.timeline.currentTime
?
The internal representation of time values is implementation dependant however, it is recommended that user agents be able to represent input time values with microsecond precision so that 0.000001 is distinguishable from 0.0.
This specification defines an abstract model for animation and, as such, for user agents that do not support scripting, there are no conformance criteria since there is no testable surface area.
User agents that do not support scripting, however, may implement additional technologies defined in terms of this specification in which case the definitions provided in this specification will form part of the conformance criteria of the additional technology.
A conforming scripted Web Animations user agent is a user agent that implements the API defined in section 5. Programming interface including dispatching events as defined in section 3.5.4 Player events.
interface AnimationTimeline { readonly attribute double? currentTime;AnimationPlayer
play (optionalAnimationNode
? source = null); sequence<AnimationPlayer
> getAnimationPlayers (); }; interface AnimationPlayer : EventTarget { attributeAnimationNode
? source; readonly attributeAnimationTimeline
timeline; attribute double startTime; attribute double currentTime; attribute double playbackRate; readonly attribute boolean paused; readonly attribute boolean finished; void cancel (); void finish (); void play (); void pause (); void reverse (); // Event callbacks attribute EventHandler onfinish; }; interface AnimationNode { // Playback state readonly attribute double? localTime; readonly attribute unsigned long? currentIteration; // Specified timing readonly attributeAnimationTiming
timing; // Calculated timing readonly attribute double startTime; readonly attribute unrestricted double duration; readonly attribute unrestricted double activeDuration; readonly attribute unrestricted double endTime; // Timing hierarchy readonly attributeAnimationGroup
? parent; readonly attributeAnimationNode
? previousSibling; readonly attributeAnimationNode
? nextSibling; void before (AnimationNode... nodes); void after (AnimationNode... nodes); void replace (AnimationNode... nodes); void remove (); // Associated player readonly attributeAnimationPlayer
? player; }; interface AnimationTiming { attribute double delay; attribute double endDelay; attributeFillMode
fill; attribute double iterationStart; attribute unrestricted double iterations; attribute (unrestricted double or DOMString) duration; attribute double playbackRate; attributePlaybackDirection
direction; attribute DOMString easing; }; dictionary AnimationTimingInput { double delay = 0; double endDelay = 0;FillMode
fill = "auto"; double iterationStart = 0.0; unrestricted double iterations = 1.0; (unrestricted double or DOMString) duration = "auto"; double playbackRate = 1.0;PlaybackDirection
direction = "normal"; DOMString easing = "linear"; }; enum FillMode { "none", "forwards", "backwards", "both", "auto" }; enum PlaybackDirection { "normal", "reverse", "alternate", "alternate-reverse" }; [Constructor (sequence<AnimationNode
>? children, optional (unrestricted double orAnimationTimingInput
) timing)] interface AnimationGroup :AnimationNode
{ readonly attributeAnimationNodeList
children; readonly attributeAnimationNode
? firstChild; readonly attributeAnimationNode
? lastChild; void prepend (AnimationNode... nodes); void append (AnimationNode... nodes);AnimationGroup
clone (); }; interface AnimationNodeList { readonly attribute unsigned long length; getterAnimationNode
? item (unsigned long index); }; [Constructor (sequence<AnimationNode
>? children, optional (unrestricted double orAnimationTimingInput
) timing)] interface AnimationSequence :AnimationGroup
{AnimationSequence
clone (); }; [Constructor (Animatable
? target, object? effect, optional (unrestricted double or AnimationTimingInput) timing)] interface Animation :AnimationNode
{ attribute (AnimationEffect
orEffectCallback
)? effect; attributeAnimatable
? target;Animation
clone (); }; [NoInterfaceObject] interface Animatable {AnimationPlayer
animate (object? effect, optional (double orAnimationTimingInput
) timing); sequence<Animation
> getCurrentAnimations (); sequence<AnimationPlayer
> getAnimationPlayers (); }; interface AnimationEffect { attributeIterationCompositeOperation
iterationComposite; attributeCompositeOperation
composite;AnimationEffect
clone (); }; enum IterationCompositeOperation { "replace", "accumulate" }; enum CompositeOperation { "replace", "add", "accumulate" }; [Constructor (object frames, optionalKeyframeEffectOptions
options)] interface KeyframeEffect :AnimationEffect
{ attribute DOMString spacing; sequence<ComputedKeyframe
> getFrames (); void setFrames (object frames); }; dictionary KeyframeEffectOptions {IterationCompositeOperation
iterationComposite = "replace";CompositeOperation
composite = "replace"; DOMString spacing = "distribute"; }; dictionary Keyframe { // ... property-value pairs ... double? offset = null; DOMString easing = "linear";CompositeOperation
? composite = null; }; dictionary ComputedKeyframe :Keyframe
{ double computedOffset; }; [Constructor ((DOMString or SVGPathSegList) path, optionalMotionPathEffectOptions
options)] interface MotionPathEffect :AnimationEffect
{ attribute SVGPathSegList segments; attributeAutoRotationMode
autoRotate; attribute double angle; attribute DOMString spacing; }; dictionary MotionPathEffectOptions {AutoRotationMode
autoRotate = "none"; double angle = 0;IterationCompositeOperation
iterationComposite = "replace";CompositeOperation
composite = "replace"; DOMString spacing = "paced"; }; enum AutoRotationMode { "auto-rotate", "none" }; callback EffectCallback = void (double? timeFraction,Animatable
currentTarget,Animation
animation); [Constructor (DOMString type, optionalAnimationPlayerEventInit
eventInit)] interface AnimationPlayerEvent : Event { attribute double? currentTime; attribute double? timelineTime; }; dictionary AnimationPlayerEventInit { double? currentTime = null; double? timelineTime = null; }; partial interface Document { readonly attributeAnimationTimeline
timeline; }; Element implementsAnimatable
; PseudoElement implementsAnimatable
;
Thank you to Michiel “Pomax” Kamermans for help with the equations for a proposed smooth timing function although this feature has been deferred to a subsequent specification.
Our deep gratitude goes out to Southern Star Animation for their kind generosity and patience in introducing the editors to the processes and techniques used producing broadcast animations.
The following changes have been made since the 25 June 2013 Working Draft.
navigationStart
moment defined by [NAVIGATION-TIMING].
animateMotion
element.
Timeline
interface to
AnimationTimeline
.
toTimelineTime
from the
AnimationTimeline
interface.
getCurrentPlayers
on the
AnimationTimeline
interface to
getAnimationPlayers
.
Player
interface to AnimationPlayer
.
onfinish
to the AnimationPlayer
interface
as the event handler for the new finish player event and made
the AnimationPlayer
interface inherit from
EventTarget
.
AnimationPlayer
interface:
finished
cancel()
finish()
play()
pause()
reverse()
paused
member of the AnimationPlayer
interface readonly.
TimedItem
interface to
AnimationNode
.
AnimationNode
since timing
events have been replaced with player events.
Similarly, made the AnimationNode
interface no longer
inherit from EventTarget
.
AnimationNode
.player
as at risk.
specified
attribute on
AnimationNode
to timing
.
Timing
interface to AnimationTiming
and likewise the TimingInput
dictionary to
AnimationTimingInput
.
AnimationTiming
interface and AnimationTimingInput
dictionary:
iterationDuration
→ duration
startDelay
→ delay
fillMode
→ fill
iterationCount
→ iterations
timingFunction
→ easing
activeDuration
member of the
AnimationTimingInput
dictionary and AnimationTiming
interface and introduced endDelay
to both.
FillMode
and made it the default value for fill
on AnimationTimingInput
.
TimingGroup
interface and
renamed ParGroup
to AnimationGroup
.
SeqGroup
to AnimationSequence
and made
it inherit from AnimationGroup
.
Animation
constructor and
the Animatable
.animate
method to
object?
and defined its processing.
null
as a possible value for the
timing parameter of the AnimationGroup
,
AnimationSequence
and Animation
constructors and
the Animatable
.animate
method.
target
member of the Animation
interface no longer
readonly.
AnimationTarget
typedef and introduced the
Animatable
interface in its place.
Animatable
.animate
return an
AnimationPlayer
instead of an Animation
.
Animatable
.getCurrentAnimations
as at
risk.
composite
member of KeyframeEffect
and MotionPathEffect
to the base class,
AnimationEffect
.
KeyframeAnimationEffect
to
KeyframeEffect
.
KeyframeEffect
to take
a KeyframeEffectOptions
dictionary object.
spacing
member to both
KeyframeEffect
and KeyframeEffectOptions
to specify spacing behavior.
getFrames
on KeyframeEffect
return the
computed keyframe offset as computedOffset
and
apply the normalization of keyframes defined in section 5.14.6 Normalizing a sequence of keyframes.
ComputedKeyframe
dictionary for representing
the return values from KeyframeEffect
.getFrames
.
OneOrMoreKeyframes
typedef since it is no
longer a valid WebIDL union. Replaced useage of
OneOrMoreKeyframes
with object
and defined
its processing.
offset
of a keyframe.
This is now incorporated in section 4.3.1 Spacing keyframes which is now a core part of the model.
[[Enumerate]]
.
easing
member to the Keyframe
dictionary.
PathAnimationEffect
to
MotionPathEffect
.
MotionPathEffect
to take
a MotionPathEffectOptions
dictionary object.
spacing
member to the
MotionPathEffect
interface.
CustomEffect
callback interface with the
EffectCallback
callback function and replaced the
currentIteration
and target
parameters
with the Animation
object that is
being sampled.
getCurrentPlayers
on the Element
interface to getAnimationPlayers
.
PseudoElementReference
interface to use the
PseudoElement
interface from CSSOM instead.
requestAnimationFrame
callbacks.
The changelog provides a more detailed history.