TBD
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>
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:
<seq>
) where each step is
gated on certain conditions (e.g. mouse clicks or keyboard
presses).
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.
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>
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>
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 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:
beginElement
and beginElementAt
methods have been extended to allow applying an animation
definition to an arbitrary target element or in an arbitrary
context (for example, another document;
see ).
sample
event dispatched to animation elements, or
perhaps only those that don't specify any target elements.
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 [[!web-animations]], this specification does not make any normative reference to SMIL Animation.
Many of the features defined in this specification are defined in terms of the Web Animations [[!web-animations]] model which serves as a normative reference for this specification.
The following requirements for SVG2 still need to be integrated into this specification.
Corresponding resolutions:
<animateTransform type="matrix">
in SVG 2.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.
The timed elements defined by Animation Elements act as templates for creating animations and timing groups as defined by [[!web-animations]].
The relationship between timed elements and Web Animations' timed items is one-to-many since:
select="div.warning"
),
begin="2s; 5s; click"
),
reverse="mouseout"
), and
beginElement
and beginElementAt
methods
which will generate further timed items.
Example and diagram
Timing group elements can contain other timed elements to produce hierarchical tree structures. Such structures can be described using the following definitions:
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.
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 | Initial 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.
New instance are generated for a given timed element, current element, and either:
using the following procedure.
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.
TBD.
Need to define that this is ignored in template-contexts. It's
treated as if it was indefinite.
Generates new instances from this timed element.
The target element or context node is based on the first matching condition from below:
options
and options.target
are
not null
,options.target
as the target
element.options
and options.context
are
not null
,options.context
as the context
node.The return value is the set of generated timed items as returned by .
TBD.
Add sequence<Element>? targets = null
as well?
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?
Can you have use elements inside a par or seq that pull in other animation elements?
What is the behavior in general?
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.
Note that seeking behavior is well-defined even when the document has yet to start.
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.
Need to define the document time used when:
TimedElement
interface
Need to add ownerSVGElement
from
SVGElement
interface?
Add other attributes from SVGElement
for backwards
compatibility?
AnimationElement
interface