cid e0da227abdca01a3898df13e20d1549676e7f28f17630a6d9644b15450540aa1 · original · open access · via w3c
Title: Web Animations
Authors:
Venue: w3c
Year: 2023
Canonical: w3c:web-animations
URL: https://www.w3.org/TR/web-animations/
Collector: w3c
OA: true
ABSTRACT
Web Animations Web Animations W3C Working Draft, 5 June 2023 More details about this document This version: https://www.w3.org/TR/2023/WD-web-animations-1-20230605/ Latest published version: https://www.w3.org/TR/web-animations-1/ Editor's Draft: https://drafts.csswg.org/web-animations-1/ Previous Versions: https://www.w3.org/TR/2021/WD-web-animations-1-20220908/ https://www.w3.org/TR/2021/WD-web-animations-1-20210518/ https://www.w3.org/TR/2018/WD-web-animations-1-20181011/ https://www.w3.org/TR/2016/WD-web-animations-1-20160913/ https://www.w3.org/TR/2015/WD-web-animations-1-20150707/ https://www.w3.org/TR/2014/WD-web-animations-20140605/ https://www.w3.org/TR/2013/WD-web-animations-20130625/ History: https://www.w3.org/standards/history/web-animations-1 Test Suite: https://github.com/web-platform-tests/wpt/tree/master/web-animations Feedback: CSSWG Issues Repository Inline In Spec Editors: Brian Birtles (Invited Expert) Robert Flack (Google) Stephen McGruer (Google) Antoine Quint (Apple Inc) Former Editors: Shane Stephens (Google) Douglas Stockwell (Google) Alex Danilo (Google) Tab Atkins (Google) Suggest an Edit for this Spec: GitHub Editor Participate: Fix the text through GitHub Join the "waapi" channel on the Animation at Work slack IRC: #webanimations on W3C’s IRC Copyright © 2023 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply. Abstract 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. CSS is a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, etc. Status of this document This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/. This document was published by the CSS Working Group as a Working Draft using the Recommendation track. Publication as a Working Draft does not imply endorsement by W3C and its Members. 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. Please send feedback by filing issues in GitHub (preferred), including the spec code “web-animations” in the title, like this: “[web-animations] …summary of comment…”. All issues and comments are archived. Alternately, feedback can be sent to the (archived) public mailing list www-style@w3.org. This document is governed by the 2 November 2021 W3C Process Document. This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page 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. 1. Introduction This 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. 1.1. Use cases The Web Animations model is intended to provide the features necessary for expressing CSS Transitions [CSS-TRANSITIONS-1], CSS Animations [CSS-ANIMATIONS-1], and SVG [SVG11]. As such, the use cases of Web Animations model is the union of use cases for those three specifications. The use cases for the programming interface include the following: Inspecting running animations Often Web applications must wait for certain animated effects to complete before updating some state. The programming interface in this specification allows such applications to wait for all currently running animation to complete, regardless of whether they are defined by CSS Transitions, CSS Animations, SVG animations, or created directly using the programming interface. // Wait until all animations have finished before removing the element Promise.all( elem.getAnimations().map(animation = animation.finished) ).then(() = elem.remove()); Alternatively, applications may wish to query the playback state of animations without waiting. const isAnimating = elem.getAnimations().some( animation = animation.playState === 'running' ); Controlling running animations It is sometimes useful to perform playback control on animations so that they can respond to external inputs. For example, it may be necessary to pause all existing animations before displaying a modal dialog so that they do not distract the user’s attention. // Pause all existing animations in the document for (const animation of document.getAnimations()) { animation.pause() } Creating animations from script While it is possible to use ECMAScript to perform animation using requestAnimationFrame [HTML], such animations behave differently to declarative animation in terms of how they are represented in the CSS cascade and the performance optimizations that are possible such as performing the animation on a separate thread. Using the Web Animations programming interface, it is possible to create animations from script that have the same behavior and performance characteristics as declarative animations. // Fade out quickly elem.animate({ transform: 'scale(0)', opacity: 0 }, 300); Animation debugging In a complex application, it may be difficult to determine how an element arrived in its present state. The Web Animations programming interface may be used to inspect running animations to answer questions such as, "Why is the opacity of this element changing?" // Print the id of any opacity animations on elem for (const animation of elem.getAnimations()) { if ( animation.effect instanceof KeyframeEffect && animation.effect .getKeyframes() .some(frame = frame.hasOwnProperty('opacity')) ) { console.log(animation.id); } } Likewise, in order to fine tune animations, it is often necessary to reduce their playback rate and replay them. // Slow down and replay any transform animations const transformAnimations = elem.getAnimations().filter( animation = animation.effect instanceof KeyframeEffect && animation.effect.getKeyframes().some( frame = frame.hasOwnProperty('transform') ) ); for (const animation of transformAnimations) { animation.currentTime = 0; animation.updatePlaybackRate(0.5); } Testing animations In order to test applications that make use of animations it is often impractical to wait for such animations to run to completion. Rather, it is desirable to seek the animations to specific times. // Seek to the half-way point of an animation and check that the opacity is 50% for (const animation of elem.getAnimations()) { const { delay, activeDuration } = animation.effect.getComputedTiming(); animation.currentTime = delay + activeDuration / 2; } assert.strictEqual(getComputedStyle(elem).opacity, '0.5'); // Check that the loading screen is hidden after the animations finish for (const animation of elem.getAnimations()) { animation.finish(); } // Wait one frame so that event handlers have a chance to run requestAnimationFrame(() = { assert.strictEqual( getComputedStyle(document.querySelector('#loading')).display, 'none'); }); 1.2. Relationship to other specifications CSS Transitions [CSS-TRANSITIONS-1], CSS Animations [CSS-ANIMATIONS-1], 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 animation frame callbacks (commonly referred to as "requestAnimationFrame") [HTML], 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 animation frame callbacks [HTML] and their execution order is 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 HTML [HTML]. 1.3. Overview of this specification 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. 2. Specification conventions This specification begins by describing abstract concepts such as animations and animation effects and properties that belong to them such as their playback rate or iteration duration. In addition to these properties, there are often specific procedures for updating these properties such as the procedure to set the playback rate or the procedure to set the start time of an animation. Where this specification does not specifically link to a procedure, text that requires the user agent to update a property such as, "make animation’s start time unresolved", should be understood to refer to updating the property directly without invoking any related procedure. Further documentation conventions that are not specific to this specification are described in Document conventions. 3. Web Animations model overview 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: Timing model Takes a moment in time and converts it to a proportional distance within a single iteration of an animation called the iteration progress. The iteration index is also recorded since some animations vary each time they repeat. Animation model Takes the iteration progress values and iteration indices produced by the timing model and converts them into a series of values to apply to the target properties. Graphically, this flow can be represented as follows: Overview of the operation of the Web Animations model. The current time is input to the timing model which produces an iteration progress value and an iteration index. These parameters are used as input to the animation model which produces the values to apply. For example, consider an animation that: starts after 3 seconds runs twice, takes 2 seconds every time, and changes the width of a rectangle from 50 pixels to 100 pixels. 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. This specification begins with the timing model and then proceeds to the animation model. 4. Timing model This section describes and defines the behavior of the Web Animations timing model. 4.1. Timing model overview This section is non-normative Two features characterize the Web Animations timing model: it is stateless and it is hierarchical. 4.1.1. Stateless The Web Animations timing model operates by taking an input time and producing an output iteration progress. 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: Frame-rate independent Since the output is independent of previous inputs, the rate at which the model is updated will not affect its progress. Provided the input times are proportional to the progress of real-world time, animations will progress at an identical rate regardless of the capabilities of the device running them. Direction-agnostic Since the sequence of inputs is insignificant, the model is directionless. This means that the model can be updated to an arbitrary moment without requiring any specialized handling. Constant-time seeking Since each input is independent of the previous input, the processing required to perform a seek operation, even far into the future, is at least potentially constant. 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. Similarly, the finishing behavior of animations means that dynamic changes to the end time of the media (associated effect) of an animation 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 updated, 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 updates and hence does not conflict with the stateless qualities described above. 4.1.2. Hierarchical The other characteristic feature of the timing model is that time is inherited. Time begins at a timeline and cascades down a number of steps to each animation effect. At each step, time may be shifted backwards and forwards, scaled, reversed, paused, and repeated. A hierarchy of timing nodes. Each node in the tree derives its time from its parent node. In this level of the specification the hierarchy is shallow. A subsequent level of this specification will introduce the concept of group effects which allows for deeper timing hierarchies. 4.2. Time values 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 there may be timelines that are based on scroll position or UI gestures in which case the connection between time values and milliseconds will be weakened even further. A time value may also be unresolved if, for example, a timing node is not in a state to produce a time value. 4.3. Timelines A timeline provides a source of time values for the purpose of synchronization. At any given moment, a timeline has a single current time value known simply as the timeline’s current time. A timeline may not always be able to return a meaningful time value, but only an unresolved time value. For example, it may be defined relative to a moment that has yet to occur, such as the firing of a document’s load event. A timeline is considered to be inactive when its time value is unresolved. A timeline is monotonically increasing if its reported current time is always greater than or equal than its previously reported current time. Specific types of timelines may define a procedure to convert a timeline time to an origin-relative time for time value time, so that the time values produced by wallclock-based timelines can be compared. A timeline may be associated with a document. When asked to update animations and send events for a Document doc at timestamp now, run these steps: Update the current time of all timelines associated with doc passing now as the timestamp. Due to the hierarchical nature of the timing model, updating the current time of a timeline also involves: Updating the current time of any animations associated with the timeline. Running the update an animation’s finished state procedure for any animations whose current time has been updated. Queueing animation events for any such animations. Remove replaced animations for doc. Perform a microtask checkpoint. Note: This is to ensure that any microtasks queued up as a result of resolving or rejecting Promise objects as part of updating timelines in the previous step, run their callbacks prior to dispatching animation events. Let events to dispatch be a copy of doc’s pending animation event queue. Clear doc’s pending animation event queue. Perform a stable sort of the animation events in events to dispatch as follows: Sort the events by their scheduled event time such that events that were scheduled to occur earlier, sort before events scheduled to occur later and events whose scheduled event time is unresolved sort before events with a resolved scheduled event time. Within events with equal scheduled event times, sort by their composite order. Note: The purpose of sorting events is to ensure that, as best possible, even on devices with differing capabilities and hence different frame rates, events are dispatched in a consistent order. Note: The requirement for the sort to be a stable sort is because sometimes events may be queued with the same scheduled event time. For example, a CSS animation with a duration of zero, may dispatch both an animationstart and an animationend event and the order of these events should be preserved. Dispatch each of the events in events to dispatch at their corresponding target using the order established in the previous step. It is often convenient to describe each time this procedure is invoked as establishing a new animation frame. Changes to the timing properties of animations or animation effects, or the addition and removal of the objects may cause the output of the timing or animation model to change, but these operations in themselves do not create a new animation frame, rather they merely update the current animation frame. 4.3.1. Document timelines A document timeline is a type of timeline that is associated with a document and whose current time is calculated as a fixed offset from the now timestamp provided each time the update animations and send events procedure is run. This fixed offset is referred to as the document timeline’s origin time. There must be a better term than "origin time"— it’s too similar to "time origin". [Issue #2079] Prior to establishing the time origin for its associated document, a document timeline is inactive. After a document timeline becomes active, it is monotonically increasing. A document timeline that is associated with a Document which is not an active document is also considered to be inactive. To convert a timeline time, timeline time, to an origin-relative time for a document timeline, timeline, return the sum of the timeline time and timeline’s origin time. If timeline is inactive, return an unresolved time value. 4.3.2. The default document timeline Each Document has a document timeline called the default document timeline. The default document timeline is unique to each document and persists for the lifetime of the document including calls to document.open() [HTML]. The default document timeline has an origin time of zero. This section is non-normative Since no scaling is applied to the now timestamp values provided to document timelines, the time values it produces will be proportional to wall-clock milliseconds. Furthermore, since the time values of the default document timeline have a zero offset from the time origin, document.timeline.currentTime will roughly correspond to Performance.now() [HR-TIME] with the exception that document.timeline.currentTime does not change in between calls to the update animations and send events procedure. 4.4. Animations This section is non-normative The children of a timeline are called animations. An animation takes an animation effect which is a static description of some timed behavior and binds it to a timeline so that it runs. An animation also allows run-time control of the connection between the animation effect and its timeline by providing pausing, seeking, and speed control. The relationship between an animation and an animation effect is analogous to that of a DVD player and a DVD. An animation connects a single animation effect, called its associated effect, to a timeline and provides playback control. Both of these associations are optional and configurable such that an animation may have no associated effect or timeline at a given moment. An animation’s document for timing is the Document with which its timeline is associated. If an animation is not associated with a timeline, or its timeline is not associated with a document, then it has no document for timing. An animation’s start time is the time value of its timeline when its associated effect is scheduled to begin playback. An animation’s start time is initially unresolved. An animation also maintains a hold time time value which is used to fix the animation’s output time value, called its current time, in circumstances such as pausing. The hold time is initially unresolved. In order to establish the relative ordering of conflicting animations, animations are appended to a global animation list in the order in which they are created. Certain classes of animations, however, may provide alternative means of ordering animations (see § 5.4.1 Animation classes). 4.4.1. Setting the timeline of an animation The procedure to set the timeline of an animation, animation, to new timeline which may be null, is as follows: Let old timeline be the current timeline of animation, if any. If new timeline is the same object as old timeline, abort this procedure. Let the timeline of animation be new timeline. If the start time of animation is resolved, make animation’s hold time unresolved. Note: This step ensures that the finished play state of animation is not "sticky" but is re-evaluated based on its updated current time. Run the procedure to update an animation’s finished state for animation with the did seek flag set to false, and the synchronously notify flag set to false. 4.4.2. Setting the associated effect of an animation The procedure to set the associated effect of an animation, animation, to new effect which may be null, is as follows: Let old effect be the current associated effect of animation, if any. If new effect is the same object as old effect, abort this procedure. If animation has a pending pause task, reschedule that task to run as soon as animation is ready. If animation has a pending play task, reschedule that task to run as soon as animation is ready to play new effect. If new effect is not null and if new effect is the associated effect of another animation, previous animation, run the procedure to set the associated effect of an animation (this procedure) on previous animation passing null as new effect. Let the associated effect of animation be new effect. Run the procedure to update an animation’s finished state for animation with the did seek flag set to false, and the synchronously notify flag set to false. 4.4.3. The current time of an animation Animations provide a time value to their associated effect called the animation’s current time. The current time is calculated from the first matching condition from below: If the animation’s hold time is resolved, The current time is the animation’s hold time. If any of the following are true: the animation has no associated timeline, or the associated timeline is inactive, or the animation’s start time is unresolved. The current time is an unresolved time value. Otherwise, current time = (timeline time - start time) × playback rate Where timeline time is the current time value of the associated timeline. The playback rate value is defined in § 4.4.15 Speed control. 4.4.4. Setting the current time of an animation The current time of an animation can be set to a new value to seek the animation. The procedure for setting the current time is defined in two parts. The procedure to silently set the current time of an animation, animation, to seek time is as follows: If seek time is an unresolved time value, then perform the following steps. If the current time is resolved, then throw a TypeError. Abort these steps. Update either animation’s hold time or start time as follows: If any of the following conditions are true: animation’s hold time is resolved, or animation’s start time is unresolved, or animation has no associated timeline or the associated timeline is inactive, or animation’s playback rate is 0, Set animation’s hold time to seek time. Otherwise, Set animation’s start time to the result of evaluating timeline time - (seek time / playback rate) where timeline time is the current time value of timeline associated with animation. If animation has no associated timeline or the associated timeline is inactive, make animation’s start time unresolved. This preserves the invariant that when we don’t have an active timeline it is only possible to set either the start time or the animation’s current time. Make animation’s previous current time unresolved. The procedure to set the current time of an animation, animation, to seek time is as follows: Run the steps to silently set the current time of animation to seek time. If animation has a pending pause task, synchronously complete the pause operation by performing the following steps: Set animation’s hold time to seek time. Apply any pending playback rate to animation. Make animation’s start time unresolved. Cancel the pending pause task. Resolve animation’s current ready promise with animation. Run the procedure to update an animation’s finished state for animation with the did seek flag set to true, and the synchronously notify flag set to false. 4.4.5. Setting the start time of an animation The procedure to set the start time of animation, animation, to new start time, is as follows: Let timeline time be the current time value of the timeline that animation is associated with. If there is no timeline associated with animation or the associated timeline is inactive, let the timeline time be unresolved. If timeline time is unresolved and new start time is resolved, make animation’s hold time unresolved. This preserves the invariant that when we don’t have an active timeline it is only possible to set either the start time or the animation’s current time. Let previous current time be animation’s current time. Note: This is the current time after applying the changes from the previous step which may cause the current time to become unresolved. Apply any pending playback rate on animation. Set animation’s start time to new start time. Update animation’s hold time based on the first matching condition from the following, If new start time is resolved, If animation’s playback rate is not zero, make animation’s hold time unresolved. Otherwise (new start time is unresolved), Set animation’s hold time to previous current time even if previous current time is unresolved. If animation has a pending play task or a pending pause task, cancel that task and resolve animation’s current ready promise with animation. Run the procedure to update an animation’s finished state for animation with the did seek flag set to true, and the synchronously notify flag set to false. 4.4.6. Waiting for the associated effect This section is non-normative Some operations performed by an animation may not occur instantaneously. For example, some user agents may delegate the playback of an animation to a separate process or to specialized graphics hardware each of which may incur some setup overhead. If such an animation is timed from the moment when the animation was triggered there may be a significant jump between the first and second frames of the animation corresponding to the setup time involved. To avoid this problem, Web Animations typically begins timing animations from the moment when the first frame of the animation is complete. This is represented by an unresolved start time on the animation which becomes resolved when the animation is ready. Content may opt out of this behavior by setting the start time to a resolved time value. An animation is ready at the first moment where both of the following conditions are true: the user agent has completed any setup required to begin the playback of the animation’s associated effect including rendering the first frame of any keyframe effect. the animation is associated with a timeline that is not inactive. 4.4.7. The current ready promise Each animation has a current ready promise. The current ready promise is initially a resolved Promise created using the procedure to create a new resolved Promise with the animation itself as its value and created in the relevant Realm of the animation. The object is replaced with a new Promise object every time the animation queues a pending play task or a pending pause task when it previously did not have a pending task, or when the animation is canceled (see § 4.4.14 Canceling an animation). Note that since the same object is used for both pending play and pending pause requests, authors are advised to check the state of the animation when the Promise object is resolved. For example, in the following code fragment, the state of the animation will be running when the current ready promise is resolved. This is because the play operation occurs while a pending play task is still queued and hence the current ready promise is re-used. animation.pause(); animation.ready.then(function() { // Displays 'running' alert(animation.playState); }); animation.play(); 4.4.8. Playing an animation The procedure to play an animation, animation, given a flag auto-rewind, is as follows: Let aborted pause be a boolean flag that is true if animation has a pending pause task, and false otherwise. Let has pending ready promise be a boolean flag that is initially false. Let seek time be a time value that is initially unresolved. If the auto-rewind flag is true, perform the steps corresponding to the first matching condition from the following, if any: If animation’s effective playback rate ≥ 0, and animation’s current time is either: unresolved, or less than zero, or greater than or equal to associated effect end, Set seek time to zero. If animation’s effective playback rate ) propertyName (double? or sequence