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) 1.0 Specification [SMIL1].
The SYMM Working Group, in collaboration with the SVG Working Group, has authored the SMIL Animation specification [ SMILANIM], which represents a general-purpose XML animation feature set. SVG incorporates the animation features defined in the SMIL Animation specification and provides some SVG-specific extensions.
For an introduction to the approach and features available in any language that supports SMIL Animation, see SMIL Animation overview and SMIL Animation animation model. For the list of animation features which go beyond SMIL Animation, see SVG extensions to SMIL Animation.
SVG is a host language in terms of SMIL 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 is the SMIL Animation [ SMILANIM] specification.
SVG supports the following four animation elements which are defined in the SMIL Animation specification:
'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 Animation:
'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 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 | ||
discard element | SVG adds a discard element which removes the target element from the DOM tree at a specified time |
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 Animation requires that the host language define the meaning for document begin and the document end. Since an 'svg' is sometimes the root of the XML document tree and other times can be a component of a parent XML grammar, the document begin for a given SVG document fragment is defined to be the exact time at which the 'svg' element's load event is triggered. The document end of an SVG document fragment is the point at which the document fragment has been released and is no longer being processed by the user agent.
For SVG, the term presentation time indicates the position in the timeline relative to the document begin of a given document fragment.
SVG defines more constrained error processing than is defined in the SMIL Animation [ SMILANIM] specification. SMIL Animation defines error processing behavior where the document continues to run in certain error situations, whereas all animations within an SVG document fragment will stop in the event of any error within the document (see Error processing).
Example anim01 below demonstrates each of SVG's five animation elements.
<?xml version="1.0" standalone="no"?> <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 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 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.
<define name='svg.AnimateCommon.attr'> <ref name='svg.XLink.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'> <attribute name='attributeName' svg:animatable='false' svg:inheritable='false'><text/></attribute> <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:
attributeName
has an XMLNS prefix, the
implementation must use the associated namespace as
defined in the scope of the target element. The
attribute must be defined as animatable in this
specification.attributeName
to an attribute for the
target element. The implementation must first search
through the list of CSS properties for a matching
property name, and if none is found, search the default
XML namespace for the element.
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 dimentional 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.
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, percentage, 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 | ||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)) |
points on <polygon> |
path | n 2 dimensional values where each value is a control 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.AnimateBegin.attr' combine='interleave'> <optional><attribute name='begin' svg:animatable='false' svg:inheritable='false'><text/></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' a:defaultValue='always' svg:animatable='false' svg:inheritable='false'> <choice> <value>always</value> <value>never</value> <value>whenNotActive</value> </choice> </attribute> </optional> </define> <define name='svg.AnimateTimingNoMinMax.attr' combine='interleave'> <ref name='svg.AnimateTimingNoFillNoMinMax.attr'/> <optional> <attribute name='fill' a:defaultValue='remove' svg:animatable='false' svg:inheritable='false'> <choice> <value>remove</value> <value>freeze</value> </choice> </attribute> </optional> </define> <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>
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.f(t)
.The SMIL Animation [ SMILANIM] specification defines the detailed processing rules associated with the above attributes. Except for any SVG-specific rules explicitly mentioned in this specification, the SMIL Animation [ SMILANIM] specification is the normative definition of the processing rules for the above attributes.
Clock values have a subsetted syntax of the clock values syntax in SMIL Animation [ SMILANIM]:
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 presentation 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:
calcMode
= "discrete | linear | paced
| spline"calcMode
attribute is ignored and discrete
interpolation is used.
discrete
linear
calcMode
.paced
paced
" is specified, any
keyTimes
or keySplines
will
be ignored. For 'animateMotion', this
is the default calcMode
.spline
values
list to the next according to a
time function defined by a cubic Bzier spline.
The points of the spline are defined in the
keyTimes
attribute, and the control points
for each interval are defined in the
keySplines
attribute.values
=
"<list>"attributeType
domain. Except for
any SVG-specific rules explicitly mentioned in this
specification, the normative definition for this attribute
is the SMIL Animation [
SMILANIM] specification. In particular, see
SMIL Animation: 'values' attribute.
keyTimes
=
"<list>"values
attribute list, and defines when the value is used in the
animation function. Each time value in the
keyTimes
list is specified as a floating
point value between 0 and 1 (inclusive), representing a
proportional offset into the simple duration of the
animation element.keyTimes
is specified, there
must be exactly as many values in the
keyTimes
list as in the values
list.The keyTimes
list semantics depends upon
the interpolation mode:
keyTime
associated with each value defines when the value is
set; values are interpolated between the
keyTimes
.keyTimes
.keyTimes
attribute is ignored.keyTimes
specification (bad values, too many or too few values),
the document fragment is in error (see error
processing).keyTimes
specification will be
ignored.keySplines
=
"<list>"keyTimes
list, defining a cubic
Bzier function that controls interval pacing. The
attribute value is a semicolon separated list of control
point descriptions. Each control point description is a set
of four values: x1 y1 x2 y2
, describing the
Bzier control points for one time segment. The
keyTimes
values that define the associated
segment are the Bzier "anchor points", and the
keySplines
values are the control points.
Thus, there must be one fewer sets of control points than
there are keyTimes
.calcMode
is set to "spline".keySplines
specification (bad values, too many or too few values), the
document fragment is in error (see error
processing).from
=
"<value>"to
=
"<value>"by
=
"<value>"The SMIL Animation [ SMILANIM] specification defines the detailed processing rules associated with the above attributes. Except for any SVG-specific rules explicitly mentioned in this specification, the SMIL Animation [ SMILANIM] 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, the document fragment is in error (see error processing).
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/by/to animations are described in Animation function values.
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="0011" (the default) | keySplines=".50.51" |
||
keySplines="0.75.251" | keySplines="10.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 Bzier spline calculation, see [FOLEY-VANDAM].
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 pixels:
<rect width="20px" ...> <animate attributeName="width" from="0px" to="10px" dur="10s" additive="sum"/> </rect>
It is frequently useful for repeated animations to build upon the previous results, accumulating with each interation. The following example causes the rectangle to continue to grow with each repeat of the animation:
<rect width="20px" ...> <animate attributeName="width" from="0px" to="10px" dur="10s" additive="sum" accumulate="sum" repeatCount="5"/> </rect>
At the end of the first repetition, the rectangle has a width of 30 pixels. At the end of the second repetition, the rectangle has a width of 40 pixels. At the end of the fifth repetition, the rectangle has a width of 70 pixels.
For more information about additive animations, see SMIL Animation: Additive animation. For more information on cumulative animations, see SMIL Animation: 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' a:defaultValue='replace' svg:animatable='false' svg:inheritable='false'> <choice> <value>replace</value> <value>sum</value> </choice> </attribute> </optional> <optional> <attribute name='accumulate' a:defaultValue='none' svg:animatable='false' svg:inheritable='false'> <choice> <value>none</value> <value>sum</value> </choice> </attribute> </optional> </define>
Attribute definitions:
by
and
to
, as described in
SMIL Animation: How from, to and by attributes affect
additive behavior.to
attribute.
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="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 Animation [ SMILANIM] specification. In particular, see SMIL Animation: '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.
The 'set' element provides a simple means of just setting the value of an attribute for a specified duration. It supports all 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 Animation [ SMILANIM] specification. In particular, see SMIL Animation: '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.
The following lists all of the elements which can be animated by the 'animateMotion' element:
Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for this element is the SMIL Animation [ SMILANIM] specification. In particular, see SMIL Animation: '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'/> <ref name='svg.AnimateTypeCommon.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:
calcMode
= "discrete | linear | paced
| spline"keyTimes
attribute list.keyPoints
is specified, there
must be exactly as many values in the
keyPoints
list as in the keyTimes
list.keyPoints
specification (bad values, too many or too few values),
then the document is in error (see Error
processing).
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.
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) A "move
to" command 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" standalone="no"?> <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 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 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 Animation [ SMILANIM] specification. In particular, see SMIL Animation: '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>
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.
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 the 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 a given attribute or property can take values of keywords (which are not additive) or numeric values (which are additive), then additive animations are possible if the subsequent animation uses a numeric value even if the base animation uses a keyword value; however, if the subsequent animation uses a keyword value, additive animation is not possible.
Data type | Additive? | 'animate' | 'set' | 'animate Color' |
'animate Transform' |
Notes |
---|---|---|---|---|---|---|
<color> | yes | yes | yes | yes | no | Only RGB color values are additive. |
<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 RGB color values are additive. |
<percentage> | yes | yes | yes | no | no | |
<time> | no | no | no | no | no | |
<transform-list> | yes | no | no | no | yes | Additive means that a transformation is post-multiplied to the base set of transformations. |
<iri> | 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 dom01 shows a simple animation using the DOM.
<?xml version="1.0" standalone="no"?> <svg width="4cm" height="2cm" viewBox="0 0 400 200" 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 DOM.</desc> <script type="application/ecmascript"><![CDATA[ var timeValue = 0; var timerIncrement = 50; var maxTime = 5000; var textElement; var svgRoot; function Init() { textElement = document.getElementById("svgtext"); svgRoot = document.getElementById("root"); ShowAndGrowElement(0); } function ShowAndGrowElement(repeatCount) { timeValue = (repeatCount + 1) * timerIncrement; // Scale the text string gradually until it is 20 times larger scalefactor = (timeValue * 20.) / maxTime; var matrix = createSVGMatrixComponents(scalefactor, 0, 0, scalefactor, 0, 0); textElement.setMatrixTrait("transform", matrix); // Make the string more opaque opacityfactor = timeValue / maxTime; textElement.setFloatTrait("fill-opacity", opacityfactor); } ]]></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="1" id="svgtext">SVG</text> </g> <rect x="1000" y="1000" width="1" height="1" display="none"> <animate id="timer" attributeName="display" from="none" to="none" begin="0" dur="50" repeatCount="99"> <handler type="application/ecmascript" ev:event="repeatEvent"> ShowAndGrowElement(evt.detail); </handler> </animate> </rect> </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 make the initial
call to ShowAndGrowElement
.
ShowAndGrowElement()
sets the transform
and
fill-opacity
attributes on the text element to new
values each time it is called.ShowAndGrowElement()
is called every 50
milliseconds from the second
'handler' in the example.
<handler type="application/ecmascript" ev:event="repeat"> ShowAndGrowElement(evt.detail); </handler>This 'handler' is placed on an animation that 'does nothing', its sole purpose is to emulate timer functionality. For each repeat (every 50ms) the 'handler' calls
ShowAndGrowElement
, passing the repeat number as a parameter.
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 Timed Animation Module contains the following elements: