SVG supports the ability to change vector graphics over time. SVG content can be animated in the following ways:
SVG's animation elements were developed in collaboration with the W3C Synchronized Multimedia (SYMM) Working Group, developers of the Synchronized Multimedia Integration Language (SMIL) 2.1 Specification [SMIL 2.1].
SVG incorporates the animation features defined in the SMIL 2.1 specification and provides some SVG-specific extensions.
For an introduction to the approach and features available in any language that supports SMIL 2.1 Animation, see SMIL 2.1 Animation overview and SMIL 2.1 animation model. For the list of animation features which go beyond SMIL Animation, see SVG extensions to SMIL 2.1 Animation.
SVG is a host language in terms of SMIL 2.1 Animation and therefore introduces additional constraints and features as permitted by that specification. Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for SVG's animation elements and attributes are the SMIL 2.1 Animation Modules. Note that the SMIL timing engine is orthogonal to the rendering tree.
SVG supports the following four animation elements which are defined in the SMIL 2.1 Animation Modules:
'animate' | allows scalar attributes and properties to be assigned different values over time | ||
'set' | a convenient shorthand for 'animate', which is useful for assigning animation values to non-numeric attributes and properties, such as the 'visibility' property | ||
'animateMotion' | moves an element along a motion path | ||
'animateColor' | modifies the color value of particular attributes or properties over time |
Additionally, SVG includes the following compatible extensions to SMIL 2.1:
'animateTransform' | modifies one of SVG's transformation attributes over time, such as the 'transform' attribute | ||
'path' attribute | SVG allows any feature from SVG's path data syntax to be specified in a 'path' attribute to the 'animateMotion' element (SMIL 2.1 Animation only allows a subset of SVG's path data syntax within a 'path' attribute) | ||
'mpath' element | SVG allows an 'animateMotion' element to contain a child 'mpath' element which references an SVG 'path' element as the definition of the motion path | ||
'keyPoints' attribute | SVG adds a 'keyPoints' attribute to the 'animateMotion' to provide precise control of the velocity of motion path animations | ||
'rotate' attribute | SVG adds a 'rotate' attribute to the 'animateMotion' to control whether an object is automatically rotated so that its x-axis points in the same direction (or opposite direction) as the directional tangent vector of the motion path |
For compatibility with other aspects of the language, SVG uses IRI references via an 'xlink:href' attribute to identify the elements which are to be targets of the animations.
SMIL 2.1 Animation requires that the host language define the meaning for document begin and document end.
Example anim01 below demonstrates each of SVG's five animation elements.
<?xml version="1.0"?> <svg width="8cm" height="3cm" viewBox="0 0 800 300" xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"> <desc>Example anim01 - demonstrate animation elements</desc> <rect x="1" y="1" width="798" height="298" fill="none" stroke="blue" stroke-width="2" /> <!-- The following illustrates the use of the 'animate' element to animate a rectangles x, y, and width attributes so that the rectangle grows to ultimately fill the viewport. --> <rect xml:id="RectElement" x="300" y="100" width="300" height="100" fill="rgb(255,255,0)" > <animate attributeName="x" begin="0s" dur="9s" fill="freeze" from="300" to="0" /> <animate attributeName="y" begin="0s" dur="9s" fill="freeze" from="100" to="0" /> <animate attributeName="width" begin="0s" dur="9s" fill="freeze" from="300" to="800" /> <animate attributeName="height" begin="0s" dur="9s" fill="freeze" from="100" to="300" /> </rect> <!-- Set up a new user coordinate system so that the text string's origin is at (0,0), allowing rotation and scale relative to the new origin --> <g transform="translate(100,100)" > <!-- The following illustrates the use of the 'set', 'animateMotion', 'animateColor' and 'animateTransform' elements. The 'text' element below starts off hidden (i.e., invisible). At 3 seconds, it: * becomes visible * continuously moves diagonally across the viewport * changes color from blue to dark red * rotates from -30 to zero degrees * scales by a factor of three. --> <text xml:id="TextElement" x="0" y="0" font-family="Verdana" font-size="35.27" visibility="hidden" > It's alive! <set attributeName="visibility" to="visible" begin="3s" dur="6s" fill="freeze" /> <animateMotion path="M 0 0 L 100 100" begin="3s" dur="6s" fill="freeze" /> <animateColor attributeName="fill" from="rgb(0,0,255)" to="rgb(128,0,0)" begin="3s" dur="6s" fill="freeze" /> <animateTransform attributeName="transform" type="rotate" from="-30" to="0" begin="3s" dur="6s" fill="freeze" /> <animateTransform attributeName="transform" type="scale" from="1" to="3" additive="sum" begin="3s" dur="6s" fill="freeze" /> </text> </g> </svg>
At zero seconds | At three seconds | |
At six seconds | At nine seconds |
The sections below describe the various animation attributes and elements.
The following attributes are common to all animation elements and identify the target element for the animation. If the target element is not capable of being a target of the animation, then the animation is ignored.
Refer to the descriptions of the individual animation elements for any restrictions on what types of elements can be targets of particular types of animations.
<define name='svg.AnimateCommon.attr'> <ref name='svg.XLink.attr'/> <ref name='svg.Conditional.attr'/> </define>
Attribute definitions:
The following attributes identify the target attribute or property for the given target element whose value changes over time.
<define name='svg.AnimateAttributeCommon.attr'> <optional> <attribute name='attributeName' svg:animatable='false' svg:inheritable='false'><text/></attribute> </optional> <optional> <attribute name='attributeType' svg:animatable='false' svg:inheritable='false'> <choice> <value>XML</value> <value>CSS</value> <value>auto</value> </choice> </attribute> </optional> </define>
Attribute definitions:
The lacuna value is auto.
Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for this attribute is the SMIL 2.1 specification. In particular, see SMIL 2.1 Animation Modules: Specifying the animation target.
In the absence of style sheets (external style sheets, style element, style attribute) animation of presentation attributes is equivalent to animating the corresponding property. Thus, for properties listed in SVG Tiny 1.2, the same effect occurs from animating the presentation attribute with attributeType="XML" as occurs with animating the corresponding property with attributeType="CSS".
Example animns01 below shows a namespace prefix being resolved to a namespace name in the scope of the referencing element, and that namespace name being used (regardless of the prefix which happens to be used in the target scope) to identify the attribute being animated.
<?xml version="1.0" encoding="UTF-8"?> <svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>Demonstration of the resolution of namespaces for animation</title> <!-- at the point of definition, the QName a:href resolves to the namespace name "http://www.w3.org/1999/xlink" and the local name "href" --> <g xmlns:a="http://www.w3.org/1999/xlink"> <animate attributeName="a:href" xlink:href="#foo" dur="2s" to="two.png" fill="freeze"/> </g> <!-- at the point of use, the namespace name "http://www.w3.org/1999/xlink" happens to be bound to the namespace prefix 'b' while the prefix 'xlink' is bound to a different namespace name--> <g xmlns:b="http://www.w3.org/1999/xlink" xmlns:xlink="http://example.net/bar"> <image xml:id="foo" b:href="one.png" x="35" y="50" width="410" height="160"/> </g> </svg>
Paced animations assume a notion of distance between the various animation values defined by the 'to', 'from', 'by' and 'values' attributes. The following table explains how the distance between values of different types should be computed.
Distance is defined for types which can be expressed as a list of values, where each value is a vector of scalars in an n-dimensional space. For example, an angle value is a list of one value in a 1-dimensional space and a color is a list of 1 value in a 3-dimensional space.
Animation is based on the computed value of properties. Thus, keywords such as inherit which yield a computed value may be animated because the computed value is a scalar or list of scalars. For example, fill="inherit" may be animated if the computed value of fill is a color.
The following table uses the following notation to describe two values
for which a distance should be computed:
Va = {va0, va1, ..., van}
Vb = {vb0, vb1, ..., vbn}
Value Type | Description | Distance | Examples |
---|---|---|---|
angle, integer, length, coordinate | single 1-dimensional value.
va0[0] = scalarA vb0[0] = scalarB |
||VaVb|| = abs(scalarA- scalarB) | 'x' attribute on 'rect' stroke-width on <circle> |
color | single 3-dimensional value. va0[0] = colorA vb0[0] = colorB |
||VaVb|| = sqrt((colorA.getRed() - colorB.getRed())^2 + (colorA.getGreen() - colorB.getGreen())^2 + (colorA.getBlue() - colorB.getBlue())^2) | 'fill' attribute on 'ellipse' |
list of length |
n 1-dimensional values. | ||VaVb|| = sum(for i = 1 to n, abs(vai[0] - vbi[0])) / n | 'stroke-dasharray' on 'path' |
list of points | n 2-dimensional values | There is no defined formula to pace a list of points. The request to pace should be ignored and the value of linear used instead. | 'points' attribute on 'polygon' |
path | n 2-dimensional values where each value is a point in the path definition. | ||VaVb|| = sum(for i = 1 to n, dist(vai,vbi))
/ n dist(vai,vbi) = sqrt((vai[0] - vbi[0])^2 + (vai[1] - vbi[1])^2)) |
'd' on 'path' |
transform list | type: translate one 2-dimensional value va0[0] = txa va0[1] = tya vb0[0] = txb vb0[1] = tyb type: rotate one 1-dimensional value and 1 2-dimensional value va0[0] = angleA va1[0] = cxa va1[1] = cya vb0[0] = angleB vb1[0] = cxb vb1[1] = cyb type: scale two 1-dimensional values va0[0] = scaleXa va1[0] = scaleYa vb0[0] = scaleXb vb1[0] = scaleYb type: skewX, skewY single 1-dimension value va0[0] = skewXorYa vb0[0] = skewXorYb |
type: translate ||VaVb|| = dist(v_a0 ,v_b0 ) = sqrt((v_a0 [0] - v_b0 [0])^2 + (v_a0 [1] - v_b0 [1])^2)) type: rotate ||VaVb|| = (abs(angleA - angleB) + sqrt((v_a1 [0] - v_b1 [0])^2 + (v_a1 [1] - v_b1 [1])^2))) / 2 type: scale ||VaVb|| = (abs(scaleXa- scaleXb) + abs(scaleYa - scaleYb)) / 2 type: skewX, skewY ||VaVb|| = abs(skewXorYa- skewXorYb) |
'transform' attribute on 'g' using
'animateTransform' |
The following attributes are common to all animation elements and control the timing of the animation, including what causes the animation to start and end, whether the animation runs repeatedly, and whether to retain the end state the animation once the animation ends.
The timing attributes also applies to Media Elements.
<define name='svg.AnimateTiming.attr' combine='interleave'> <ref name='svg.AnimateTimingNoMinMax.attr'/> <optional><attribute name='min' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional><attribute name='max' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> </define> <define name='svg.AnimateTimingNoMinMax.attr' combine='interleave'> <ref name='svg.AnimateTimingNoFillNoMinMax.attr'/> <optional> <attribute name='fill' svg:animatable='false' svg:inheritable='false'> <choice> <value>remove</value> <value>freeze</value> </choice> </attribute> </optional> </define> <define name='svg.AnimateTimingNoFillNoMinMax.attr' combine='interleave'> <ref name='svg.AnimateBegin.attr'/> <optional><attribute name='dur' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional><attribute name='end' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional><attribute name='repeatCount' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional><attribute name='repeatDur' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional> <attribute name='restart' svg:animatable='false' svg:inheritable='false'> <choice> <value>always</value> <value>never</value> <value>whenNotActive</value> </choice> </attribute> </optional> </define> <define name='svg.AnimateBegin.attr' combine='interleave'> <optional><attribute name='begin' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> </define>
In the syntax specifications that follow, optional white space is indicated as "S", defined as follows:
S ::= (#x20 | #x9 | #xD | #xA)*
Attribute definitions:
begin
or end
to
identify whether to synchronize with the beginning or
active end of the referenced animation element.keydown
event corresponding to the
specified key. From a formal processing model perspective, accessKey is a
keydown
event listener on the document which behaves as if
stopPropagation()
and
preventDefault()
have both been invoked in the capture phase.
keydown
event
listener using "U+0051" as the target keyboard identifier string.
beginElement()
method call or a hyperlink targeted to
the element. (Hyperlink-based timing is described in
SMIL 2.1 Timing and Synchronization: Hyperlinks and timing.)endElement()
method call.f(t)
.f(t)
is defined to freeze the effect value at the
last value of the active duration. The animation effect
is "frozen" for the remainder of the document duration
(or until the animation is restarted - see
SMIL 2.1: Restarting animation ).The SMIL 2.1 specification defines the detailed processing rules associated with the above attributes. Except for any SVG-specific rules explicitly mentioned in this specification, the SMIL 2.1 specification is the normative definition of the processing rules for the above attributes.
This section is informative. For a normative reference of event-base element, see the SMIL 2.1 Animation Modules and the multimedia section of this specification. For declarative animation or 'discard' elements, the default event-base element is the animation target, which for elements with an 'xlink:href' attribute is the target IRI, and is otherwise the parent element. The default event-base element for all SVG Media elements (e.g. audio, video, animation) is the element itself. For all event-values that are prefaced with an Id-value, the event-base element is the element indicated by that id. Authoring Note: non-rendered elements such as the audio element cannot receive user-initiated pointer events, so it is recommended that authors specify a rendered element as the event-base element for such cases.
Clock values have a subsetted syntax of the clock values syntax in SMIL 2.1: Clock values:
Clock-val ::= Timecount-val Timecount-val ::= Timecount ("." Fraction)? (Metric)? Metric ::= "s" | "ms" Fraction ::= DIGIT+ Timecount ::= DIGIT+ DIGIT ::= [0-9]
For Timecount values, the default metric suffix is "s" (for seconds). No embedded white space is allowed in clock values, although leading and trailing white space characters will be ignored.
Clock values describe document time.
The following are examples of legal clock values:
30s
= 30
seconds 5ms
= 5
milliseconds 12.467
= 12 seconds and 467
millisecondsFractional values are just (base 10) floating point definitions of seconds. Thus:
00.5s = 500 milliseconds
The following attributes are common to elements 'animate', 'animateMotion', 'animateColor' and 'animateTransform'. These attributes define the values that are assigned to the target attribute or property over time. The attributes below provide control over the relative timing of keyframes and the interpolation method between discrete values.
<define name='svg.AnimateToCommon.attr' combine='interleave'> <optional><attribute name='to' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> </define> <define name='svg.AnimateValueCommon.attr'> <ref name='svg.AnimateToCommon.attr'/> <optional> <attribute name='calcMode' svg:animatable='false' svg:inheritable='false'> <choice> <value>discrete</value> <value>linear</value> <value>paced</value> <value>spline</value> </choice> </attribute> </optional> <optional><attribute name='values' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional><attribute name='keyTimes' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional><attribute name='keySplines' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional><attribute name='from' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional><attribute name='by' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> </define>
Attribute definitions:
The 'keyTimes' list semantics depends upon the interpolation mode:
x1 y1 x2 y2
, describing the
Bézier control points for one time segment. The
'keyTimes' values that define the associated
segment are the Bézier "anchor points", and the
'keySplines' values are the control points.
Thus, there must be one fewer sets of control points than
there are 'keyTimes'. The SMIL 2.1 specification defines the detailed processing rules associated with the above attributes. Except for any SVG-specific rules explicitly mentioned in this specification, the SMIL 2.1 specification is the normative definition of the processing rules for the above attributes.
The animation values specified in the animation element must be legal values for the specified attribute. Leading and trailing white space, and white space before and after semicolon separators, will be ignored.
All values specified must be legal values for the specified attribute (as defined in the associated namespace). If any values are not legal, they are considered to be unsupported and is processed as if they had not been specified.
If a list of 'values' is used, the animation will apply the values in order over the course of the animation. If a list of 'values' is specified, any 'from', 'to' and 'by' attribute values are ignored.
The processing rules for the variants of 'from'/ 'to'/'by' animations are described in Animation function values.
If a 'by' value is used on a non-scalar data type ( such as color or transform ), the starting 0 delta value is to be conceptually considered as ‘identity’.
The following figure illustrates the interpretation of the 'keySplines' attribute. Each diagram illustrates the effect of 'keySplines' settings for a single interval (i.e. between the associated pairs of values in the 'keyTimes' and 'values' lists.). The horizontal axis can be thought of as the input value for the unit progress of interpolation within the interval - i.e. the pace with which interpolation proceeds along the given interval. The vertical axis is the resulting value for the unit progress, yielded by the 'keySplines' function. Another way of describing this is that the horizontal axis is the input unit time for the interval, and the vertical axis is the output unit time. See also the section Timing and real-world clock times.
keySplines="0 0 1 1" (the default) | keySplines=".5 0 .5 1" |
||
keySplines="0 .75 .25 1" | keySplines="1 0 .25 .25" |
To illustrate the calculations, consider the simple example:
<animate dur="4s" values="10; 20" keyTimes="0; 1" calcMode="spline" keySplines={as in table} />
Using the 'keySplines' values for each of the four cases above, the approximate interpolated values as the animation proceeds are:
keySplines values | Initial value | After 1s | After 2s | After 3s | Final value |
---|---|---|---|---|---|
0 0 1 1 | 10.0 | 12.5 | 15.0 | 17.5 | 20.0 |
.5 0 .5 1 | 10.0 | 11.0 | 15.0 | 19.0 | 20.0 |
0 .75 .25 1 | 10.0 | 18.0 | 19.3 | 19.8 | 20.0 |
1 0 .25 .25 | 10.0 | 10.1 | 10.6 | 16.9 | 20.0 |
For a formal definition of Bézier spline calculation, see [FOLEY-VANDAM], pp. 488-491.
It is frequently useful to define animation as an offset or delta to an attribute's value, rather than as absolute values. A simple "grow" animation can increase the width of an object by 10 units:
<rect width="20" ...> <animate attributeName="width" from="0" to="10" dur="10s" additive="sum"/> </rect>
It is frequently useful for repeated animations to build upon the previous results, accumulating with each iteration. The following example causes the rectangle to continue to grow with each repeat of the animation:
<rect width="20" ...> <animate attributeName="width" from="0" to="10" dur="10s" additive="sum" accumulate="sum" repeatCount="5"/> </rect>
At the end of the first repetition, the rectangle has a width of 30 units. At the end of the second repetition, the rectangle has a width of 40 units. At the end of the fifth repetition, the rectangle has a width of 70 units.
For more information about additive animations, see SMIL 2.1: Additive animation. For more information on cumulative animations, see SMIL 2.1: Controlling behavior of repeating animation - Cumulative animation.
The following attributes are common to elements 'animate', 'animateMotion', 'animateColor' and 'animateTransform'.
<define name='svg.AnimateAdditionCommon.attr'> <optional> <attribute name='additive' svg:animatable='false' svg:inheritable='false'> <choice> <value>replace</value> <value>sum</value> </choice> </attribute> </optional> <optional> <attribute name='accumulate' svg:animatable='false' svg:inheritable='false'> <choice> <value>none</value> <value>sum</value> </choice> </attribute> </optional> </define>
Attribute definitions:
SVG allows both attributes and properties to be animated. If a given attribute or property is inheritable by descendants, then animations on a parent element such as a 'g' element has the effect of propagating the attribute or property animation values to descendant elements as the animation proceeds; thus, descendant elements can inherit animated attributes and properties from their ancestors.
The 'animate' element is used to animate a single attribute or property over time. For example, to make a rectangle repeatedly fade away over 5 seconds, you can specify:
<rect> <animate attributeType="CSS" attributeName="fill-opacity" from="1" to="0" dur="5s" repeatCount="indefinite" /> </rect>
Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for this element is the SMIL 2.1 specification. In particular, see SMIL 2.1: 'animate' element.
<define name='animate'> <element name='animate'> <ref name='animate.AT'/> <zeroOrMore><ref name='animateCommon.CM'/></zeroOrMore> </element> </define> <define name='animate.AT' combine='interleave'> <ref name='svg.Core.attr'/> <ref name='svg.AnimateCommon.attr'/> <ref name='svg.AnimateAttributeCommon.attr'/> <ref name='svg.AnimateTiming.attr'/> <ref name='svg.AnimateValueCommon.attr'/> <ref name='svg.AnimateAdditionCommon.attr'/> </define>
For a list of attributes and properties that can be animated using the 'animate' element, see Attributes and properties that can be animated.
In the case where an 'animate' element is animating a color value, the same calculation method as the 'animateColor' element is used. That is, 'animate' and 'animateColor' have identical behavior when animating colors.
The 'set' element provides a simple means of just setting the value of an attribute for a specified duration. It supports most attribute types, including those that cannot reasonably be interpolated, such as string and boolean values. The 'set' element is non-additive. The 'additive' and 'accumulate' attributes are not allowed, and will be ignored if specified.
Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for this element is the SMIL 2.1 specification. In particular, see SMIL 2.1: 'set' element.
<define name='set'> <element name='set'> <ref name='set.AT'/> <zeroOrMore><ref name='animateCommon.CM'/></zeroOrMore> </element> </define> <define name='set.AT' combine='interleave'> <ref name='svg.Core.attr'/> <ref name='svg.AnimateCommon.attr'/> <ref name='svg.AnimateAttributeCommon.attr'/> <ref name='svg.AnimateTiming.attr'/> <ref name='svg.AnimateToCommon.attr'/> </define>
Attribute definitions:
For a list of attributes and properties that can be animated using the 'set' element, see Attributes and properties that can be animated.
The 'animateMotion' element causes a referenced element to move along a motion path.
Any element that can take a transform attribute may have animateMotion applied to it. See the transform attribute for a list of these elements.
Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for this element is the SMIL 2.1 specification. In particular, see SMIL 2.1: 'animateMotion' element.
<define name='animateMotion'> <element name='animateMotion'> <ref name='animateMotion.AT'/> <zeroOrMore> <ref name='animateCommon.CM'/> </zeroOrMore> <optional> <ref name='mpath'/> </optional> <zeroOrMore> <ref name='animateCommon.CM'/> </zeroOrMore> </element> </define> <define name='animateMotion.AT' combine='interleave'> <ref name='svg.Core.attr'/> <ref name='svg.AnimateCommon.attr'/> <ref name='svg.AnimateTiming.attr'/> <ref name='svg.AnimateAdditionCommon.attr'/> <ref name='svg.AnimateValueCommon.attr'/> <optional><attribute name='path' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional><attribute name='keyPoints' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional><attribute name='rotate' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> <optional><attribute name='origin' svg:animatable='false' svg:inheritable='false'><text/></attribute></optional> </define>
Attribute definitions:
For 'animateMotion', the specified values for 'from', 'by', 'to' and 'values' consists of x, y coordinate pairs, with a single comma and/or white space separating the x coordinate from the y coordinate. For example, from="33,15" specifies an x coordinate value of 33 and a y coordinate value of 15.
If provided, the 'values' attribute must consists of a list of x, y coordinate pairs. Coordinate values are separated by at least one white space character or a comma. Additional white space around the separator is allowed. For example, values="10,20;30,20;30,40" or values="10mm,20mm;30mm,20mm;30mm,40mm". Each coordinate represents a <length>. Attributes 'from', 'by', 'to' and 'values' specify a shape on the current canvas which represents the motion path.
Two options are available which allow definition of a motion path using any of SVG's path data commands:
Note that SVG's path data commands can only contain values in user space, whereas 'from', 'by', 'to' and 'values' can specify coordinates in user space or using unit identifiers. See Units.
Note that any styling on the 'animateMotion' or 'mpath' elements does not affect the defined path. For example specifying a dashed stroke won't cause the animation to jump from dash to dash.
The various (x,y) points of the shape provide a supplemental transformation matrix onto the CTM for the referenced object which causes a translation along the x- and y-axes of the current user coordinate system by the (x,y) values of the shape computed over time. Thus, the referenced object is translated over time by the offset of the motion path relative to the origin of the current user coordinate system. The supplemental transformation is applied on top of any transformations due to the target element's 'transform' attribute or any animations on that attribute due to 'animateTransform' elements on the target element.
The 'additive' and 'accumulate' attributes apply to 'animateMotion' elements. Multiple 'animateMotion' elements all simultaneously referencing the same target element can be additive with respect to each other; however, the transformations which result from the 'animateMotion' elements are always supplemental to any transformations due to the target element's 'transform' attribute or any 'animateTransform' elements.
The default calculation mode ('calcMode') for 'animateMotion' is paced. This will produce constant velocity motion along the specified path. Note that while 'animateMotion' elements can be additive, it is important to observe that the addition of two or more paced (constant velocity) animations might not result in a combined motion animation with constant velocity.
When a 'path' is combined with discrete, linear or spline 'calcMode' settings, and if attribute 'keyPoints' is not provided, the number of values is defined to be the number of points defined by the path, unless there are "move to" commands within the 'path'. A "move to" command within the 'path' (i.e. other than at the beginning of the 'path' description) does not count as an additional point when dividing up the duration, or when associating 'keyTimes', 'keySplines' and 'keyPoints' values. When a 'path' is combined with a paced 'calcMode' setting, all "move to" commands are considered to have 0 length (i.e. they always happen instantaneously), and is not considered in computing the pacing.
For more flexibility in controlling the velocity along the motion path, the 'keyPoints' attribute provides the ability to specify the progress along the motion path for each of the 'keyTimes' specified values. If specified, 'keyPoints' causes 'keyTimes' to apply to the values in 'keyPoints' rather than the points specified in the 'values' attribute array or the points on the 'path' attribute.
The override rules for 'animateMotion' are as follows. Regarding the definition of the motion path, the 'mpath' element overrides the the 'path' attribute, which overrides 'values', which overrides 'from'/'by'/'to'. Regarding determining the points which correspond to the 'keyTimes' attributes, the 'keyPoints' attribute overrides 'path' , which overrides 'values', which overrides 'from'/'by'/'to'.
At any time t within a motion path animation of duration dur, the computed coordinate (x,y) along the motion path is determined by finding the point (x,y) which is t/dur distance along the motion path using the user agent's distance along the path algorithm.
The following example demonstrates the supplemental transformation matrices that are computed during a motion path animation.
Example animMotion01 shows a triangle moving along a motion path.
<?xml version="1.0"?> <svg width="5cm" height="3cm" viewBox="0 0 500 300" xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" xmlns:xlink="http://www.w3.org/1999/xlink" > <desc>Example animMotion01 - demonstrate motion animation computations</desc> <rect x="1" y="1" width="498" height="298" fill="none" stroke="blue" stroke-width="2" /> <!-- Draw the outline of the motion path in blue, along with three small circles at the start, middle and end. --> <path xml:id="path1" d="M100,250 C 100,50 400,50 400,250" fill="none" stroke="blue" stroke-width="7.06" /> <circle cx="100" cy="250" r="17.64" fill="blue" /> <circle cx="250" cy="100" r="17.64" fill="blue" /> <circle cx="400" cy="250" r="17.64" fill="blue" /> <!-- Here is a triangle which will be moved about the motion path. It is defined with an upright orientation with the base of the triangle centered horizontally just above the origin. --> <path d="M-25,-12.5 L25,-12.5 L 0,-87.5 z" fill="yellow" stroke="red" stroke-width="7.06" > <!-- Define the motion path animation --> <animateMotion dur="6s" repeatCount="indefinite" rotate="auto" > <mpath xlink:href="#path1"/> </animateMotion> </path> </svg>
At zero seconds | At three seconds | At six seconds |
The following table shows the supplemental transformation matrices that are applied to achieve the effect of the motion path animation.
After 0s | After 3s | After 6s | |
---|---|---|---|
Supplemental transform due to movement along motion path |
translate(100,250) | translate(250,100) | translate(400,250) |
Supplemental transform due to rotate="auto" |
rotate(-90) | rotate(0) | rotate(90) |
The 'mpath'
element is a sub element to the 'animateMotion' element (its only place in the document tree
is as a child of an 'animateMotion'). 'mpath' reference an external
'path' element
that will serve as the definition of the motion path.
Example:
<?xml version="1.0" encoding="UTF-8"?> <svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 80 60"> <desc>mpath example</desc> <path xml:id="mpathRef" d="M15,43 C15,43 36,20 65,33" fill="none" stroke="black" stroke-width="1"/> <animateMotion begin="0s" dur="6s" calcMode="linear" fill="freeze"> <mpath xlink:href="#mpathRef"/> </animateMotion> </svg>
<define name='mpath'> <element name='mpath'> <ref name='mpath.AT'/> <zeroOrMore><ref name='svg.Desc.group'/></zeroOrMore> </element> </define> <define name='mpath.AT' combine='interleave'> <ref name='svg.Core.attr'/> <ref name='svg.XLinkRequired.attr'/> </define>
Attribute definitions:
The 'animateColor' element specifies a color transformation over time.
Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for this element is the SMIL 2.1 specification. In particular, see SMIL 2.1: 'animateColor' element.
<define name='animateColor'> <element name='animateColor'> <ref name='animateColor.AT'/> <zeroOrMore><ref name='animateCommon.CM'/></zeroOrMore> </element> </define> <define name='animateColor.AT' combine='interleave'> <ref name='svg.Core.attr'/> <ref name='svg.AnimateCommon.attr'/> <ref name='svg.AnimateAttributeCommon.attr'/> <ref name='svg.AnimateTiming.attr'/> <ref name='svg.AnimateValueCommon.attr'/> <ref name='svg.AnimateAdditionCommon.attr'/> </define>
The 'from', 'by' and 'to' attributes take color values, where each color value is expressed using the following syntax (the same syntax as used in SVG's properties that can take color values):
<color> | currentColor | none | inherit
In the case of 'currentColor' and 'inherit', if these evaluate to a color then all animation modes may be used. Otherwise, and in the case where 'none' is specified, only discrete animation may be used.
The 'values' attribute for the 'animateColor' element consists of a semicolon-separated list of color values, with each color value expressed in the above syntax.
Out of range color values can be provided, but user agent processing will be implementation dependent. User agents should clamp color values to allow color range values as late as possible, but note that system differences might preclude consistent behavior across different systems.
For a list of attributes and properties that can be animated using the 'animateColor' element, see Attributes and properties that can be animated.
The 'animateTransform' element animates a transformation attribute on a target element, thereby allowing animations to control translation, scaling, rotation and/or skewing.
<define name='animateTransform'> <element name='animateTransform'> <ref name='animateTransform.AT'/> <zeroOrMore><ref name='animateCommon.CM'/></zeroOrMore> </element> </define> <define name='animateTransform.AT' combine='interleave'> <ref name='svg.Core.attr'/> <ref name='svg.AnimateCommon.attr'/> <ref name='svg.AnimateAttributeCommon.attr'/> <ref name='svg.AnimateTiming.attr'/> <ref name='svg.AnimateValueCommon.attr'/> <ref name='svg.AnimateAdditionCommon.attr'/> <ref name='svg.AnimateTypeCommon.attr'/> </define>
Attribute definitions:
The 'from', 'by' and 'to' attributes take a value expressed using the same syntax that is available for the given transformation type:
The 'values' attribute for the 'animateTransform' element consists of a semicolon-separated list of values, where each individual value is expressed as described above for 'from', 'by' and 'to'.
The underlying value of transform animations (see SMIL discussion of animation function values) is the corresponding identity transformation value. Thus, the underlying value for
Note that this results in counter-intuitive results for a to animation. Since the underlying value is identity, and the 'additive' attribute is ignored on to animations according to SMIL, such animations will behave like a non-additive from-to animation where the "from" value is identity.
If 'calcMode' has the value paced, then the "distance" for the transformation is calculated consisting of the sum of the absolute values of the differences between each pair of values as further described in Paced animations and complex types.
When an animation is active, the effect of non-additive 'animateTransform' (i.e. additive="replace") is to replace the given attribute's value with the transformation defined by the 'animateTransform'. The effect of additive (i.e. additive="sum") is to post-multiply the transformation matrix corresponding to the transformation defined by this 'animateTransform'. To illustrate:
<rect transform="skewX(30)"...> <animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0" to="90" dur="5s" additive="replace" fill="freeze"/> <animateTransform attributeName="transform" attributeType="XML" type="scale" from="1" to="2" dur="5s" additive="replace" fill="freeze"/> </rect>
In the code snippet above, because the both animations have additive="replace", the first animation overrides the transformation on the rectangle itself and the second animation overrides the transformation from the first animation; therefore, at time 5 seconds, the visual result of the above two animations would be equivalent to the following static rectangle:
<rect transform="scale(2)" ... />
whereas in the following example:
<rect transform="skewX(30)"...> <animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0" to="90" dur="5s" additive="sum" fill="freeze"/> <animateTransform attributeName="transform" attributeType="XML" type="scale" from="1" to="2" dur="5s" additive="sum" fill="freeze"/> </rect>
In this code snippet, because both animations have additive="sum", the first animation post-multiplies its transformation to any transformations on the rectangle itself and the second animation post-multiplies its transformation to any transformation from the first animation; therefore, at time 5 seconds, the visual result of the above two animations would be equivalent to the following static rectangle:
<rect transform="skewX(30) rotate(90) scale(2)" ... />
For a list of attributes and properties that can be animated using the 'animateTransform' element, see Attributes and properties that can be animated.
Each attribute or property within this specification
indicates whether or not it can be animated by SVG's animation
elements. Animatable attributes and properties are designated
as follows:
Animatable:
yes.
whereas attributes and properties that cannot be animated are
designated:
Animatable:
no.
SVG has a defined set of basic data types for its various supported attributes and properties. For those attributes and properties that can be animated, the following table indicates which animation elements can be used to animate each of the basic data types.
If the computed value of a given attribute or property and the values specified in an animation can all be converted to numeric values, then additive animations are possible; however, if the animation or base value uses one or more keyword values which cannot be converted to a numeric value, additive animation is not possible.
In the example below, the fill has a base value of "currentColor" and is animated from "red" to "#DDF". The value of the color property is yellow.
<rect color="yellow" fill="currentColor"> <animateColor attributeName="fill" from="red" to="#DDF" begin="1s" dur="5s" fill="freeze"/> </rect>
The animation can be additive, because the computed value of the fill is yellow, which can be converted to an RGB color which is a triple of numeric values (255, 255, 0); the keyword "red" can likewise be converted to an RGB color which is a triple of numeric values (255, 0, 0) as can the value "#DDF" which corresponds to(221, 221, 255). Had any of these values been keywords which could not be converted to a numeric representation - for example "none" or "url(#foo)" - then the animation could not have been additive.
Note: all animations that are additive are also cumulative.
Data type | Additive? | 'animate' | 'set' | 'animate Color' |
'animate Transform' |
Notes |
---|---|---|---|---|---|---|
<color> | yes | yes | yes | yes | no | Only additive if each value can be converted an RGB color. |
<coordinate> | yes | yes | yes | no | no | |
<integer> | yes | yes | yes | no | no | |
<length> | yes | yes | yes | no | no | |
<list of xxx> | no | yes | yes | no | no | |
<number> | yes | yes | yes | no | no | |
<paint> | yes | yes | yes | yes | no | Only additive if each value can be converted an RGB color. |
<transform> | yes | no | no | no | yes | Additive means that a transformation is post-multiplied to the base set of transformations. |
<XMLRI> | no | yes | yes | no | no | |
All other data types used in animatable attributes and properties | no | yes | yes | no | no |
Any deviation from the above table or other special note about the animation capabilities of a particular attribute or property is included in the section of the specification where the given attribute or property is defined.
Example dom_animate shows a simple animation using the DOM.
<?xml version="1.0"?> <svg width="4cm" height="2cm" viewBox="0 0 400 200" xml:id="root" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"> <desc>A simple animation using the uDOM and the Timer interface of the uDOM.</desc> <script type="application/ecmascript"><![CDATA[ var timeValue = 0; var timerIncrement = 50; var maxTime = 5000; var textElement; var svgRoot; var mytimer; // We need a "class" that "implements" the EventListener interface // (i.e. have an handleEvent method) SomeListenerClass.prototype = new Object(); function SomeListenerClass() {} SomeListenerClass.prototype.handleEvent = function(evt) { if (evt.target == mytimer) { showAndGrowElement(); } } function init() { textElement = document.getElementById("svgtext"); svgRoot = document.getElementById("root"); launchTimer(); } function launchTimer() { // Fire timer event as soon as possible, initialInterval = 0 // Timer event must be sent every 50 ms, repeatInterval = 50 someTimer = createTimer(0 , 50); // Instantiate the listener object var someListenerObject = new SomeListenerClass(); // Add a listener for the "SVGTimer" event someTimer.addEventListener("SVGTimer", someListenerObject, false); // Start the timer. Which will fire the first event immediately as initialInterval is 0. someTimer.start(); } function showAndGrowElement() { timeValue += timerIncrement; // Scale the text string gradually until it is 20 times larger scalefactor = (timeValue * 20.) / maxTime; var matrix = svgRoot.createSVGMatrixComponents(scalefactor, 0, 0, scalefactor, 0, 0); textElement.setMatrixTrait("transform", matrix); // Make the string more opaque var opacityFactor = timeValue / maxTime; textElement.setFloatTrait("fill-opacity", opacityFactor); if (timeValue >= maxTime) someTimer.stop(); } ]]></script> <handler type="application/ecmascript" ev:event="load"> init(); </handler> <rect x="1" y="1" width="398" height="198" fill="none" stroke="blue" stroke-width="2"/> <g transform="translate(50,150)" font-size="7" stroke="none"> <text fill="red" fill-opacity="0" xml:id="svgtext">SVG</text> </g> </svg>
At zero seconds | At 2.5 seconds | At five seconds |
The above SVG file contains a 'text' element that says "SVG". The animation loops for 5 seconds. The text string starts out small and transparent and grows to be large and opaque. Here is an explanation of how this example works:
<handler type="application/ecmascript" ev:event="load"> init(); </handler>Once the document has been fully loaded and processed, this 'handler' invokes the ECMAScript function
init()
.init()
function is only called once to give a value to global variables textElement
and svgRoot
and to create and launch a Timer
object via the launchTimer()
method. showAndGrowElement()
sets the transform
and fill-opacity
attributes on the text element to new values each time it is called.launchTimer()
method and given as a parameter of the addEventListener()
on the timer object so that the handleEvent()
is called each time an 'SVGTimer' event is triggered (the 'someTimer' object is the only target of this event). This way, it is possible to register a listener on a timer object using scripting.showAndGrowElement()
is called every 50
milliseconds and changes the text attributes thereby animating the text. showAndGrowElement()
checks each time it is invoked whether the maximum duration of the animation has been reached and calls the stop()
method on the timer
object when this happens, so that the animation stops.
If an attribute/property value is modified while an animation element is animating the same attribute/property, the animations are required to adjust dynamically to the new value.
The effects of animation may affect the bounding box of animated elements. For details on this, see the definition for the bounding box.