This specification defines an element-based markup for defining animation and time-related changes to a Web page. It is intended to replace the animation features of SVG 1.1 by building on the model defined in Web Animations.

Introduction

TBD

Use cases

Tweening and cutout animation

A common animation technique involves taking some graphical elements and interpolating their properties such as position or color or moving them along a path. This is sometimes referred to as cutout animation since the moving parts were traditionally represented by separate shapes cut from cardboard or similar material.

For example, in the following segment of a cartoon, a golfer swings his arms (and club!) and as a result the golf ball follows a trajectory through the air before bouncing along the ground.

<path id="golferBody" d="…"/> 
<g id="armsAndClub">
  <path id="club" d="…"/> 
  <path id="arms" d="…"/> 
</g>
<circle id="ball" …/>
<seq>
  <!-- Rotate man's arms and club -->
  <animate href="armsAndClub" attributeName="transform"
    values="rotate(0); rotate(-120); rotate(30); rotate(0)"
    keyTimes="0; 0.5; 0.8; 1" additive="sum" dur="1.2s"/>
  <!-- Show course of ball -->
  <animateMotion href="ball" begin="-0.312s" path="…"/>
</seq>
        

Timesheets

In simple examples such as the above cartoon, it is useful to represent graphical content and timing side-by-side. However, for applications that involve complex sequencing of effects it is often convenient to separate the temporal markup into a separate subtree or document sometimes referred to as a “timesheet”—the temporal equivalent of a stylesheet.

Such a timesheet may define animations directly or simply set classes and define the animation effects using, for example, CSS Animations [[CSS3-ANIMATIONS]].

For example, the title screen and first scene of an interactive story might use the following timesheet:

<!-- Title screen -->
<seq begin="0s">
  <!-- Draw curtains to the side -->
  <par>
    <animate href="leftCurtain" attributeName="transform"
      to="translate(-100 0)" dur="1s" additive="sum"/>
    <animate href="rightCurtain" attributeName="transform"
      to="translate(100 0)" dur="1s" additive="sum"/>
  </par>
  <!-- Then show the title by setting a class which may trigger,
       for example, a fade animation defined in CSS -->
  <set href="title" attributeName="class" to="active"/>
</seq>

<!-- Show the first scene when the user clicks the title screen -->
<seq begin="titleScreen.click" restart="whenNotActive">
  <!-- Cross fade to show background -->
  <par>
    <animate href="titleScreen" attributeName="opacity" to="0" dur="1s"/>
    <animate href="scene1Background" attributeName="opacity" to="1" dur="1s"/>
  </par>
  <!-- Move narrator onstage -->
  <animate href="narrator" attributeName="transform"
    to="translate(180 90)" dur="0.3s"/>
  <!-- Set the active class on the narrator which may trigger further
       animations or perhaps update the pointer-events property so he
       becomes clickable-->
  <set href="narrator" attributeName="class" to="active"/>
</seq>
        

The triggers for these effects can be defined declaratively as in the example above or they can be applied using script (see the beginElement and beginElementAt methods).

For more complex usage such as an interactive comic book the following features would be useful:

  • Ability to define a “sequence” (which may or may not be a type of <seq>) where each step is gated on certain conditions (e.g. mouse clicks or keyboard presses).
  • Ability to step backwards through such a sequence.
  • Ability to define alternative animations when stepping backwards.
  • Ability to step forwards causing the current in-play step to skip to its end and triggering the next step.
  • Ability to hyperlink to a particular step (including when steps when such steps are nested)

The features currently defined in this specification can be used to realize some of these sort of use cases but typically it is quite cumbersome.

It is possible to extend this specification to cover the above features or we can defer it and introduce a more fully-featured state tracking feature in a subsequent version.

Round-trip ad-hoc animation

When performing DOM manipulation, it is often useful to attach animation to an element in such a form that it can be serialized for later playback and editing.

For example, a presentation authoring tool allows a user to select items on a slide and tween their various properties at different times or in response to events such as mouse clicks. This could be achieved by annotating the element in question with a child element as follows:

<image>
  <animate begin="3s" dur="1s" attributeName="opacity" to="1" fill="forwards"/>
</image>
        

In many cases, such an approach is easier to generate and re-parse than doing so with stylesheet animation:

<image>
  <style scoped>
    image {
      animation: fadeIn 1s 3s forwards;
    }
    @keyframes fadeIn {
      to {
        opacity: 1.0;
      }
    }
  </style>
</image>
        

Frame-based animation

Rather than smoothly tweening values, sometimes it is desirable to overlay a series of independent images in quick succession.

For example, a children's workshop teaching animation principles allows children to draw a series of similar images and then show and hide them in turn creating the illusion of movement.

Supposing each drawn image is contained in an SVG <g> element, the animation could be produced as follows:

  <!-- Graphical content -->
  <g class="frame" visibility="hidden">…</g>
  <g class="frame" visibility="hidden">…</g>
  <g class="frame" visibility="hidden">…</g>
  <g class="frame" visibility="hidden">…</g>

  <!-- Timing -->
  <seq repeatCount="indefinite">
    <set select=".frame" dur="0.2s" attributeName="visibility" to="visible"/>
  </seq>
        

Animated user interface widgets

User interface widgets are often accompanied by animated effects that provides affordances to the user. These effects should be defined in a manner that allows re-use across a variety of similar widgets.

For example, following is a re-usable definition of mouse hover effects applied to some content representing a button.

<!-- A button-like object -->
<g role="button">
  <rect … />
  <text filter="child">
    <filter … />…<feGaussianBlur … /></filter>
    Button label
  </text>
</g>

<!-- A complex mouseover effect -->
<par select="g[role=button]" begin="mouseover" end="mouseout">
  <!-- Tween background color of button -->
  <animate select="rect" attributeName="fill" to="blue" dur="0.3s" fill="forwards"/>
  <seq>
    <!-- Wiggle text to the side -->
    <animate select="text" attributeName="transform" dur="0.3s"
      additive="sum" values="translate(0); translate(-10); translate(0)"/>
    <!-- Then make it glow by tweaking part of the filter -->
    <animate select="feGaussianBlur" attributeName="stdDeviation"
      from="0" to="2" fill="forwards" dur="0.3s"/>
  </seq>
</par>

<!-- Fade out button background on mouseout -->
<par select="g[role=button]" begin="mouseout" end="mouseover; indefinite">
  <animate select="rect" begin="mouseout" attributeName="fill"
    to="navy" dur="0.3s" fill="forwards"/>
  <set select="feGaussianBlur" attributeName="stdDeviation" to="0"/>
</par>
        
This use case would also benefit from the custom reversing suggested for timesheets / interactive comics.

Relationship to SVG 1.1 Animation

This specification is intended to be backwards-compatible with the animation features defined in SVG 1.1 Second Edition [[SVG11]] with the following exceptions:

The following features defined in SVG 1.1 have been deprecated in this specification:

The following additional features not present in SVG 1.1 have been added to this specification:

Link the above to the appropriate sections once they have been written.
Add support for Web Animations custom effects—perhaps through a sample event dispatched to animation elements, or perhaps only those that don't specify any target elements.

Relationship to SMIL Animation

To the extent that this specification is backwards-compatible with SVG 1.1's animation features, most of which are defined in terms of SMIL Animation [[SMIL-ANIMATION]], this specification defines many features similar to those defined in SMIL Animation. However, since such features are fully-defined either in this specification or in Web Animations [[!WEBANIMATIONS]], this specification does not make any normative reference to SMIL Animation.

Relationship to Web Animations

Many of the features defined in this specification are defined in terms of the Web Animations [[!WEBANIMATIONS]] model which serves as a normative reference for this specification.

Timed elements

This specification defines a number of elements that share common timing behavior referred to as timed elements. The common timing features of timed elements are described first followed by the specific elements.

Introduction

The timed elements defined by Animation Elements act as templates for creating animations and timing groups as defined by [[!WEBANIMATIONS]].

The relationship between timed elements and Web Animations' timed items is one-to-many since:

Example and diagram

Timed element hierarchies

Timing group elements can contain other timed elements to produce hierarchical tree structures. Such structures can be described using the following definitions:

parent timed element
For a given timed element A, the first timed element, if any, encountered when traversing the list of ancestor elements [[!DOM4]] beginning with the parent [[!DOM4]] of A and without leaving the current SVG context [[!SVG2]].
child timed element
A timed element whose parent timing group is this timed element.
root timed element
A timed element with no parent timed element.

Namespace

The timed elements defined in this specification belong to the SVG namespace as defined in [[!SVG11]].

If SVG2 allows SVG elements to exist outside the SVG namespace then we will reflect that here as well.

Furthermore, SVG2 aside, it may be worth investigating allowing these elements directly in HTML.

Attributes to identify the target elements for a timed element

Each timed element may specify a set of target elements which are used to determine:

When we add media reference elements, the target elements will be used to establish the source media element when not explicitly set.

Each element in the list of target elements may have an associated context element which represents the scope in which the reference to the target element was resolved. Each pair of a target element and optional context element is unique within the list of target elements.

The following attributes are the target element attributes which specify the target elements for a timed element.

Attribute definitions:

Name Value Lacuna value Animatable
select <selector-list> (none) No
href local IRI (none) No
xlink:href local IRI (none) No

A timed element where one or more of the target element attributes is specified is said to have a specified target. The list of target elements of a timed element without a specified target is an empty list.

If more than one of the target element attributes is specified then the attribute with the highest precedence is used even if its value is empty or invalid; the other attributes are ignored. select has the highest precedence followed by href then xlink:href.

A set of target elements is resolved with reference to a given context node which may be either an element or a document.

The href and xlink:href attributes specify an element belonging to the same document as the context node's node document. The syntax is that of a fragment identifier including the leading hash (#, U+0023) but without an absolute IRI or relative IRI as defined by [[!IRI]]. For example, #button12. The fragment identifier is interpreted as an ID reference which is resolved using the same definition for getElementById from [[!DOM4]] with the context node as the context object. If no element matches the ID reference or it is malformed, the resulting set of target elements is an empty list.

The select attribute specifies a CSS selector list [[!SELECTORS4]] that is matched against the subtree beginning with the context node using the same procedure as for querySelectorAll [[!SELECTORS-API2]]. If no element matches or the selector list is malformed, the resulting set of target elements is an empty list.

select should match content inside a seamless iframe

Describe how to handle changes to what is selected (including an iframe becoming seamless or not).

Describe how to handle dynamic changes to the attributes.

Generating new instances

New instance are generated for a given timed element, current element, and either:

using the following procedure.

  1. Initialize the list of target elements based on the first matching condition from the following:
    If an initial target is provided,
    Let target elements be a list consisting of a single element, initial target.
    If element has a specified target,
    Let target elements be the result of evaluating the current element's target element attributes as defined in using current context as the context node.
    Otherwise,
    Let target elements be a list consisting of a single element, current context.
  2. Let generated items be an empty list.
  3. For each element, current target, in target elements:
    1. Let current item be the result of generating a timed item for the specific type of current element as defined in and so on (TBD: add specific references here to other sections as they are added). The context node to be passed in each case is current target.
    2. If current element is a group timing element, then for each child timed item, current child of current element perform the following steps:
      1. Recursively apply this procedure (i.e. with current child as the context node.
      2. Append the resulting list of timed items to current item's list of child timed items.
    3. Append current item to generated items.
  4. Return generated items.

Make a section about interval handling where we say that when the conditions match, we call the above procedure using the node document of the timed element as the context node. For external timesheets we'll need to override it.

Attributes to control the triggering of timed elements

The begin attribute

TBD.
Need to define that this is ignored in template-contexts. It's treated as if it was indefinite.

Attributes to control timing

Timed element interfaces

sequence<TimedItem> beginElement(optional BeginElementOptions options)

Generates new instances from this timed element.

The target element or context node is based on the first matching condition from below:

If options and options.target are not null,
Use options.target as the target element.
If options and options.context are not null,
Use options.context as the context node.
Otherwise,
Use the node document of this element as the context node.

The return value is the set of generated timed items as returned by .

sequence<TimedItem> beginElementAt(float offset, optional BeginElementOptions options)

TBD.

Element? target = null
(Element or Document)? context = null
BeginElementAtReferenceTime since = "now"

Add sequence<Element>? targets = null as well?

now
start

Animation elements

Attributes to identify the target attribute or property for an animation

Attributes that define animation values over time

Attributes that control whether animations are additive

Elements, attributes and properties that can be animated

Generating an instance of an animation element

Animation elements generate animations.

The target element of the generated animation is the context node provided when the animation was generated, provided it is an element. If the context node is a document the target element is the parent element of the animation element's root timed element.

What if the root timed element is not in the same document as the context node? Generate the animation with no target element? Abort?

The animate element

The set element

The animateMotion element

Timing group elements

The par element

The seq element

Structural elements

The discard element

Deprecated elements

The animateTransform element

Integration with SVG

Start of the timeline

The svg element

Reclaiming resources

Animations in elements referenced by a use element

Can you have use elements inside a par or seq that pull in other animation elements?

What is the behavior in general?

Integration with Media Fragments

The Media Fragments specification [[!MEDIA-FRAGMENTS]] defines a means for addressing a temporal range of a media resource. The application of the temporal parameters to documents with the SVG MIME type [[!SVG11] is as follows.

What happens if the fragment is changed after the document has loaded

Note that media fragments are defined to operate on resources based on their MIME type. As a result, temporal addressing may not have any effect for SVG content that is served in a document with a MIME type other than the SVG MIME type such as SVG embedded in HTML.

Resources in other documents

Need to define the document time used when:

DOM interfaces

The TimedElement interface

Need to add ownerSVGElement from SVGElement interface?

Add other attributes from SVGElement for backwards compatibility?

The AnimationElement interface

Reflecting changes to the DOM