# Web Animations Level 2

## Unofficial Proposal Draft, 1 January 1970

This version:
  https://drafts.csswg.org/web-animations-2/
Version History:
  https://github.com/w3c/csswg-drafts/commits/master/web-animations-1
Editors:
  Brian Birtles (Mozilla)
  Shane Stephens (Google Inc)
  Douglas Stockwell (Google Inc)
Issue Tracking:
  GitHub Issues
  GitHub
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

Not Ready For Implementation

This spec is not yet ready for implementation. It exists in this repository to record the ideas and promote discussion.

Before attempting to implement this spec, please contact the CSSWG at www-style@w3.org.

Copyright © 1970 W3C® (MIT, ERCIM, Keio, Beihang). 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

## 1. Delta specification

This is a delta specification, meaning that it currently contains only the differences from Web Animations Level 1 [WEB-ANIMATIONS-1]. Once the Level 1 specification is closer to complete, it will be merged with the additions here into a complete level 2 specification.

## 2. Changes since level 1

This specification introduces the following changes compared to the previous level of this specification:

- group effects and sequence effects,

- an animation effect-specific playback rate,

- custom effects.

## 3. Timing model

This section describes and defines the behavior of the Web Animations timing model.

### 3.1. Timing model overview

This section is non-normative

#### 3.1.1. Hierarchical

This level of the specification includes an updated timing hierarchy diagram.

A hierarchy of timing nodes. Each node in the tree derives its time from its parent node.

Along with the following updated description:

> 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.

### 3.2. Animations

This section is non-normative

#### 3.2.1. Setting the timeline of an animation

If new timeline is null, we should ensure that custom effects get called with an unresolved iteration progress (unless a subsequent change in the same script execution context makes this redundant).

#### 3.2.2. Setting the target effect of an animation

After the step to reschedule a pending play task add the following step:

> 1. If new effect is not `null` and if new effect has a parent group, remove new effect from its parent group.

After the step to assign new effect as animation’s target effect include the following step:

> 1. If old effect is not `null`, queue a task to call any custom effects associated with inclusive descendants of old effect with an unresolved iteration progress.

>    This is not quite right. If old effect is attached to another animation in the same task then we should probably not do an extra callback with unresolved.

>    The definition of when custom effects gets called needs to be audited and probably rewritten.

#### 3.2.3. Waiting for the target effect

The definition of when an animation is ready needs to be extended to consider descendant effects and custom effects such that the first condition is:

> - the user agent has completed any setup required to begin the playback of each inclusive descendant of the animation’s target effect including rendering the first frame of any keyframe effect or executing any custom effects associated with an animation effect.

#### 3.2.4. Playing an animation

The procedure to play an animation needs to include scheduling a task for updating custom effects.

#### 3.2.5. Pausing an animation

The procedure to pause an animation needs to refer to not on the target effect but also any descedants of the target effect.

Likewise, the procedure to pause an animation needs to include scheduling a task for updating custom effects.

#### 3.2.6. Canceling an animation

The procedure to cancel an animation needs to include the final step:

> 1. Queue a task to call any custom effects associated with inclusive descendants of animation’s target effect with an unresolved iteration progress.

>    The procedures for calling custom effects need to be reworked. Currently they probably involve calling too often for changes that could be coalesced.

#### 3.2.7. Speed control

Add the following sentence:

> Note that animation effects also have a playback rate associated with them that behaves differently to that defined here.

### 3.3. Animation effects

Adds the following text:

> The target effect of an animation is said to be directly associated with that animation.

> Animation effects can be combined together into a hierarchy using group effects (see § 3.8 Grouping and synchronization). Only the root animation effect of such a hierarchy can be directly associated with an animation. If an animation effect that has a parent group is designated as the target effect of an animation, the animation effect is removed from its parent group before being associated with the animation.

> An animation effect is associated with an animation if it is directly associated with an animation or if it has an ancestor group effect that is directly associated with an animation.

#### 3.3.1. Types of animation effects

This specification defines two types of animation effects:

- keyframe effects, and

- group effects.

#### 3.3.2. The active interval

In this level of the specification the lower bound of the acive interval is defined as:

> The lower bound of the active interval is determined by the start time of the animation effect but may be shifted by a start delay on the animation effect.

The subsequent diagram should also refer to the animation effect start time as opposed to the animation start time.

Finally, the description of the end delay is updated to:

> An end delay may also be specified but is primarily only of use when sequencing animations such as by using a sequence effect.

The normative description is updated as follows:

> The lower bound of the active interval is defined by the combination of the animation effect’s start time and start delay.

> An animation effect’s start time is the moment at which the parent group, if any, has scheduled the animation effect to begin. It is expressed in inherited time.

> In most cases, including the case when the animation effect has no parent group, the start time is zero. The singular exception is sequence effects which set the start times of their children as described in § 3.8.4.1 The start time of children of a sequence effect.

> In addition to the start time, an animation effect also has a start delay which is an offset from the start time.

> Unlike the start time which is determined by the parent group, the start delay is a property of the animation effect itself.

> The lower bound of the active interval of an animation effect, 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 § 3.3.3 Local time and inherited time) and active time.

And finally regarding the definition of the end time:

> The end time of an animation effect is the result of evaluating `max(start time + start delay + active duration + end delay, 0)`.

#### 3.3.3. Local time and inherited time

This section is added.

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. Group effects typically perform some transformations on the time values they receive from their parent or animation before passing on the transformed time values to their children. Child animation effects 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.

Inherited time and local time.
At time t, the inherited time is 2.5.
For animation effect (a) which has a start time of 1, the local time is 1.5.
For animation effect (b) which has a start time of 1 and a start delay of 1, the local time is also 1.5 since local time is based on an animation effect’s start time only, and not on its start delay.

For an animation effect, the inherited time at a given moment is based on the first matching condition from the following:

If the animation effect has a parent group,

  the inherited time is the parent group’s current transformed time.

If the animation effect is directly associated with an animation,

  the inherited time is the current time of the animation.

Otherwise,

  the inherited time is unresolved.

The local time of an animation effect is the animation effect’s inherited time minus its start time. If the inherited time is unresolved then the local time is also unresolved.

#### 3.3.4. Animation effect phases and states

This section is non-normative

The non-normative description of the in play state includes the following description;

> This occurs when the animation effect and all its ancestors are in the active phase. Animation effects only “move” when they are in play.

> It is possible for an animation effect to be in the active phase but not in play. For example, if an animation effect has a parent group that causes the animation effect’s active interval to be clipped and both parent and child apply the same fill mode, the child animation effect may be effectively be snapshotted within the active phase despite no longer being in play.

Likewise for current

> This will be the case if the animation effect 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 effect might play again (e.g. due to repeating).

The normative definition of in play includes the following condition:

> 2. the animation effect has a parent group that is in play or else the animation effect is directly associated with an animation that is not finished.

In place of:

> 2. the animation effect is associated with an animation that is not finished.

The normative definition of current adds the following condition:

> - the animation effect has a parent group and the parent group is current.

#### 3.3.5. Fill modes

This section is non-normative

The description of the forwards fill mode is updated from:

> When the animation effect is in the after phase, …

to:

> When the animation effect is in the after phase, or when the animation effect is in the active phase but an ancestor is in its after phase, …

The description of the backwards fill mode is updated from:

> When the animation effect is in the before phase, …

to:

> When the animation effect is in the before phase, or when the animation effect is in the active phase but an ancestor is in its before phase, …

The description of the both fill mode is updated from:

> When the animation effect …

to:

> When the animation effect or an ancestor …

(twice).

Currently timing functions that generate results outside the range [0, 1] will behave unexpectedly when applied to group effects, 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.

### 3.4. Repeating

#### 3.4.1. Iteration intervals

After:

> The length of a single iteration is called the iteration duration.

Add:

> The initial iteration duration of an animation effect is simply its intrinsic iteration duration.

> The intrinsic iteration duration of an animation effect is zero, however some specific types of animation effect such as group effects override this behavior and provide an alternative intrinsic duration (see § 3.8.3 The intrinsic iteration duration of a group effect and § 3.8.4.2 The intrinsic iteration duration of a sequence effect).

> The iteration duration of an animation effect may be set by the author to represent a value other than the intrinsic iteration duration.

#### 3.4.2. Iteration time space

This section is non-normative

The first few paragraphs of this section are replaced with:

> We have already encountered different time spaces in describing local time and inherited time (see § 3.3.3 Local time and inherited time). Repetition introduces yet another time space: the iteration time space.

#### 3.4.3. Interval timing

This section is non-normative

The description is updated as follows:

> In the examples below, for the repeated effect, at local time 1s, the iteration time is 0. For the sequenced effects, at inherited time 1s, only effect B will be in play; there is no overlap.

And likewise the figure is updated as follows:

Illustration of end-point exclusive timing. For both repeated and sequenced animation effects there is no overlap at the boundaries between intervals.

### 3.5. Animation effect speed control

(This section is added.)

Like animations, animation effects also have a playback rate parameter. The playback rate of an animation effect is a finite real number that acts as a multiplier when calculating the animation effect’s transformed time from its local time.

The effect of setting the playback rate of an animation effect differs from the setting the playback rate on an animation. Its behavior is defined in the timing calculations given in § 3.6 Core animation effect calculations.

This section is non-normative

In summary, the behavior of the playback rate of an animation effect is as follows:

- The playback rate is applied only to the active interval of an animation effect and not to the time while it is delayed or filling.

- Setting a negative playback rate on an animation effect causes the animation effect to begin at the end of its active interval. This differs from the playback rate on an animation. Setting a playback rate on an animation to a negative value at a moment before the animation’s target effect has begun, will result in the target effect never playing.

- Setting the playback rate of an animation effect affects the calculated value of the active duration (see § 3.6.2 Calculating the active duration).

- Changing the playback rate of an animation effect 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 effects depend on the animation effect’s active duration, such as sibling animation effect in a sequence effect, they too may jump as a result of setting the animation effect’s playback rate.

  For runtime speed control the playback rate of the animation should be used.

### 3.6. Core animation effect calculations

#### 3.6.1. Overview

This section is non-normative

Update description from:

> At the core of the Web Animations timing model is the process that takes a local time value and converts it to an iteration progress.

to:

> At the core of the Web Animations timing model is the process that takes an inherited time value and converts it to an iteration progress.

Update diagram to show animation effect playback rate:

Calculation of the active duration is based on multiplying the iteration duration by the iteration count and then dividing by the playback rate.

Update:

> Having established the active duration, the process for transforming an animation effect’s local time into its transformed progress (iteration progress) is illustrated below.

to:

> Having established the active duration, the process for transforming an animation effect’s inherited time into its transformed progress (iteration progress) is illustrated below.

Update the time calculations diagram as follows:

An overview of timing model calculations.
(1) The inherited time is converted into a local time by incorporating the start time.
(2) The local time is converted into an active time by incorporating the start delay.
(3) The active time is divided by the iteration duration incorporating also the iteration start property and the playback rate property to produce the overall progress.
(4) The overall progress time is then converted to an offset within a single iteration: the simple iteration progress.
(5) The simple iteration progress is converted into a directed progress by incorporating the playback direction.
(6) Finally, a timing function is applied to the directed progress to produce the transformed progress.

Update:

> The first step, calculating the local time is described in Local time.

to:

> The first step, calculating the local time is described in § 3.3.3 Local time and inherited time.

#### 3.6.2. Calculating the active duration

Updated to:

> 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:

> 1. If the playback rate is zero, return `Infinity`.

> 2. Otherwise, return `repeated duration / abs(playback rate)`.

#### 3.6.3. Transforming the local time

##### 3.6.3.1. Calculating the active time

Update the qualification on the definition of the active time to include reference to the parent group:

> However, it is only defined when the animation effect should produce an output and hence depends on its fill mode and phase as well as the phase of its parent group, if any, as follows,

Update the definition to include the additional steps to for each phase:

> If the animation effect is in the before phase,

>   The result depends on the first matching condition from the following,

>   If the animation effect has a parent group and that parent group is in the after phase,

>     Return an unresolved time value.

>   …

> If the animation effect is in the active phase,

>   The result depends on the first matching condition from the following,

>   If the animation effect has a parent group and that parent group is in the before phase, and the fill mode of this animation effect is none or forwards,

>     Return an unresolved time value.

>   If the animation effect has a parent group and that parent group is in the after phase, and the fill mode of this animation effect is none or backwards,

>     Return an unresolved time value.

>   Otherwise,

>     Return the result of evaluating `local time - start delay`.

> If the animation effect is in the after phase,

>   The result depends on the first matching condition from the following,

>   If the animation effect has a parent group and that parent group is in the before phase,

>     Return an unresolved time value.

>   …

> Otherwise (the local time is unresolved),

>   Return an unresolved time value.

##### 3.6.3.2. Calculating the overall progress

In the definition of the overall progress update the “Otherwise” branch of the definition of the initial progress as:

> Otherwise,

>   Calculate the overall progress following the first matching condition from below:

>   If the animation effect playback rate is less than zero,

>     Let overall progress be `(active time - active duration) × playback rate / iteration duration`.

>   If the animation effect playback rate is zero,

>     Let overall progress be zero.

>   Otherwise,

>     Let overall progress be `(active time × playback rate) / iteration duration`.

### 3.7. Time transformations

Currently, the set of timing functions allowed on a group effect 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 group effects is considered at risk.

Alternatives are to either restrict timing functions on group effects 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.

See section 2 of the discussion from August 2013.

#### 3.7.1. Calculating the transformed progress

Replace the second step as the calculation of the before flag (to accommodate the effect playback rate):

> 1. If either the current direction is forwards or the animation effect playback rate ≥ 0 (but not when both conditions are true), let going forwards be true, otherwise it is false.

#### 3.7.2. Calculating the transformed time

(This section is added.)

The transformed time of an animation effect is simply the transformed progress multiplied by the iteration duration.

If the transformed progress is unresolved, then the transformed time is also unresolved.

If the transformed progress is zero and the iteration duration is infinity, then the transformed time is zero.

### 3.8. Grouping and synchronization

This section is non-normative

While it is possible to set the timing properties of animation effects individually, it is often useful to synchronize animation effects so that they share common timing properties and maintain their temporal relationship. This is achieved using an group effect.

A simple example is illustrated below.

Using groups to share common timing properties.
(a) Shows setting a delay of 5 seconds on individual animations.
(b) Produces the same effect by setting the delay on the group.

When a group effect is directly associated with an animation, the animation effect associated with the group effect can be seeked, paused, and stopped as a unit.

A group effect is a type of animation effect that contains an ordered sequence of zero or more animation effects known as child effects.

At a given moment, an animation effect may be a child effect of at most one group effect known as the parent group. The parent group cannot be the same animation effect as the child effect itself.

By nesting group effects 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 [DOM]:

- tree order

- root

- ancestor

- descendant

- inclusive ancestor

- inclusive descendant

- next sibling

- previous sibling

- first child

- last child

Note: in applying these definitions to animation effects, the term parent refers exclusively to a parent group and does not include the animation which with an animation effect may be directly associated despite the fact that conceptually the animation acts as a parent time source.

The temporal relationship between a child effect and its parent group is incorporated in the definition of inherited time (see § 3.3.3 Local time and inherited time).

#### 3.8.1. Relationship of group time to child time

This section is non-normative

The timing of the children of a group effect 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 a group effect 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.

Since children of a group effect base their timing on the group’s transformed time, when the group repeats, the children play again.

Note that even in this case, the child animation effects 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.

Specifying an iteration count of 2 on a group effect and an iteration count of 3 on one of its children results in that child playing 6 times.

A further result of the children of a group effect 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.

In the first instance, an animation effect has a negative delay and an infinite iteration count.
However, when a similar animation effect is placed inside a group effect with a specified iteration duration it has the effect of clipping the child animation effect’s active interval.

Some further consequences of group effect children basing their timing on their parent group’s transformed time are:

- Setting the playback rate of a group effect will speed up or slow down all children.

- Changing the playback direction of a group effect will change the direction of all children.

- Applying a timing function to a group effect will affect the progress of all children.

#### 3.8.2. The start time of children of a group effect

The start time of a child effect of a group effect is zero.

Note that specific types of group effects may override this definition to provide other kinds of synchronization behavior.

#### 3.8.3. The intrinsic iteration duration of a group effect

The intrinsic iteration duration of a group effect is based on the time when the last child effect completes its active interval and depends on the number of child effects as follows.

If the group has no child effects,

  the intrinsic iteration duration is zero.

Otherwise,

  1. Let maximum end time be the maximum value after calculating the end time of each child effect in the group.

  2. The intrinsic iteration duration is the result of evaluating `max(0, maximum end time)`.

This definition of the intrinsic iteration duration may be overridden by specific types of group effects.

#### 3.8.4. Sequence effects

This section is non-normative

Specific types of group effects can be used to provide different kinds of synchronization behavior for their children. This specification defines one additional type of group effect: a sequence effect. Sequence effects arrange the start times of their children so that they run one at a time, in turn.

Compare the two arrangements illustrated below:

Group effects and sequence effects.
(a) is a regular group effect where all the children run simultaneously.
(b) is a sequence effect where the children run in turn.

Since group effects can also contain other group effects, complex synchronization is possible by combining different types of groups as illustrated below.

A sequence effect that contains a regular group effect as a child.
The group effect waits for the previous child of the sequence effect to finish, and then the children of the group effect play simultaneously. After they have finished the next child of the sequence effect plays.

A sequence effect is a type of group effect that schedules its child effects such that they play in turn following their order in the group. This sequencing is achieved by adjusting the start time of each child effect in the group.

##### 3.8.4.1. The start time of children of a sequence effect

The start time of a child effect of a sequence effect 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 effect 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 a sequence effect 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 effect’s start time and start delay, the active intervals of children of a sequence effect need not run in strict sequence but can be shifted back and forth by using the start delay as shown in the following diagram.

Example of using the start delay on children of a sequence effect to shift their timing so that they overlap (a negative delay) or are spaced apart (a positive delay).

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.

##### 3.8.4.2. The intrinsic iteration duration of a sequence effect

The intrinsic iteration duration of a sequence effect is equivalent to the start time of a hypothetical child effect appended to the group’s children calculated according to the definition in § 3.8.4.1 The start time of children of a sequence effect unless that produces a negative value, in which case the intrinsic iteration duration is zero.

As a result, if the sequence effect has no child effects the intrinsic iteration duration will be zero.

## 4. Animation model

### 4.1. Animation types

#### 4.1.1. Not animatable

Update the description of an effect that targets a non-animated property as:

> An animation effect that targets a property that is not animatable will still exhibit the usual behavior for an animation effect such as occupying time in a sequence effect and delaying the fulfilment of an animation’s current finished promise.

### 4.2. Keyframe Effects

#### 4.2.1. The effect value of a keyframe effect

The procedure for computing the effect value of a single property referenced by a keyframe effect as one of its target properties, for a given iteration progress, current iteration and underlying value is amended by inserting the following step after the step to apply the keyframe effect composite mode.

12. For each keyframe in interval endpoints:

    1. (As in web-animations-1).

    2. If this keyframe effect has an iteration composite operation of accumulate, apply the following step current iteration times:

       - replace the property value of target property on keyframe with the result of combining the property value on the final keyframe in property-specific keyframes (Va) with the property value on keyframe (Vb) using the accumulation procedure defined for target property.

       Note: The order of arguments here is important. In the case where the animation type of the target property does not define a procedure for accumulation or addition, the default definition for these procedures result in Vb being returned. When performing iteration composition on propreties that do not support accumulation, the result should be the initial property value of target property on keyframe, hence we we make this Vb in the above step.

### 4.3. Combining effects

#### 4.3.1. The effect stack

The procedure for sorting effects appends the following step:

> 1. Sort A and B in tree order. (By this point, A and B must have the same animation since otherwise the order would have been resolved in the previous step.)

### 4.4. Effect accumulation

Similar to the compositing performed between effect values (see Web Animations 1 §5.4.4 Effect composition), the iteration composite operation determines how values are combined between successive iterations of the same keyframe effect.

This specification defines two iteration composite operations as follows:

replace

  Each successive iteration is calculated independently of previous iterations.

accumulate

  Successive iterations of the animation are accumulated with the final value of the previous iteration.

  The application of the iteration composite operation is incorporated in the calculation of the effect value in § 4.2.1 The effect value of a keyframe effect.

### 4.5. Custom effects

(This section is added.)

This whole feature needs to be revisited. The current thinking is that rather than having custom effects, we should simply have an `onupdate` callback on each animation effect. That would allow, for example, augmenting an existing effect with a function that performs logging or triggers additional actions at certain times. With the current arrangement, doing this would require adding a parent group just to achieve this.

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 an iteration progress 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 as part of the update animations and send events procedure.

It needs to be called whenever timing properties are updated too, right?

#### 4.5.1. Sampling custom effects

Custom effects are called for each referencing animation effect when the update animations and send events procedure is performed (henceforth referred to simple as an update) based on the following criteria.

1. If, on the previous update, the animation effect referencing the custom effect:

   - was in effect, and

   - referenced this same custom effect, and

   - had a different target element

   Call the callback passing an unresolved iteration progress and the target element from the previous update as parameters to the callback.

2. Call the callback for the current target element based on the first matching condition from the following:

   If the animation effect referencing the custom effect is not in effect but was in effect in the previous update,

     Call the callback passing an unresolved iteration progress and the current target element as parameters to the callback.

   Otherwise, if the animation effect referencing the custom effect:

     - is in effect, and

     - was not in effect in the previous update, or was in effect but with a different iteration progress or current iteration,

     Call the callback passing with the referencing animation effect’s current iteration progress and target element 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:

- Additional calling conditions could be defined to accommodate zero-width custom effects. For example, it could be required that the callback be called if (given infinite precision) there was a time between the previous and current update times that aligned with the custom effect.

- Instead of adding special calling conditions to custom effects, a new type of animation effect, Trigger, could be introduced. The trigger would only ever act as a zero-width custom effect as described above, its constructor would take a callback function, but not require a target or timing. It could also specify other calling conventions, for example whether it should only trigger in a specific playback direction.

#### 4.5.2. Execution order of custom effects

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.f

Custom effects are executed after all animation effects have completed and applied their result to their targets (see 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 § 4.3.1 The effect stack. Items sorted earlier are executed before those sorted later.

## 5. Programming interface

### 5.1. The `AnimationTimeline` interface

    [Exposed=Window]
    partial interface AnimationTimeline {
        Animation play (optional AnimationEffectReadOnly? effect = null);
    };

`Animation play(optional AnimationEffectReadOnly? effect = null)`

  Creates a new `Animation` object associated with this timeline that begins playback as soon as it is ready.

  If effect is specified, it will be used as the animation’s target effect.

  It has been suggested this method be renamed, or even removed (see TAG feedback).

  Need to define the start behavior when effect is null.

  The new `Animation` object is created using the `Animation()` constructor passing this `AnimationTimeline` object as the timeline parameter and effect as the effect parameter.

  Following construction of the `Animation` object, the procedure to play an animation is performed on the newly constructed object with the auto-rewind flag set to true.

  `effect`

    the target effect to assign to the newly-created `Animation` object.

### 5.2. The `Animation` interface

The Animation interface is amended to make the timeline member mutable:

    partial interface Animation {
                   attribute AnimationTimeline?       timeline;
    };

`timeline`, of type AnimationTimeline, nullable

  The timeline associated with this animation. Setting this attribute updates the object’s timeline using the procedure to set the timeline of an animation.

### 5.3. The `AnimationEffectReadOnly` interface

The following paragraph is added:

> Interfaces that inherit from `AnimationEffectReadOnly` that are intended to be mutable must also implement the additional `AnimationEffectMutable` interface.

    [Exposed=Window]
    partial interface AnimationEffectReadOnly {
        // Timing hierarchy
        readonly attribute GroupEffectReadOnly?     parent;
        readonly attribute AnimationEffectReadOnly? previousSibling;
        readonly attribute AnimationEffectReadOnly? nextSibling;
    };

    [NoInterfaceObject]
    interface AnimationEffectMutable {
        void before (AnimationEffectReadOnly... effects);
        void after (AnimationEffectReadOnly... effects);
        void replace (AnimationEffectReadOnly... effects);
        void remove ();
    };

`getComputedTiming()`

  The description of the `duration` attribute of the object needs to indicate that if `timing.duration` is the string `auto`, this attribute will return the current calculated value of the intrinsic iteration duration.

`parent`, of type GroupEffectReadOnly, readonly, nullable

  The parent group of this animation effect or `null` if this animation effect does not have a parent group.

  Should this be `parentGroup`?

`previousSibling`, of type AnimationEffectReadOnly, readonly, nullable

  The previous sibling of this animation effect.

`nextSibling`, of type AnimationEffectReadOnly, readonly, nullable

  The next sibling of this animation effect.

`void before (AnimationEffectReadOnly... effects)`

  Inserts effects before this animation effect.

  1. If there is no parent group, abort these steps.

  2. If any of the animation effects in effects is an inclusive ancestor of this animation effect, throw a HierarchyRequestError exception and abort these steps.

  3. Insert effects before this animation effect.

  Note that this definition precludes the following usage since `effect` is an inclusive ancestor of itself:

      effect.before(effect); // throws HierarchyRequestError

`void after(AnimationEffectReadOnly... effects)`

  Inserts effects after this animation effect.

  1. If there is no parent group, abort these steps.

  2. If any of the animation effects in effects is an inclusive ancestor of this animation effect, throw a HierarchyRequestError exception and abort these steps.

  3. Let reference child be the next sibling of this animation effect not in effects.

  4. Insert effects before reference child.

`void replace(AnimationEffectReadOnly... effects)`

  Replaces this `AnimationEffectReadOnly` with the passed in effects.

  1. If there is no parent group, abort these steps.

  2. If any of the animation effects in effects is an inclusive ancestor of the parent group throw a HierarchyRequestError exception and abort these steps.

  3. Let reference child be the next sibling of this animation effect not in effects.

  4. Remove this animation effect from its parent group.

  5. Insert effects before reference child.

`void remove()`

  Removes this animation effect from its parent group or animation.

The `remove()` method can be used to remove an effect from either its parent group or animation. Should we keep it in level 1 and define it simply as removing the animation from its animation?

### 5.4. The `AnimationEffectTimingReadOnly` interface

    [Exposed=Window]
    partial interface AnimationEffectTimingReadOnly {
        readonly attribute double                             playbackRate;
    };

delay

  Update the description as:

  > The start delay which represents the number of milliseconds from an animation effect’s start time to the start of the active interval.

endDelay

  Update the description as:

  > The end delay which represents the number of milliseconds from the end of an animation effect’s active interval until the start time of any animation effect that may follow, for example, in a sequence effect.

duration

  Add:

  > The string value `auto` is used to indicate that the iteration duration reflects the animation effect’s intrinsic iteration duration.

`playbackRate`, of type double, readonly

  The animation effect’s playback rate property which is a multiplier applied to the local time potentially causing the effect to run at a different rate to its natural speed.

### 5.5. The `AnimationEffectTiming` interface

Update the description to refer to the group/sequence effects:

> The `AnimationEffectTiming` interface is a mutable subclass of `AnimationEffectTimingReadOnly` returned for the `timing` attribute of a mutable animation effect such as `KeyframeEffect`, `GroupEffect`, or `SequenceEffect`.

    [Exposed=Window]
    partial interface AnimationEffectTiming : AnimationEffectTimingReadOnly {
        inherit attribute double                             playbackRate;
    };

`playbackRate`, of type double

  See the `playbackRate` attribute of the `AnimationEffectTimingReadOnly` interface.

### 5.6. The `AnimationEffectTimingProperties` dictionary

    partial dictionary AnimationEffectTimingProperties {
        double playbackRate = 1.0;
    };

`playbackRate`, of type double, defaulting to `1.0`

  See the `playbackRate` attribute of the `AnimationEffectTiming` interface.

### 5.7. The `ComputedTimingProperties` dictionary

    partial dictionary ComputedTimingProperties : AnimationEffectTimingProperties {
        double startTime;
    };

`startTime`, of type double

  The start time of this animation effect in milliseconds. This is the time at which the parent group, if any, has scheduled this child to run within its transformed time space, that is, the animation effect’s inherited time space.

  The start of the active interval is based on the sum of the start time and start delay.

endTime

  Update the description as:

  > The end time of the animation effect expressed in milliseconds in inherited time space.

  > This corresponds to the end of the animation effect’s active interval plus any end delay.

localTime

  Update the second paragraph as:

  > This will be `null` if this animation effect is not associated with an animation or if it has a parent group that is not in effect.

#### 5.7.1. The `FillMode` enumeration

    enum FillMode { "none", "forwards", "backwards", "both", "auto" };

`auto`

  Update the description as:

  > Fill backwards and forwards when applied to an `GroupEffectReadOnly` and no fill when applied to an `KeyframeEffectReadOnly`.

### 5.8. The `GroupEffectReadOnly` and `GroupEffect` interfaces

(This section is added.)

Group effects are represented by the `GroupEffectReadOnly` interface. Mutable group effects are represented by the `GroupEffect` interface.

    [Exposed=Window,
     Constructor (sequence? children,
                  optional (unrestricted double or AnimationEffectTimingProperties) timing)]
    interface GroupEffectReadOnly : AnimationEffectReadOnly {
        readonly attribute AnimationNodeList      children;
        readonly attribute AnimationEffectReadOnly? firstChild;
        readonly attribute AnimationEffectReadOnly? lastChild;
        GroupEffect clone ();
    };

    [NoInterfaceObject]
    interface GroupEffectMutable {
      void prepend (AnimationEffectReadOnly... effects);
      void append (AnimationEffectReadOnly... effects);
    };

    [Exposed=Window,
     Constructor (sequence? children,
                  optional (unrestricted double or AnimationEffectTimingProperties) timing)]
    interface GroupEffect : GroupEffectReadOnly {
    };
    GroupEffect implements AnimationEffectMutable;
    GroupEffect implements GroupEffectMutable;

`GroupEffectReadOnly ()`

  Creates a new `GroupEffectReadOnly` object using the following procedure:

  1. Create a new `GroupEffectReadOnly` object, group.

  2. Let timing input be the result of applying the procedure to process a timing argument to `timing`.

  3. Set `group.timing` to a new `AnimationEffectTimingReadOnly` object created in the current realm (that is, the same realm used to create effect) whose attributes are assigned the value of the member of the same name on timing input.

  4. Insert `children` before `null`.

  `children`

    A sequence of animation effects to add as children of this group.

    These children are appended in sequence using the same semantics as the `append()` method of the `GroupEffectMutable` interface.

  `timing`

    The timing properties or iteration duration of the new group effect.

`GroupEffect ()`

  Creates a new `GroupEffect` object using the same procedure as with the `GroupEffectReadOnly()` constructor with the following differences:

  - group is initialized to a new `GroupEffect` object rather than a new `GroupEffectReadOnly` object.

  - `group.timing` is set to a new `AnimationEffectTiming` object rather than a new `AnimationEffectTimingReadOnly` object.

`children`, of type AnimationNodeList, readonly

  The list of child effects in the group.

`firstChild`, of type AnimationEffectReadOnly, readonly, nullable

  The first child of this group effect.

`lastChild`, of type AnimationEffectReadOnly, readonly, nullable

  The last child of this group effect.

``
void prepend (AnimationEffectReadOnly... effects)

  1. If any of the animation effects in effects is an inclusive ancestor of this animation effect, throw a HierarchyRequestError exception and abort these steps.

  2. Insert effects before the first child.

`void append (AnimationEffectReadOnly... effects)`

  1. If any of the animation effects in effects is an inclusive ancestor of this animation effect, throw a HierarchyRequestError exception and abort these steps.

  2. Insert effects before `null`.

`GroupEffect clone ()`

  Creates a deep copy of this `GroupEffectReadOnly` object using the following procedure.

  1. Let source be this `GroupEffectReadOnly` object, the object to be cloned.

  2. Let cloned timing be a new `AnimationEffectTimingProperties` object whose members are assigned the value of the attribute with the same name on `source.timing`.

  3. Let cloned children be an empty sequence of `AnimationEffectReadOnly` objects.

  4. For each child in `source.children`, append the result of calling `child.clone()` to cloned children.

  5. Return a new `GroupEffect` object created by calling the `GroupEffect()` constructor with parameters `GroupEffect(cloned children, cloned timing)`.

#### 5.8.1. Processing a `timing` argument

The timing parameter passed to the `GroupEffectReadOnly()`, `GroupEffect()`, `SequenceEffectReadOnly()`, or `SequenceEffect()` constructor may be an `AnimationEffectTimingProperties` object, a double representing the duration of the animation effect in milliseconds, or undefined.

The following procedure to process a timing argument, timing, normalizes the above inputs into a `AnimationEffectTimingProperties` object.

If timing is an `AnimationEffectTimingProperties` object,

  Return timing.

If timing is a `double`,

  Return a new `AnimationEffectTimingProperties` object with all members set to their default values and `duration` set to timing.

Otherwise (timing is undefined),

  Return a new `AnimationEffectTimingProperties` object with all members set to their default values.

Note that since `AnimationEffectTimingReadOnly` objects have the same member keys as `AnimationEffectTimingProperties` dictionaries, it is also possible to pass the `timing` member of another `AnimationEffectReadOnly` to the any of the methods that invoke this method as the timing parameter.

Doing so will cause the `AnimationEffectTimingReadOnly` object to be treated as an `AnimationEffectTimingProperties` dictionary and thus it will effectively be cloned, not shared.

For example, the timing of two animations may be aligned as follows:

    var effectA = elem.animate({ opacity: 0 }, 1000).effect;
    var effectB = elem.animate({ width: '0px' }, effectA.timing).effect;
    alert(effectA.timing !== effectB.timing); // Displays 'true'
    alert(effectA.timing.duration === effectB.timing.duration); // Displays 'true'

#### 5.8.2. Definitions for manipulating hierarchies

The next sibling of effect not included in a set of animation effects, effects is determined using the following teps:

1. Let context effect be effect.

2. While the next sibling of context effect is not `null` perform the following steps:

   1. Let context effect be the next sibling of context effect.

   2. If context effect is not in effects return context effect and abort these steps.

3. Return `null`.

To remove a effect from its parent group or animation, perform the steps corresponding to the first matching condition from below, if any:

If effect has a parent group,

  Remove effect from the parent group’s list of child effects.

If effect is directly associated with an animation,

  Disassociate effect from the animation.

To insert a series of zero or more animation effects, effects, to parent’s list of child effects before reference child perform the following steps for each effect in effects:

1. Remove effect from its parent.

2. Insert effect to parent’s list of child effects before reference child

### 5.9. The `AnimationNodeList` interface

A list of animation effects 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.

    [Exposed=Window]
    interface AnimationNodeList {
        readonly attribute unsigned long length;
        getter AnimationEffectReadOnly? item (unsigned long index);
    };

`length`, of type unsigned long, readonly

  The number of animation effects in the list.

`getter AnimationEffectReadOnly? item(unsigned long index)`

  Returns the animation effect at `index`. If `index` is greater than or equal to `length` returns `null`.

### 5.10. The `SequenceEffectReadOnly` and `SequenceEffect` interfaces

Sequence effects are represented by the `SequenceEffectReadOnly` interface. Mutable sequence effects are represented by the `SequenceEffect` interface.

    [Exposed=Window,
     Constructor (sequence? children,
                  optional (unrestricted double or AnimationEffectTimingProperties) timing)]
    interface SequenceEffectReadOnly : GroupEffectReadOnly {
        SequenceEffect clone ();
    };

    [Exposed=Window,
     Constructor (sequence? children,
                  optional (unrestricted double or AnimationEffectTimingProperties) timing)]
    interface SequenceEffect : SequenceEffectReadOnly {
    };
    SequenceEffect implements AnimationEffectMutable;
    SequenceEffect implements GroupEffectMutable;

``Constructor (sequence<AnimationEffectReadOnly>? children, optional (unrestricted double or AnimationEffectTimingProperties) timing)``

  The meaning and handling of each of the parameters in this constructor is identical to the `GroupEffect()` constructor.

`SequenceEffect clone ()`

  Creates a deep copy of this `SequenceEffectReadOnly` object using the same procedure as defined for the `clone()` method of the `GroupEffectReadOnly` interface except that a new `SequenceEffect` object is created.

### 5.11. The `KeyframeEffectReadOnly` and `KeyframeEffect` interfaces

The KeyframeEffect interface is modified to add the following:

    partial interface KeyframeEffect {
        attribute IterationCompositeOperation    iterationComposite;
    };

    KeyframeEffect implements AnimationEffectMutable;

`KeyframeEffect (target, keyframes, options)`

  Amend step 5 of the procedure to create a new KeyframeEffect object as follows:

  5. If options is a `KeyframeEffectOptions` object, assign the `iterationComposite`, and `composite`, properties of effect to the corresponding value from options.

     When assigning these properties, the error-handling defined for the corresponding setters on the `KeyframeEffect` interface is applied. If any of those setters require an exception to be thrown for the values specified by options, this procedure must throw the same exception and abort all further steps.

`KeyframeEffect (source)`

  Amend the procedure to create a new `KeyframeEffect` object with the same properties as `source` to include setting the iteration composite operation from source on effect.

`iterationComposite`, of type IterationCompositeOperation

  The iteration composite operation property of this keyframe effect as specified by one of the IterationCompositeOperation enumeration values.

  On setting, sets the iteration composite operation property of this animation effect to the provided value.

#### 5.11.1. Creating a new `KeyframeEffect` object

This section is non-normative

Replace:

> If the duration is not specified, a value of zero is used.

with:

> If the duration is not specified, the intrinsic iteration duration is used which, for a keyframe effect, is zero.

Add:

> This is particularly useful in combination with other animation effects. For example, fading an element before switching visibility to ‘hidden’ can be achieved as follows,

    new SequenceEffect(
      [
        new KeyframeEffect(elem, { opacity: 0 }, 1000),
        new KeyframeEffect(elem, { visibility: 'hidden' }, { fill: 'forwards' })
      ]
    );

#### 5.11.2. The KeyframeEffectOptions dictionary

The KeyframeEffectOptions dictionary interface is modified to add the following member:

    partial dictionary KeyframeEffectOptions {
        IterationCompositeOperation iterationComposite = "replace";
    };

`iterationComposite`, of type IterationCompositeOperation, defaulting to `"replace"`

  The iteration composite operation used to define the way animation values build from iteration to iteration.

### 5.12. The IterationCompositeOperation enumeration

The possible values of an animation effect’s iteration composite operation are represented by the IterationCompositeOperation enumeration.

    enum IterationCompositeOperation { "replace", "accumulate" };

`replace`

  Corresponds to the replace iteration composite operation value such that the effect value produced is independent of the current iteration.

`accumulate`

  Corresponds to the accumulate iteration composite operation value such that subsequent iterations of an animation effect build on the final value of the previous iteration.

### 5.13. The `EffectCallback` callback function

Custom effects can be defined in script by providing an `EffectCallback` callback function.

    callback EffectCallback = void (double? progress,
                                    (Element or CSSPseudoElement) currentTarget,
                                    Animation animation);

An `EffectCallback` is called each time an `KeyframeEffectReadOnly` object with which it is associated is updated.

double? progress

  The iteration progress value for which to produce an effect. When this is `null`, the function SHOULD remove the effect.

(Element or CSSPseudoElement) currentTarget

  The target element on which this callback is expected to operate.

  Note that currentTarget may differ from `animation.target`.

  If the target element of animation is changed between updates, this method will be called once with a null progress and the previous target element as the currentTarget, then again with the current progress and the updated target element as the currentTarget. This allows the animation effect to be removed from the old target element.

Animation animation

  The `Animation` object that is being updated.

### 5.14. The `Animatable` interface

`sequence<Animation> getAnimations()`

  Add:

  > If this object is the target element of two or more animation effects which are associated with the same animation, the corresponding `Animation` object will still only appear in the returned list once.

### 5.15. Model liveness

This section is non-normative

Regarding the section on, “ Changes made to the Web Animations model take effect immediately”, add:

> The same concept applies to more complex modifications of the Web Animations model such as adding and removing children from an `GroupEffect`.

Add:

> Changes made to the model using the programming interface do not cause any `EffectCallback` functions to be called

>   For example, in the following code, the callback function will not be called until after the script block has completed during regular updating.

>       var timesCalled = 0;
>       elem.animate(function() {
>         timesCalled++;
>       }, 10000);
>       alert(timesCalled); // Displays ‘0’

>   Note: Need to spec this properly somewhere.

## Conformance

### Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with `class="example"`, like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with `class="note"`, like this:

Note, this is an informative note.

Advisements are normative sections styled to evoke special attention and are set apart from other normative text with `<strong class="advisement">`, like this: UAs MUST provide an accessible alternative.

### Conformance classes

Conformance to this specification is defined for three conformance classes:

style sheet
  A CSS style sheet.
renderer
  A UA that interprets the semantics of a style sheet and renders documents that use them.
authoring tool
  A UA that writes a style sheet.

A style sheet is conformant to this specification if all of its statements that use syntax defined in this module are valid according to the generic CSS grammar and the individual grammars of each feature defined in this module.

A renderer is conformant to this specification if, in addition to interpreting the style sheet as defined by the appropriate specifications, it supports all the features defined by this specification by parsing them correctly and rendering the document accordingly. However, the inability of a UA to correctly render a document due to limitations of the device does not make the UA non-conformant. (For example, a UA is not required to render color on a monochrome monitor.)

An authoring tool is conformant to this specification if it writes style sheets that are syntactically correct according to the generic CSS grammar and the individual grammars of each feature in this module, and meet all other conformance requirements of style sheets as described in this module.

### Requirements for Responsible Implementation of CSS

The following sections define several conformance requirements for implementing CSS responsibly, in a way that promotes interoperability in the present and future.

#### Partial Implementations

So that authors can exploit the forward-compatible parsing rules to assign fallback values, CSS renderers must treat as invalid (and ignore as appropriate) any at-rules, properties, property values, keywords, and other syntactic constructs for which they have no usable level of support. In particular, user agents must not selectively ignore unsupported property values and honor supported values in a single multi-value property declaration: if any value is considered invalid (as unsupported values must be), CSS requires that the entire declaration be ignored.

#### Implementations of Unstable and Proprietary Features

To avoid clashes with future stable CSS features, the CSSWG recommends following best practices for the implementation of unstable features and proprietary extensions to CSS.

#### Implementations of CR-level Features

Once a specification reaches the Candidate Recommendation stage, implementers should release an unprefixed implementation of any CR-level feature they can demonstrate to be correctly implemented according to spec, and should avoid exposing a prefixed variant of that feature.

To establish and maintain the interoperability of CSS across implementations, the CSS Working Group requests that non-experimental CSS renderers submit an implementation report (and, if necessary, the testcases used for that implementation report) to the W3C before releasing an unprefixed implementation of any CSS features. Testcases submitted to W3C are subject to review and correction by the CSS Working Group.

Further information on submitting testcases and implementation reports can be found from on the CSS Working Group’s website at http://www.w3.org/Style/CSS/Test/. Questions should be directed to the public-css-testsuite@w3.org mailing list.

## Index

### Terms defined by this specification

- "accumulate", in §5.12
- active duration, in §3.6.2
- after(), in §5.3
- after(...effects), in §5.3
- ancestor, in §3.8
- AnimationEffectMutable, in §5.3
- animation effect playback rate, in §3.5
- animation effect start time, in §3.2
- AnimationNodeList, in §5.9
- append(), in §5.8
- append(...effects), in §5.8
- associated with an animation, in §3.3
- "auto", in §5.7.1
- "backwards", in §5.7.1
- before(), in §5.3
- before(...effects), in §5.3
- "both", in §5.7.1
- child effect, in §3.8
- children, in §5.8
- clone()
  - method for GroupEffectReadOnly, in §5.8
  - method for SequenceEffectReadOnly, in §5.10
- current, in §3.3.4
- custom effect, in §4.5
- delay, in §5.4
- descendant, in §3.8
- directly associated with an animation, in §3.3
- duration, in §5.4
- EffectCallback, in §5.13
- endDelay, in §5.4
- end time, in §3.2
- endTime, in §5.7
- FillMode, in §5.7.1
- first child, in §3.8
- firstChild, in §5.8
- "forwards", in §5.7.1
- getAnimations(), in §5.14
- getComputedTiming(), in §5.3
- group effect, in §3.8
- GroupEffect, in §5.8
- GroupEffect(children, timing), in §5.8
- GroupEffectMutable, in §5.8
- GroupEffectReadOnly, in §5.8
- GroupEffectReadOnly(children, timing), in §5.8
- inclusive ancestor, in §3.8
- inclusive descendant, in §3.8
- inherited time, in §3.3.3
- in play, in §3.3.4
- insert children, in §5.8.2
- intrinsic iteration duration, in §3.4.1
- item(index), in §5.9
- iterationComposite
  - attribute for KeyframeEffect, in §5.11
  - dict-member for KeyframeEffectOptions, in §5.11.2
- iteration composite operation, in §4.4
- IterationCompositeOperation
  - (enum), in §5.12
  - definition of, in §5.12
- iteration composite operation accumulate, in §4.4
- iteration composite operation replace, in §4.4
- KeyframeEffect(source), in §5.11
- KeyframeEffect(target, keyframes, options), in §5.11
- last child, in §3.8
- lastChild, in §5.8
- length, in §5.9
- local time, in §3.3.3
- localTime, in §5.7
- next sibling, in §3.8
- nextSibling, in §5.3
- next sibling not included, in §5.8.2
- "none", in §5.7.1
- parent, in §5.3
- parent group, in §3.8
- play(), in §5.1
- playbackRate
  - attribute for AnimationEffectTiming, in §5.5
  - attribute for AnimationEffectTimingReadOnly, in §5.4
  - dict-member for AnimationEffectTimingProperties, in §5.6
- play(effect), in §5.1
- prepend(), in §5.8
- prepend(...effects), in §5.8
- previous sibling, in §3.8
- previousSibling, in §5.3
- process a timing argument, in §5.8.1
- remove(), in §5.3
- remove an animation effect, in §5.8.2
- repeated duration, in §3.6.2
- "replace", in §5.12
- replace(), in §5.3
- replace(...effects), in §5.3
- root, in §3.8
- sequence effect, in §3.8.4
- SequenceEffect, in §5.10
- SequenceEffect(), in §5.10
- SequenceEffectReadOnly, in §5.10
- SequenceEffectReadOnly(), in §5.10
- start delay, in §3.2
- startTime, in §5.7
- timeline, in §5.2
- transformed time, in §3.7.2
- tree order, in §3.8

https://drafts.csswg.org/css-easing-1/#linear-easing-function Referenced in:

- 3.7. Time transformations

https://drafts.csswg.org/css-easing-1/#easing-function Referenced in:

- 3.3.5. Fill modes
- 3.7. Time transformations
- 3.8.1. Relationship of group time to child time

https://drafts.csswg.org/css-pseudo-4/#csspseudoelement Referenced in:

- 5.13. The EffectCallback callback function

https://drafts.csswg.org/css-values-4/#accumulation Referenced in:

- 4.2.1. The effect value of a keyframe effect
- 4.4. Effect accumulation

https://drafts.csswg.org/css2/visufx.html#propdef-visibility Referenced in:

- 5.11.1. Creating a new KeyframeEffect object

https://dom.spec.whatwg.org/#element Referenced in:

- 5.13. The EffectCallback callback function

http://www.ecma-international.org/ecma-262/6.0/#sec-code-realms Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

http://www.ecma-international.org/ecma-262/6.0/#sec-execution-contexts Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

https://drafts.csswg.org/web-animations-1/#animation Referenced in:

- 3.3. Animation effects (2) (3)
- 3.3.3. Local time and inherited time (2)
- 3.5. Animation effect speed control (2) (3) (4) (5)
- 3.8. Grouping and synchronization (2)
- 4.1.1. Not animatable
- 4.3.1. The effect stack
- 5.1. The AnimationTimeline interface (2) (3) (4) (5)
- 5.2. The Animation interface (2)
- 5.3. The AnimationEffectReadOnly interface
- 5.8.2. Definitions for manipulating hierarchies (2)
- 5.13. The EffectCallback callback function (2)
- 5.14. The Animatable interface (2)

https://drafts.csswg.org/web-animations-1/#dom-animation-animation Referenced in:

- 5.1. The AnimationTimeline interface

https://drafts.csswg.org/web-animations-1/#animationtimeline Referenced in:

- 5.1. The AnimationTimeline interface (2)
- 5.2. The Animation interface (2)

https://drafts.csswg.org/web-animations-1/#keyframeeffect Referenced in:

- 5.5. The AnimationEffectTiming interface
- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces (2) (3) (4)

https://drafts.csswg.org/web-animations-1/#dictdef-keyframeeffectoptions Referenced in:

- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces
- 5.11.2. The KeyframeEffectOptions dictionary

https://drafts.csswg.org/web-animations-1/#active-interval Referenced in:

- 3.3.2. The active interval
- 3.2. Animations (2)
- 3.3.4. Animation effect phases and states
- 3.5. Animation effect speed control (2) (3)
- 3.8.1. Relationship of group time to child time (2) (3) (4) (5)
- 3.8.3. The intrinsic iteration duration of a group effect
- 3.8.4.1. The start time of children of a sequence effect (2) (3) (4)
- 5.4. The AnimationEffectTimingReadOnly interface (2)
- 5.7. The ComputedTimingProperties dictionary

https://drafts.csswg.org/web-animations-1/#active-phase Referenced in:

- 3.3.4. Animation effect phases and states (2) (3)
- 3.3.5. Fill modes (2)
- 3.6.3.1. Calculating the active time

https://drafts.csswg.org/web-animations-1/#active-time Referenced in:

- 3.2. Animations
- 3.6.1. Overview (2)
- 3.6.3.1. Calculating the active time
- 3.6.3.2. Calculating the overall progress (2)

https://drafts.csswg.org/web-animations-1/#after-phase Referenced in:

- 3.3.5. Fill modes (2) (3)
- 3.6.3.1. Calculating the active time (2) (3)

https://drafts.csswg.org/web-animations-1/#animation Referenced in:

- 3.3. Animation effects (2) (3)
- 3.3.3. Local time and inherited time (2)
- 3.5. Animation effect speed control (2) (3) (4) (5)
- 3.8. Grouping and synchronization (2)
- 4.1.1. Not animatable
- 4.3.1. The effect stack
- 5.1. The AnimationTimeline interface (2) (3) (4) (5)
- 5.2. The Animation interface (2)
- 5.3. The AnimationEffectReadOnly interface
- 5.8.2. Definitions for manipulating hierarchies (2)
- 5.13. The EffectCallback callback function (2)
- 5.14. The Animatable interface (2)

https://drafts.csswg.org/web-animations-1/#animation-effect Referenced in:

- 2. Changes since level 1
- 3.2.3. Waiting for the target effect
- 3.2.7. Speed control
- 3.3. Animation effects (2) (3) (4) (5)
- 3.3.1. Types of animation effects
- 3.3.2. The active interval (2)
- 3.2. Animations (2) (3) (4) (5) (6) (7)
- 3.3.3. Local time and inherited time (2) (3) (4) (5) (6) (7) (8) (9)
- 3.3.4. Animation effect phases and states (2) (3) (4) (5) (6) (7) (8) (9) (10) (11)
- 3.4.1. Iteration intervals
- 3.5. Animation effect speed control (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14)
- 3.6.1. Overview (2)
- 3.6.3.1. Calculating the active time
- 3.8. Grouping and synchronization (2) (3) (4) (5) (6) (7) (8) (9)
- 3.8.1. Relationship of group time to child time (2) (3) (4)
- 3.8.4.1. The start time of children of a sequence effect (2)
- 4.1.1. Not animatable (2)
- 4.5. Custom effects (2) (3) (4)
- 4.5.1. Sampling custom effects (2) (3) (4) (5)
- 4.5.2. Execution order of custom effects (2) (3) (4)
- 5.3. The AnimationEffectReadOnly interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14)
- 5.4. The AnimationEffectTimingReadOnly interface (2) (3) (4)
- 5.5. The AnimationEffectTiming interface
- 5.7. The ComputedTimingProperties dictionary (2) (3) (4) (5)
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2) (3) (4)
- 5.8.1. Processing a timing argument
- 5.8.2. Definitions for manipulating hierarchies (2)
- 5.9. The AnimationNodeList interface (2) (3)
- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces
- 5.11.1. Creating a new KeyframeEffect object
- 5.12. The IterationCompositeOperation enumeration (2)
- 5.14. The Animatable interface

https://drafts.csswg.org/web-animations-1/#animation-playback-rate Referenced in:

- 3.5. Animation effect speed control (2) (3) (4)

https://drafts.csswg.org/web-animations-1/#before-flag Referenced in:

- 3.7.1. Calculating the transformed progress

https://drafts.csswg.org/web-animations-1/#before-phase Referenced in:

- 3.3.4. Animation effect phases and states
- 3.3.5. Fill modes (2) (3)
- 3.6.3.1. Calculating the active time (2) (3)

https://drafts.csswg.org/web-animations-1/#cancel-an-animation Referenced in:

- 3.2.6. Canceling an animation

https://drafts.csswg.org/web-animations-1/#dom-keyframeeffect-composite Referenced in:

- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces

https://drafts.csswg.org/web-animations-1/#current-finished-promise Referenced in:

- 4.1.1. Not animatable

https://drafts.csswg.org/web-animations-1/#current-iteration Referenced in:

- 4.5. Custom effects
- 4.5.1. Sampling custom effects
- 5.12. The IterationCompositeOperation enumeration

https://drafts.csswg.org/web-animations-1/#current-time Referenced in:

- 3.3.3. Local time and inherited time

https://drafts.csswg.org/web-animations-1/#directed-progress Referenced in:

- 3.6.1. Overview (2)

https://drafts.csswg.org/web-animations-1/#end-delay Referenced in:

- 3.3.2. The active interval (2)
- 3.2. Animations
- 5.4. The AnimationEffectTimingReadOnly interface
- 5.7. The ComputedTimingProperties dictionary

https://drafts.csswg.org/web-animations-1/#fill-mode Referenced in:

- 3.3.4. Animation effect phases and states
- 3.5. Animation effect speed control
- 3.6.3.1. Calculating the active time (2) (3)

https://drafts.csswg.org/web-animations-1/#finished-play-state Referenced in:

- 3.3.4. Animation effect phases and states (2)

https://drafts.csswg.org/web-animations-1/#in-effect Referenced in:

- 4.5.1. Sampling custom effects (2) (3) (4) (5) (6)
- 5.7. The ComputedTimingProperties dictionary

https://drafts.csswg.org/web-animations-1/#iteration-count Referenced in:

- 3.6.1. Overview
- 3.6.2. Calculating the active duration (2)
- 3.8.1. Relationship of group time to child time (2) (3) (4) (5) (6) (7)

https://drafts.csswg.org/web-animations-1/#iteration-duration Referenced in:

- 3.4.1. Iteration intervals (2)
- 3.6.1. Overview (2)
- 3.6.2. Calculating the active duration (2)
- 3.6.3.2. Calculating the overall progress (2)
- 3.7.2. Calculating the transformed time (2)
- 3.8.1. Relationship of group time to child time
- 5.4. The AnimationEffectTimingReadOnly interface
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

https://drafts.csswg.org/web-animations-1/#iteration-progress Referenced in:

- 3.2.1. Setting the timeline of an animation
- 3.2.2. Setting the target effect of an animation
- 3.6.1. Overview (2) (3) (4)
- 4.5. Custom effects
- 4.5.1. Sampling custom effects (2) (3) (4)
- 5.13. The EffectCallback callback function

https://drafts.csswg.org/web-animations-1/#iteration-start Referenced in:

- 3.6.1. Overview

https://drafts.csswg.org/web-animations-1/#keyframe-effect Referenced in:

- 3.2.3. Waiting for the target effect
- 3.3.1. Types of animation effects
- 4.2.1. The effect value of a keyframe effect (2)
- 4.4. Effect accumulation
- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces
- 5.11.1. Creating a new KeyframeEffect object

https://drafts.csswg.org/web-animations-1/#not-animatable Referenced in:

- 4.1.1. Not animatable

https://drafts.csswg.org/web-animations-1/#overall-progress Referenced in:

- 3.6.1. Overview (2)
- 3.6.3.2. Calculating the overall progress

https://drafts.csswg.org/web-animations-1/#pause-an-animation Referenced in:

- 3.2.5. Pausing an animation (2)

https://drafts.csswg.org/web-animations-1/#pending-play-task Referenced in:

- 3.2.2. Setting the target effect of an animation

https://drafts.csswg.org/web-animations-1/#play-an-animation Referenced in:

- 3.2.4. Playing an animation
- 5.1. The AnimationTimeline interface

https://drafts.csswg.org/web-animations-1/#playback-direction Referenced in:

- 3.6.1. Overview
- 3.8.1. Relationship of group time to child time

https://drafts.csswg.org/web-animations-1/#ready Referenced in:

- 5.1. The AnimationTimeline interface

https://drafts.csswg.org/web-animations-1/#set-the-timeline-of-an-animation Referenced in:

- 5.2. The Animation interface

https://drafts.csswg.org/web-animations-1/#simple-iteration-progress Referenced in:

- 3.6.1. Overview (2)

https://drafts.csswg.org/web-animations-1/#dom-keyframeeffect-keyframeeffect-source-source Referenced in:

- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces

https://drafts.csswg.org/web-animations-1/#target-effect Referenced in:

- 3.2.2. Setting the target effect of an animation
- 3.2.3. Waiting for the target effect
- 3.2.5. Pausing an animation (2)
- 3.2.6. Canceling an animation
- 3.3. Animation effects (2)
- 3.5. Animation effect speed control
- 5.1. The AnimationTimeline interface (2)

https://drafts.csswg.org/web-animations-1/#target-element Referenced in:

- 4.5.1. Sampling custom effects (2) (3) (4) (5)
- 5.13. The EffectCallback callback function (2) (3) (4) (5)
- 5.14. The Animatable interface

https://drafts.csswg.org/web-animations-1/#target-property Referenced in:

- 4.2.1. The effect value of a keyframe effect
- 4.5.2. Execution order of custom effects

https://drafts.csswg.org/web-animations-1/#time-value Referenced in:

- 3.3.3. Local time and inherited time (2)
- 3.6.3.1. Calculating the active time (2) (3) (4) (5)

https://drafts.csswg.org/web-animations-1/#timeline Referenced in:

- 5.1. The AnimationTimeline interface
- 5.2. The Animation interface (2)

https://drafts.csswg.org/web-animations-1/#transformed-progress Referenced in:

- 3.6.1. Overview (2) (3)
- 3.7.2. Calculating the transformed time (2) (3)

https://drafts.csswg.org/web-animations-1/#unresolved Referenced in:

- 3.2.1. Setting the timeline of an animation
- 3.2.2. Setting the target effect of an animation (2)
- 3.2.6. Canceling an animation
- 3.3.3. Local time and inherited time (2) (3)
- 3.6.3.1. Calculating the active time (2) (3) (4) (5) (6)
- 3.7.2. Calculating the transformed time (2)
- 4.5.1. Sampling custom effects (2)

https://drafts.csswg.org/web-animations-1/#update-animations-and-send-events Referenced in:

- 4.5. Custom effects
- 4.5.1. Sampling custom effects

https://heycam.github.io/webidl/#Exposed Referenced in:

- 5.1. The AnimationTimeline interface
- 5.3. The AnimationEffectReadOnly interface
- 5.4. The AnimationEffectTimingReadOnly interface
- 5.5. The AnimationEffectTiming interface
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2)
- 5.9. The AnimationNodeList interface
- 5.10. The SequenceEffectReadOnly and SequenceEffect interfaces (2)

https://heycam.github.io/webidl/#NoInterfaceObject Referenced in:

- 5.3. The AnimationEffectReadOnly interface
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

https://heycam.github.io/webidl/#idl-double Referenced in:

- 5.4. The AnimationEffectTimingReadOnly interface (2)
- 5.5. The AnimationEffectTiming interface (2)
- 5.6. The AnimationEffectTimingProperties dictionary (2)
- 5.7. The ComputedTimingProperties dictionary (2)
- 5.13. The EffectCallback callback function

https://heycam.github.io/webidl/#dfn-throw Referenced in:

- 5.3. The AnimationEffectReadOnly interface (2) (3)
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2)
- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces

https://heycam.github.io/webidl/#idl-unsigned-long Referenced in:

- 5.9. The AnimationNodeList interface (2) (3)

### Terms defined by reference

- [css-easing-1] defines the following terms:
  - linear timing function
  - timing function
- [css-pseudo-4] defines the following terms:
  - CSSPseudoElement
- [css-values-4] defines the following terms:
  - value accumulation
- [CSS2] defines the following terms:
  - visibility
- [DOM] defines the following terms:
  - Element
- [ECMASCRIPT] defines the following terms:
  - code realms
  - execution contexts
- [WEB-ANIMATIONS-1] defines the following terms:
  - Animation
  - Animation(effect, timeline)
  - AnimationTimeline
  - KeyframeEffect
  - KeyframeEffectOptions
  - active interval
  - active phase
  - active time
  - after phase
  - animation
  - animation effect
  - animation playback rate
  - before flag
  - before phase
  - cancel an animation
  - composite
  - current finished promise
  - current iteration
  - current time
  - directed progress
  - end delay
  - fill mode
  - finished play state
  - in effect
  - iteration count
  - iteration duration
  - iteration progress
  - iteration start
  - keyframe effect
  - not animatable
  - overall progress
  - pause an animation
  - pending play task
  - play an animation
  - playback direction
  - ready
  - set the timeline of an animation
  - simple iteration progress
  - source
  - target effect
  - target element
  - target property
  - time value
  - timeline
  - transformed progress
  - unresolved
  - update animations and send events
- [WebIDL] defines the following terms:
  - Exposed
  - NoInterfaceObject
  - double
  - throw
  - unsigned long

## References

### Normative References

[CSS-EASING-1]
  Brian Birtles; Dean Jackson; Matt Rakow. CSS Easing Functions Level 1. 30 April 2019. CR. URL: https://www.w3.org/TR/css-easing-1/
[CSS-PSEUDO-4]
  Daniel Glazman; Elika Etemad; Alan Stearns. CSS Pseudo-Elements Module Level 4. 25 February 2019. WD. URL: https://www.w3.org/TR/css-pseudo-4/
[CSS-VALUES-4]
  Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 31 January 2019. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS2]
  Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 7 June 2011. REC. URL: https://www.w3.org/TR/CSS2/
[DOM]
  Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
  ECMAScript Language Specification. URL: https://tc39.github.io/ecma262/
[RFC2119]
  S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[WEB-ANIMATIONS-1]
  Brian Birtles; et al. Web Animations. 11 October 2018. WD. URL: https://www.w3.org/TR/web-animations-1/
[WebIDL]
  Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/

## IDL Index

    [Exposed=Window]
    partial interface AnimationTimeline {
        Animation play (optional AnimationEffectReadOnly? effect = null);
    };

    partial interface Animation {
                   attribute AnimationTimeline?       timeline;
    };

    [Exposed=Window]
    partial interface AnimationEffectReadOnly {
        // Timing hierarchy
        readonly attribute GroupEffectReadOnly?     parent;
        readonly attribute AnimationEffectReadOnly? previousSibling;
        readonly attribute AnimationEffectReadOnly? nextSibling;
    };

    [NoInterfaceObject]
    interface AnimationEffectMutable {
        void before (AnimationEffectReadOnly... effects);
        void after (AnimationEffectReadOnly... effects);
        void replace (AnimationEffectReadOnly... effects);
        void remove ();
    };

    [Exposed=Window]
    partial interface AnimationEffectTimingReadOnly {
        readonly attribute double                             playbackRate;
    };

    [Exposed=Window]
    partial interface AnimationEffectTiming : AnimationEffectTimingReadOnly {
        inherit attribute double                             playbackRate;
    };

    partial dictionary AnimationEffectTimingProperties {
        double playbackRate = 1.0;
    };

    partial dictionary ComputedTimingProperties : AnimationEffectTimingProperties {
        double startTime;
    };

    enum FillMode { "none", "forwards", "backwards", "both", "auto" };

    [Exposed=Window,
     Constructor (sequence? children,
                  optional (unrestricted double or AnimationEffectTimingProperties) timing)]
    interface GroupEffectReadOnly : AnimationEffectReadOnly {
        readonly attribute AnimationNodeList      children;
        readonly attribute AnimationEffectReadOnly? firstChild;
        readonly attribute AnimationEffectReadOnly? lastChild;
        GroupEffect clone ();
    };

    [NoInterfaceObject]
    interface GroupEffectMutable {
      void prepend (AnimationEffectReadOnly... effects);
      void append (AnimationEffectReadOnly... effects);
    };

    [Exposed=Window,
     Constructor (sequence? children,
                  optional (unrestricted double or AnimationEffectTimingProperties) timing)]
    interface GroupEffect : GroupEffectReadOnly {
    };
    GroupEffect implements AnimationEffectMutable;
    GroupEffect implements GroupEffectMutable;

    [Exposed=Window]
    interface AnimationNodeList {
        readonly attribute unsigned long length;
        getter AnimationEffectReadOnly? item (unsigned long index);
    };

    [Exposed=Window,
     Constructor (sequence? children,
                  optional (unrestricted double or AnimationEffectTimingProperties) timing)]
    interface SequenceEffectReadOnly : GroupEffectReadOnly {
        SequenceEffect clone ();
    };

    [Exposed=Window,
     Constructor (sequence? children,
                  optional (unrestricted double or AnimationEffectTimingProperties) timing)]
    interface SequenceEffect : SequenceEffectReadOnly {
    };
    SequenceEffect implements AnimationEffectMutable;
    SequenceEffect implements GroupEffectMutable;

    partial interface KeyframeEffect {
        attribute IterationCompositeOperation    iterationComposite;
    };

    KeyframeEffect implements AnimationEffectMutable;

    partial dictionary KeyframeEffectOptions {
        IterationCompositeOperation iterationComposite = "replace";
    };

    enum IterationCompositeOperation { "replace", "accumulate" };

    callback EffectCallback = void (double? progress,
                                    (Element or CSSPseudoElement) currentTarget,
                                    Animation animation);

## Issues Index

If new timeline is null, we should ensure that custom effects get called with an unresolved iteration progress (unless a subsequent change in the same script execution context makes this redundant). ↵
This is not quite right. If old effect is attached to another animation in the same task then we should probably not do an extra callback with unresolved.

The definition of when custom effects gets called needs to be audited and probably rewritten.

↵
The procedures for calling custom effects need to be reworked. Currently they probably involve calling too often for changes that could be coalesced. ↵
Currently timing functions that generate results outside the range [0, 1] will behave unexpectedly when applied to group effects, 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.

↵
Currently, the set of timing functions allowed on a group effect 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 group effects is considered at risk.

Alternatives are to either restrict timing functions on group effects 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.

See section 2 of the discussion from August 2013.

↵
This whole feature needs to be revisited. The current thinking is that rather than having custom effects, we should simply have an `onupdate` callback on each animation effect. That would allow, for example, augmenting an existing effect with a function that performs logging or triggers additional actions at certain times. With the current arrangement, doing this would require adding a parent group just to achieve this. ↵
It needs to be called whenever timing properties are updated too, right? ↵
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:

- Additional calling conditions could be defined to accommodate zero-width custom effects. For example, it could be required that the callback be called if (given infinite precision) there was a time between the previous and current update times that aligned with the custom effect.

- Instead of adding special calling conditions to custom effects, a new type of animation effect, Trigger, could be introduced. The trigger would only ever act as a zero-width custom effect as described above, its constructor would take a callback function, but not require a target or timing. It could also specify other calling conventions, for example whether it should only trigger in a specific playback direction.

↵
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? ↵
It has been suggested this method be renamed, or even removed (see TAG feedback). ↵
Need to define the start behavior when effect is null. ↵
Should this be `parentGroup`? ↵
The `remove()` method can be used to remove an effect from either its parent group or animation. Should we keep it in level 1 and define it simply as removing the animation from its animation? ↵
#directly-associated-with-an-animation Referenced in:

- 3.3. Animation effects (2) (3)
- 3.3.3. Local time and inherited time
- 3.3.4. Animation effect phases and states
- 3.8. Grouping and synchronization (2)
- 5.8.2. Definitions for manipulating hierarchies

#associated-with-an-animation Referenced in:

- 3.3.4. Animation effect phases and states
- 5.7. The ComputedTimingProperties dictionary

#animation-effect-start-time Referenced in:

- 3.3.2. The active interval
- 3.2. Animations (2) (3) (4) (5) (6) (7) (8)
- 3.3.3. Local time and inherited time (2) (3) (4) (5)
- 3.6.1. Overview
- 3.8.2. The start time of children of a group effect
- 3.8.4. Sequence effects
- 3.8.4.1. The start time of children of a sequence effect (2) (3) (4) (5) (6)
- 3.8.4.2. The intrinsic iteration duration of a sequence effect
- 5.4. The AnimationEffectTimingReadOnly interface (2)
- 5.7. The ComputedTimingProperties dictionary (2)

#start-delay Referenced in:

- 3.3.2. The active interval
- 3.2. Animations (2) (3) (4)
- 3.3.3. Local time and inherited time (2)
- 3.5. Animation effect speed control
- 3.6.1. Overview
- 3.6.3.1. Calculating the active time
- 3.8.4.1. The start time of children of a sequence effect (2) (3) (4) (5) (6)
- 5.4. The AnimationEffectTimingReadOnly interface
- 5.7. The ComputedTimingProperties dictionary

#end-time Referenced in:

- 3.2. Animations
- 3.8.3. The intrinsic iteration duration of a group effect
- 3.8.4.1. The start time of children of a sequence effect (2)
- 5.7. The ComputedTimingProperties dictionary

#inherited-time Referenced in:

- 3.2. Animations (2)
- 3.3.3. Local time and inherited time (2) (3) (4)
- 3.4.2. Iteration time space
- 3.6.1. Overview (2) (3)
- 3.8. Grouping and synchronization
- 5.7. The ComputedTimingProperties dictionary (2)

#local-time Referenced in:

- 3.2. Animations
- 3.3.3. Local time and inherited time (2) (3) (4)
- 3.4.2. Iteration time space
- 3.5. Animation effect speed control (2) (3)
- 3.6.1. Overview (2) (3) (4) (5) (6)
- 3.6.3.1. Calculating the active time (2)
- 5.4. The AnimationEffectTimingReadOnly interface

#in-play Referenced in:

- 3.3.4. Animation effect phases and states (2) (3) (4) (5) (6)
- 3.4.3. Interval timing

#current Referenced in:

- 3.3.4. Animation effect phases and states (2)

#intrinsic-iteration-duration Referenced in:

- 3.4.1. Iteration intervals (2)
- 3.8.3. The intrinsic iteration duration of a group effect (2) (3) (4)
- 3.8.4.2. The intrinsic iteration duration of a sequence effect (2) (3)
- 5.3. The AnimationEffectReadOnly interface
- 5.4. The AnimationEffectTimingReadOnly interface
- 5.11.1. Creating a new KeyframeEffect object

#animation-effect-playback-rate Referenced in:

- 2. Changes since level 1
- 3.2.7. Speed control
- 3.5. Animation effect speed control (2) (3) (4) (5) (6) (7) (8)
- 3.6.1. Overview (2)
- 3.6.2. Calculating the active duration (2)
- 3.6.3.2. Calculating the overall progress (2) (3) (4)
- 3.7.1. Calculating the transformed progress
- 3.8.1. Relationship of group time to child time
- 5.4. The AnimationEffectTimingReadOnly interface

#repeated-duration Referenced in:

- 3.6.2. Calculating the active duration (2) (3)

#active-duration Referenced in:

- 3.2. Animations
- 3.5. Animation effect speed control (2) (3)
- 3.6.1. Overview (2) (3)
- 3.6.2. Calculating the active duration
- 3.6.3.2. Calculating the overall progress
- 3.8.4.1. The start time of children of a sequence effect (2)

#transformed-time Referenced in:

- 3.3.3. Local time and inherited time
- 3.5. Animation effect speed control
- 3.7.2. Calculating the transformed time (2)
- 3.8.1. Relationship of group time to child time (2) (3) (4) (5)
- 5.7. The ComputedTimingProperties dictionary

#group-effect Referenced in:

- 2. Changes since level 1
- 3.3. Animation effects (2)
- 3.3.1. Types of animation effects
- 3.3.3. Local time and inherited time
- 3.4.1. Iteration intervals
- 3.7. Time transformations
- 3.8. Grouping and synchronization (2) (3) (4) (5)
- 3.8.1. Relationship of group time to child time (2) (3) (4) (5) (6) (7) (8) (9) (10)
- 3.8.2. The start time of children of a group effect (2)
- 3.8.3. The intrinsic iteration duration of a group effect (2)
- 3.8.4. Sequence effects (2) (3) (4) (5) (6) (7) (8) (9)
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2) (3) (4)

#child-effect Referenced in:

- 3.8. Grouping and synchronization (2) (3)
- 3.8.2. The start time of children of a group effect
- 3.8.3. The intrinsic iteration duration of a group effect (2) (3) (4)
- 3.8.4. Sequence effects (2)
- 3.8.4.1. The start time of children of a sequence effect
- 3.8.4.2. The intrinsic iteration duration of a sequence effect (2)
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces
- 5.8.2. Definitions for manipulating hierarchies (2) (3)

#parent-group Referenced in:

- 3.2.2. Setting the target effect of an animation (2)
- 3.3. Animation effects (2)
- 3.2. Animations (2) (3)
- 3.3.3. Local time and inherited time (2) (3)
- 3.3.4. Animation effect phases and states (2) (3) (4)
- 3.6.3.1. Calculating the active time (2) (3) (4) (5) (6)
- 3.8. Grouping and synchronization (2) (3)
- 5.3. The AnimationEffectReadOnly interface (2) (3) (4) (5) (6) (7) (8)
- 5.7. The ComputedTimingProperties dictionary (2)
- 5.8.2. Definitions for manipulating hierarchies (2) (3)

#tree-order Referenced in:

- 4.3.1. The effect stack

#root Referenced in:

- 3.3. Animation effects

#ancestor Referenced in:

- 3.3. Animation effects
- 3.3.5. Fill modes (2) (3)

#descendant Referenced in:

- 3.1.1. Hierarchical

#inclusive-ancestor Referenced in:

- 5.3. The AnimationEffectReadOnly interface (2) (3) (4)
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2)

#inclusive-descendant Referenced in:

- 3.2.2. Setting the target effect of an animation
- 3.2.3. Waiting for the target effect
- 3.2.6. Canceling an animation

#next-sibling Referenced in:

- 5.3. The AnimationEffectReadOnly interface
- 5.8.2. Definitions for manipulating hierarchies (2)

#previous-sibling Referenced in:

- 3.8.4.1. The start time of children of a sequence effect (2)
- 5.3. The AnimationEffectReadOnly interface

#first-child Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2)

#last-child Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

#sequence-effect Referenced in:

- 2. Changes since level 1
- 3.3.2. The active interval
- 3.2. Animations
- 3.5. Animation effect speed control
- 3.8.4. Sequence effects (2) (3) (4) (5) (6)
- 3.8.4.1. The start time of children of a sequence effect (2) (3) (4)
- 3.8.4.2. The intrinsic iteration duration of a sequence effect (2)
- 4.1.1. Not animatable
- 5.4. The AnimationEffectTimingReadOnly interface
- 5.10. The SequenceEffectReadOnly and SequenceEffect interfaces (2)

#iteration-composite-operation Referenced in:

- 4.2.1. The effect value of a keyframe effect
- 4.4. Effect accumulation (2)
- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces (2) (3)
- 5.11.2. The KeyframeEffectOptions dictionary
- 5.12. The IterationCompositeOperation enumeration (2)

#iteration-composite-operation-replace Referenced in:

- 5.12. The IterationCompositeOperation enumeration

#iteration-composite-operation-accumulate Referenced in:

- 4.2.1. The effect value of a keyframe effect
- 5.12. The IterationCompositeOperation enumeration

#custom-effect Referenced in:

- 2. Changes since level 1
- 3.2.1. Setting the timeline of an animation
- 3.2.2. Setting the target effect of an animation (2)
- 3.2.3. Waiting for the target effect
- 3.2.4. Playing an animation
- 3.2.5. Pausing an animation
- 3.2.6. Canceling an animation
- 4.5. Custom effects (2)
- 4.5.1. Sampling custom effects (2) (3)
- 4.5.2. Execution order of custom effects (2) (3)
- 5.13. The EffectCallback callback function

#dom-animationtimeline-play Referenced in:

- 5.1. The AnimationTimeline interface

#dom-animationtimeline-play-effect-effect Referenced in:

- 5.1. The AnimationTimeline interface

#dom-animation-timeline Referenced in:

- 5.2. The Animation interface

#animationeffectmutable Referenced in:

- 5.3. The AnimationEffectReadOnly interface
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces
- 5.10. The SequenceEffectReadOnly and SequenceEffect interfaces
- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces

#dom-animationeffectreadonly-parent Referenced in:

- 5.3. The AnimationEffectReadOnly interface

#dom-animationeffectreadonly-previoussibling Referenced in:

- 5.3. The AnimationEffectReadOnly interface

#dom-animationeffectreadonly-nextsibling Referenced in:

- 5.3. The AnimationEffectReadOnly interface

#dom-animationeffectmutable-before Referenced in:

- 5.3. The AnimationEffectReadOnly interface

#dom-animationeffectmutable-after Referenced in:

- 5.3. The AnimationEffectReadOnly interface

#dom-animationeffectmutable-replace Referenced in:

- 5.3. The AnimationEffectReadOnly interface

#dom-animationeffectmutable-remove Referenced in:

- 5.3. The AnimationEffectReadOnly interface

#dom-animationeffecttimingreadonly-playbackrate Referenced in:

- 5.4. The AnimationEffectTimingReadOnly interface
- 5.5. The AnimationEffectTiming interface

#dom-animationeffecttiming-playbackrate Referenced in:

- 5.5. The AnimationEffectTiming interface
- 5.6. The AnimationEffectTimingProperties dictionary

#dom-animationeffecttimingproperties-playbackrate Referenced in:

- 5.6. The AnimationEffectTimingProperties dictionary

#dom-computedtimingproperties-starttime Referenced in:

- 5.7. The ComputedTimingProperties dictionary

#groupeffectreadonly Referenced in:

- 5.3. The AnimationEffectReadOnly interface (2)
- 5.7.1. The FillMode enumeration
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2) (3) (4) (5) (6) (7)
- 5.10. The SequenceEffectReadOnly and SequenceEffect interfaces (2)

#groupeffectmutable Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2)
- 5.10. The SequenceEffectReadOnly and SequenceEffect interfaces

#groupeffect Referenced in:

- 5.5. The AnimationEffectTiming interface
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2) (3) (4) (5) (6) (7)
- 5.15. Model liveness

#dom-groupeffectreadonly-groupeffectreadonly Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces
- 5.8.1. Processing a timing argument

#dom-groupeffectreadonly-groupeffectreadonly-children-timing-children Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

#dom-groupeffectreadonly-groupeffectreadonly-children-timing-timing Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

#dom-groupeffect-groupeffect Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces
- 5.8.1. Processing a timing argument
- 5.10. The SequenceEffectReadOnly and SequenceEffect interfaces

#dom-groupeffectreadonly-children Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

#dom-groupeffectreadonly-firstchild Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

#dom-groupeffectreadonly-lastchild Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

#dom-groupeffectmutable-prepend Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

#dom-groupeffectmutable-append Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2)

#dom-groupeffectreadonly-clone Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces
- 5.10. The SequenceEffectReadOnly and SequenceEffect interfaces

#process-a-timing-argument Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces

#next-sibling-not-included Referenced in:

- 5.3. The AnimationEffectReadOnly interface (2)

#remove-an-animation-effect Referenced in:

- 3.2.2. Setting the target effect of an animation
- 5.3. The AnimationEffectReadOnly interface (2)
- 5.8.2. Definitions for manipulating hierarchies

#insert-children Referenced in:

- 5.3. The AnimationEffectReadOnly interface (2) (3)
- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2) (3)

#animationnodelist Referenced in:

- 5.8. The GroupEffectReadOnly and GroupEffect interfaces (2)
- 5.9. The AnimationNodeList interface

#dom-animationnodelist-length Referenced in:

- 5.9. The AnimationNodeList interface

#dom-animationnodelist-item Referenced in:

- 5.9. The AnimationNodeList interface

#sequenceeffectreadonly Referenced in:

- 5.10. The SequenceEffectReadOnly and SequenceEffect interfaces (2) (3)

#sequenceeffect Referenced in:

- 5.5. The AnimationEffectTiming interface
- 5.10. The SequenceEffectReadOnly and SequenceEffect interfaces (2) (3) (4) (5)

#dom-sequenceeffect-sequenceeffect Referenced in:

- 5.8.1. Processing a timing argument

#dom-sequenceeffectreadonly-sequenceeffectreadonly Referenced in:

- 5.8.1. Processing a timing argument

#dom-sequenceeffectreadonly-clone Referenced in:

- 5.10. The SequenceEffectReadOnly and SequenceEffect interfaces

#dom-keyframeeffect-iterationcomposite Referenced in:

- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces (2)

#dom-keyframeeffectoptions-iterationcomposite Referenced in:

- 5.11.2. The KeyframeEffectOptions dictionary

#iterationcompositeoperation Referenced in:

- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces

#enumdef-iterationcompositeoperation Referenced in:

- 5.11. The KeyframeEffectReadOnly and KeyframeEffect interfaces (2)
- 5.11.2. The KeyframeEffectOptions dictionary (2)

#callbackdef-effectcallback Referenced in:

- 5.13. The EffectCallback callback function (2)
- 5.15. Model liveness