(frahopgood@gmail.com), daduce@brookes.ac.uk, phopgood@svg-editor.org.uk)
W3C's Web/Animation document states:
The future for SVG declarative animation appears to be as follows:
The following paper looks at some of these statements from the perspective of somebody interested in SVG animation
The authors' particluar interests in SVG animation include:
SVG declarative animation (SVG Animation) consists primarily of animating SVG content via changing path descriptions over time. That is our main interest. It is also possible to change the styling of SVG content via the modification of SVG element attributes (stroke, fill etc) or via equivalent CSS properties where they exist. It is thus possible to change the style of SVG content via a CSS stylesheet if the SVG author allows it to happen. For most of our SVG animations that is inappropriate.
Timing is important in animating SVG content and in SMIL multimedia content. The SYMM working group produced a reference model for scheduling and orchestrating media objects to be selected and rendered under a variety of timing and spatial constraints. It was primarily aimed at SMIL at a time when the duration of playing a video clip was unknown and it was not possible to predict which of two videos would complete first if played in parallel. Playing part of a video clip might have its start delayed while the video was being positioned etc. In consequence, only a small part of the model is required by SVG animation where timing is more precise. A subset of the SMIL timing attributes are sufficient and the time containers are unnecessary. SVG is a creation language for animated objects which are similar to individual SMIL media objects.
The origins of SMIL was the European Union Chameleon project with RAL and CWI as partners. The par and seq functionality was added to ensure that simple multimedia objects from, say, a reporter in the field could add archival footage to a news item consisting of one or two new video clips and a simple par and seq shorthand view of how they should be broadcast.
SMIL 2.0 [1] added styling to multimedia content via transition effects and SMIL Animation. Transition effects are similar to those used by PowerPoint. SMIL Animation was designed to allow the values of visual, aural and position attributes in a SMIL presentation to be changed. Examples are changing the sound level of an aural track, the background colour applied to a video clip or positioning a video clip depending on the presentation system in use. In SMIL, these were only intended for changing the style of a multimedia presentation. The author of SMIL 2.0 made it clear that SMIL was not an animation creation language like SVG but it could be used to display SVG animated content objects and could be used to adjust the timing and rendering properties of the SVG object as a whole while it is being displayed.
Why all the confusion between SMIL Animation and SVG Animation? Partly because the SVG Recommendation refers to the SMIL Recommendation. Also because the general timing control attributes (begin, dur and end), object persistance attribute (fill), repeating objects attributes (repeatCount and repeatDur) are common to both and some of SMIL's inline transition attributes (from, to, by, values, calcMode) are defined for both albeit for different purposes. The other major similarity is that neither use CSS. Both are defined in XML. SMIL 1.0 indicated that its basic layout could be transformed into equivalent CSS-2 notation, but it is a less concise notation than is convenient for multimedia specifications. Even so SMIL tried to make it possible to use either CSS properties or SMIL attributes when compatible as does SVG.
Our view is that the SVG Working Group belief that SVG animation is inherently presentational is not correct. We do not believe that any of our SVG animations are presentational. SVG geometric content is specified in SVG primarily by the path descriptions as SVG attributes and animating these path descriptions is SVG animation. If area colour or line thickness, say, is part of the SVG content it will use SVG rendering attributes or CSS properties in such a way that they cannot be changed by a change in user stylesheet. Providing SVG animation facilities via CSS is inappropriate. Declarative XML-based content is the best way to define SVG animation and CSS rule-based styling is inappropriate for both SVG and SMIL content. The main part of almost any SVG animation is animating path descriptions as content.
One of the problems is the misuse of the word animation when the person is using it to mean styling transitions of media objects. Such transitions can be considered styling and could be defined in CSS. SMIL defined a timing model for the presentation of multimedia objects and the transitions between such objects. SVG uses parts of both models to define its timing control of SVG content. A step forward would be to separate the part of the model applicable to SVG content animation rather than continuing to try and merge the requirements of styling transitions, multimedia presentations and SVG content animation into a single model.
SVG animation is not as efficiently defined as it might be, especially for large animations. Below we consider what changes could be made to make SVG content animation more efficient. At the same time it might make it more feasible that timing could be controlled by CSS.
We will use a simple example from Preston Blair's Animation published in 1949 as an example of how to use SVG for content animation. It animates a figure walking forward over an 8-frame cycle.
To animate the figure, the eight path descriptions must be defined and an animate command to animate between the positions.
The SVG code looks something like:
<svg width="200" height="320" xmlns="http://www.w3.org/2000/svg"> <style type="text/css"> path {stroke-width:2;fill:none;stroke:forestgreen} </style> <path d="M84,70l1,-10c-70,-77,80,-77,15,0l-1,10c41,5,76,30,78,60c10,15,-32,15,-22,0c0,-30,-38,-40,-48,-30c10,30,10,50,5,70c11,20,18,40,13,50c40,-40,5,80,-25,35c7,-30,0,-55,-3,-82c-7,3,-14,3,-21,0c-8,17,-2,27,16,49c-8,68,-67,28,-12,3c-30,-15,-30,-45,-24,-57c-1,-20,9,-40,19,-73c-40,20,-11,15,9,5c11,-20,22,10,3,20c-77,30,-77,10,-3,-50l0,0Z"> <animate attributeName="d" values=" M84,70l1,-10c-70,-77,80,-77,15,0l-1,10c41,5,76,30,78,60c10,15,-32,15,-22,0c0,-30,-38,-40,-48,-30c10,30,10,50,5,70c11,20,18,40,13,50c40,-40,5,80,-25,35c7,-30,0,-55,-3,-82c-7,3,-14,3,-21,0c-8,17,-2,27,16,49c-8,68,-67,28,-12,3c-30,-15,-30,-45,-24,-57c-1,-20,9,-40,19,-73c-40,20,-11,15,9,5c11,-20,22,10,3,20c-77,30,-77,10,-3,-50z; M86,70l0,-10c-71,-64,79,-74,14,0l-1,10c11,5,46,30,64,70c10,25,-30,30,-25,15c17,-20,-27,-55,-29,-45c8,20,8,40,6,60c28,20,35,40,0,70c50,0,15,40,-26,10c26,-25,31,-50,8,-70c-7,-4,-14,-4,-21,0c-18,10,-12,20,14,20c-6,90,-45,50,-23,19c-37,-9,-27,-39,-1,-61c-6,-10,3,-30,11,-61c-42,28,-13,23,3,10c10,-17,30,8,0,23c-50,10,-70,-10,6,-60z; M86,70l0,-14c-76,-60,74,-70,14,-2l-1,13c21,8,56,33,34,83c7,35,-53,20,-13,0c10,-15,0,-50,-20,-70c17,50,17,70,5,80c5,20,35,50,0,90c70,0,25,40,-15,5c15,-20,15,-55,10,-85c-10,6,-15,6,-25,0c-35,20,-25,30,-15,20c60,-40,-25,90,0,10c-55,10,-20,-20,5,-42c-5,-10,0,-30,10,-73c-25,10,-25,25,-23,40c18,-15,18,30,-7,20c-15,-15,-15,-75,41,-75z; M87,68l0,-12c-73,-60,73,-70,18,-2l-1,11c51,40,51,40,13,79c-27,10,-37,-24,-9,-18c22,-17,22,-17,-2,-34c8,18,15,38,16,58c4,40,2,80,-7,118c50,-8,15,52,-25,-13c20,-20,20,-55,10,-85c-10,2,-15,2,-22,-5c-18,0,-8,25,-3,35c40,60,-90,-20,-10,-8c-40,-22,-25,-47,10,-42c-5,-10,0,-22,10,-55c-35,5,-35,15,-45,32c-10,28,-40,28,-22,-2c2,-15,37,-45,69,-57z; M85,72l1,-12c-72,-64,74,-74,9,0l0,10c70,45,70,75,0,44c-15,20,-25,-44,0,-12c45,17,35,7,9,-12c10,20,17,40,2,78c20,2,-2,59,0,70c34,22,-6,42,-21,-3c0,-20,5,-40,11,-62c-6,3,-11,3,-16,2c10,10,-10,25,-12,70c27,75,-73,-25,-10,-5c-3,-20,-3,-40,7,-65c-5,-25,-5,-47,11,-91c-26,36,-46,26,-56,43c0,28,-30,-2,-15,-9c15,-8,50,-38,80,-46z; M85,72l1,-12c-52,-64,84,-60,14,0l0,10c55,45,65,55,5,64c-30,10,-35,-54,0,-17c25,2,25,-8,-3,-22c8,15,13,35,4,73c24,17,29,37,-1,59c45,38,-20,63,-12,-22c22,-10,-8,-18,0,-32c-7,-1,-10,-1,-15,2c-13,20,-18,50,11,75c16,30,-94,40,-27,-5c-22,-15,-17,-55,5,-75c-5,-20,-5,-42,12,-76c-29,26,-49,16,-47,53c-7,18,-37,28,-17,-5c5,-28,40,-62,70,-70z; M85,72l1,-12c-66,-64,74,-65,12,0l0,11c47,44,57,54,12,81c-18,2,-20,-22,-3,-15c23,-18,18,-28,-5,-40c6,13,11,33,2,66c31,22,41,47,4,44c67,51,-53,8,0,-12c14,7,17,-8,-10,-18c-12,-3,-15,-3,-20,0c-3,18,-8,48,8,73c19,30,-91,35,-18,5c-18,-25,-13,-65,-1,-85c-3,-20,-3,-42,12,-72c-19,22,-29,47,-17,57c8,20,-24,35,-12,0c-30,-11,15,-75,35,-83z; M86,76l0,-14c-66,-66,74,-67,12,-2l0,14c42,16,72,56,66,68c2,30,-28,28,-16,-5c-18,-20,-23,-28,-43,-30c3,3,8,23,-5,56c35,-28,55,-13,12,35c88,-53,-32,82,-8,7c18,-45,-4,-18,-12,-17c-3,2,-6,2,-10,0c-7,7,-12,37,4,62c9,60,-91,30,-14,15c-24,-35,-19,-75,-12,-92c4,-23,4,-45,19,-75c-19,22,-29,47,-12,49c23,-22,23,38,0,10c-57,7,-22,-77,19,-81z; M84,70l1,-10c-70,-77,80,-77,15,0l-1,10c41,5,76,30,78,60c10,15,-32,15,-22,0c0,-30,-38,-40,-48,-30c10,30,10,50,5,70c11,20,18,40,13,50c40,-40,5,80,-25,35c7,-30,0,-55,-3,-82c-7,3,-14,3,-21,0c-8,17,-2,27,16,49c-8,68,-67,28,-12,3c-30,-15,-30,-45,-24,-57c-1,-20,9,-40,19,-73c-40,20,-11,15,9,5c11,-20,22,10,3,20c-77,30,-77,10,-3,-50z" begin="1s" dur="2s" fill="freeze" repeatCount="indefinite"/> </path> </svg>
Some things to notice:
Something like the following would handle the timing but CSS cannot currently handle the d values:
path {animation-delay: 1s; animation-duration: 2s; animation-iteration-count: infinite;animation-fill-mode: forwards} path.d {0%: ; 12.5%: ;25%: ;37.5%: ;50%: ; 62.5%: ; 75%: ; 87.5%: ;100%: }
Each path requires a style rule so we may be talking about 5000 style rules to be added for a short animation. Large companies may well have significantly larger requirements. Is CSS engineered to handle style sheets that large?
Irrespective of whether timing gets moved to CSS or stays with SVG, having an indirect reference to the d value has advantages. The CSS would be something like:
path.d {0%:#frame1; 12.5%:frame2;25%:#frame3;37.5%:#frame4;50%:#frame5;62.5%:#frame6;75%:#frame7;87.5%:#frame8;100%:#frame1}
Currently, CSS accesses URL's with something like url(#frame2). A shorter notation would be appropriate as would shorter names of the other CSS properties.
A change to SVG animation that would be of value to both CSS and SVG would be the way access is made to d values. Consider the following:
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="900" height="400" xmlns="http://www.w3.org/2000/svg"> <path id="frame1" style="stroke:forestgreen;fill:none" d="M84,70l1,-10c-70,-77,80,-77,15,0l-1,10c41,5,76,30,78,60c10,15,-32,15,-22,0c0,-30,-38,-40,-48,-30c10,30,10,50,5,70c11,20,18,40,13,50c40,-40,5,80,-25,35c7,-30,0,-55,-3,-82c-7,3,-14,3,-21,0c-8,17,-2,27,16,49c-8,68,-67,28,-12,3c-30,-15,-30,-45,-24,-57c-1,-20,9,-40,19,-73c-40,20,-11,15,9,5c11,-20,22,10,3,20c-77,30,-77,10,-3,-50l0,0Z"/> <defs> <path id="frame2" d="M86,70l0,-10c-71,-64,79,-74,14,0l-1,10c11,5,46,30,64,70c10,25,-30,30,-25,15c17,-20,-27,-55,-29,-45c8,20,8,40,6,60c28,20,35,40,0,70c50,0,15,40,-26,10c26,-25,31,-50,8,-70c-7,-4,-14,-4,-21,0c-18,10,-12,20,14,20c-6,90,-45,50,-23,19c-37,-9,-27,-39,-1,-61c-6,-10,3,-30,11,-61c-42,28,-13,23,3,10c10,-17,30,8,0,23c-50,10,-70,-10,6,-60z"/> <path id="frame3" d="M86,70l0,-14c-76,-60,74,-70,14,-2l-1,13c21,8,56,33,34,83c7,35,-53,20,-13,0c10,-15,0,-50,-20,-70c17,50,17,70,5,80c5,20,35,50,0,90c70,0,25,40,-15,5c15,-20,15,-55,10,-85c-10,6,-15,6,-25,0c-35,20,-25,30,-15,20c60,-40,-25,90,0,10c-55,10,-20,-20,5,-42c-5,-10,0,-30,10,-73c-25,10,-25,25,-23,40c18,-15,18,30,-7,20c-15,-15,-15,-75,41,-75z"/> <path id="frame4" d="M87,68l0,-12c-73,-60,73,-70,18,-2l-1,11c51,40,51,40,13,79c-27,10,-37,-24,-9,-18c22,-17,22,-17,-2,-34c8,18,15,38,16,58c4,40,2,80,-7,118c50,-8,15,52,-25,-13c20,-20,20,-55,10,-85c-10,2,-15,2,-22,-5c-18,0,-8,25,-3,35c40,60,-90,-20,-10,-8c-40,-22,-25,-47,10,-42c-5,-10,0,-22,10,-55c-35,5,-35,15,-45,32c-10,28,-40,28,-22,-2c2,-15,37,-45,69,-57z"/> <path id="frame5" d="M85,72l1,-12c-72,-64,74,-74,9,0l0,10c70,45,70,75,0,44c-15,20,-25,-44,0,-12c45,17,35,7,9,-12c10,20,17,40,2,78c20,2,-2,59,0,70c34,22,-6,42,-21,-3c0,-20,5,-40,11,-62c-6,3,-11,3,-16,2c10,10,-10,25,-12,70c27,75,-73,-25,-10,-5c-3,-20,-3,-40,7,-65c-5,-25,-5,-47,11,-91c-26,36,-46,26,-56,43c0,28,-30,-2,-15,-9c15,-8,50,-38,80,-46z"/> <path id="frame6" d="M85,72l1,-12c-52,-64,84,-60,14,0l0,10c55,45,65,55,5,64c-30,10,-35,-54,0,-17c25,2,25,-8,-3,-22c8,15,13,35,4,73c24,17,29,37,-1,59c45,38,-20,63,-12,-22c22,-10,-8,-18,0,-32c-7,-1,-10,-1,-15,2c-13,20,-18,50,11,75c16,30,-94,40,-27,-5c-22,-15,-17,-55,5,-75c-5,-20,-5,-42,12,-76c-29,26,-49,16,-47,53c-7,18,-37,28,-17,-5c5,-28,40,-62,70,-70z"/> <path id="frame7" d="M85,72l1,-12c-66,-64,74,-65,12,0l0,11c47,44,57,54,12,81c-18,2,-20,-22,-3,-15c23,-18,18,-28,-5,-40c6,13,11,33,2,66c31,22,41,47,4,44c67,51,-53,8,0,-12c14,7,17,-8,-10,-18c-12,-3,-15,-3,-20,0c-3,18,-8,48,8,73c19,30,-91,35,-18,5c-18,-25,-13,-65,-1,-85c-3,-20,-3,-42,12,-72c-19,22,-29,47,-17,57c8,20,-24,35,-12,0c-30,-11,15,-75,35,-83z"/> <path id="frame8" d="M86,76l0,-14c-66,-66,74,-67,12,-2l0,14c42,16,72,56,66,68c2,30,-28,28,-16,-5c-18,-20,-23,-28,-43,-30c3,3,8,23,-5,56c35,-28,55,-13,12,35c88,-53,-32,82,-8,7c18,-45,-4,-18,-12,-17c-3,2,-6,2,-10,0c-7,7,-12,37,4,62c9,60,-91,30,-14,15c-24,-35,-19,-75,-12,-92c4,-23,4,-45,19,-75c-19,22,-29,47,-12,49c23,-22,23,38,0,10c-57,7,-22,-77,19,-81z"/> </defs> <animate xlink:href="#frame1" attributeName="d" values="#frame1;#frame2;#frame3;#frame4;#frame5;#frame6;#frame7;#frame8;#frame1" begin="1s" dur="2s" fill="freeze" repeatCount="indefinite"/> or <animate xlink:href="#frame1" attributeName="d" to="#frame2;#frame3;#frame4;#frame5;#frame6;#frame7;#frame8;#frame1" begin="1s" dur="2s" fill="freeze" repeatCount="indefinite"/> </svg>
If the animate command had the ability to access a d value by specifying the id of the associated path, the SVG code becomes cleaner in that a user would only defined d values in path elements and the animate commands become easier to read. From the CSS perspective, the styling rule for a path would be appropriate for any 8-frame cycle. Furthermore, while debugging other parts of the animation, the CSS style rule could be changed to something like:
path.d {0%:#frame1; 33%:#frame4;66%:#frame8;100%:#frame1}
The suggested modification to the animate command would not be that difficult to implement while retaining the current alternatives.
It might be approprriate not to reuse the current path element but instead introduce a new element, say <gpath> (geometric path definition).
In SVG, path elements can only have a single fill attribute or property. In consequence most objects making up an animated scene contain multiple paths. For example, a trivial extension to the example above would be to define the man by:
The animated figure now is:
The SVG code looks something like:
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="320" xmlns="http://www.w3.org/2000/svg"> <style type="text/css"> path.head {fill:navajowhite;stroke:none} path.body {fill:green;stroke:none} path.legs {fill:blue;stroke:none} </style> <g id="frame1"> <path class="head" id="head1" d="M84,70l1,-10c-70,-77,80,-77,15,0l-1,10l-15,0Z"/> <path class="body" id="body1" d="M99,70c41,5,76,30,78,60c10,15,-32,15,-22,0c0,-30,-38,-40,-48,-30c10,30,10,50,5,70l-56,-2c-1,-20,9,-40,19,-73c-40,20,-11,15,9,5c11,-20,22,10,3,20c-77,30,-77,10,-3,-50Z"/> <path class="legs" id="legs1" d="M112,170c11,20,18,40,13,50c40,-40,5,80,-25,35c7,-30,0,-55,-3,-82c-7,3,-14,3,-21,0c-8,17,-2,27,16,49c-8,68,-67,28,-12,3c-30,-15,-30,-45,-24,-57l56,2Z"/> </g> <animate xlink:href="#head1" attributeName="d" values="M84,70l1,-10c-70,-77,80,-77,15,0l-1,10l-15,0Z;M86,70l0,-10c-71,-64,79,-74,14,0l-1,10l-13,0Z;M86,70l0,-14c-76,-60,74,-70,14,-2l-1,13l-13,3Z;M87,68l0,-12c-73,-60,73,-70,18,-2l-1,11l-17,3Z;M85,72l1,-12c-72,-64,74,-74,9,0l0,10l-10,2Z;M85,72l1,-12c-52,-64,84,-60,14,0l0,10l-15,2Z;M85,72l1,-12c-66,-64,74,-65,12,0l0,11l-13,1Z;M86,76l0,-14c-66,-66,74,-67,12,-2l0,14l-12,2Z;M84,70l1,-10c-70,-77,80,-77,15,0l-1,10l-15,0Z" begin="1s" dur="2s" fill="freeze" repeatCount="indefinite"/> <animate xlink:href="#body1" attributeName="d" values="M99,70c41,5,76,30,78,60c10,15,-32,15,-22,0c0,-30,-38,-40,-48,-30c10,30,10,50,5,70l-56,-2c-1,-20,9,-40,19,-73c-40,20,-11,15,9,5c11,-20,22,10,3,20c-77,30,-77,10,-3,-50Z;M99,70c11,5,46,30,64,70c10,25,-30,30,-25,15c17,-20,-27,-55,-29,-45c8,20,8,40,6,60l-49,-12c-6,-10,3,-30,11,-61c-42,28,-13,23,3,10c10,-17,30,8,0,23c-50,10,-70,-10,6,-60z;M99,67c21,8,56,33,34,83c7,35,-53,20,-13,0c10,-15,0,-50,-20,-70c17,50,17,70,5,80l-40,-2c-5,-10,0,-30,10,-73c-25,10,-25,25,-23,40c18,-15,18,30,-7,20c-15,-15,-15,-75,41,-75z;M104,65c51,40,51,40,13,79c-27,10,-37,-24,-9,-18c22,-17,22,-17,-2,-34c8,18,15,38,16,58l-47,0c-5,-10,0,-22,10,-55c-35,5,-35,15,-45,32c-10,28,-40,28,-22,-2c2,-15,37,-45,69,-57z;M95,70c70,45,70,75,0,44c-15,20,-25,-44,0,-12c45,17,35,7,9,-12c10,20,17,40,2,78l-41,7c-5,-25,-5,-47,11,-91c-26,36,-46,26,-56,43c0,28,-30,-2,-15,-9c15,-8,50,-38,80,-46z;M100,70c55,45,65,55,5,64c-30,10,-35,-54,0,-17c25,2,25,-8,-3,-22c8,15,13,35,4,73l-39,2c-5,-20,-5,-42,12,-76c-29,26,-49,16,-47,53c-7,18,-37,28,-17,-5c5,-28,40,-62,70,-70z;M98,71c47,44,57,54,12,81c-18,2,-20,-22,-3,-15c23,-18,18,-28,-5,-40c6,13,11,33,2,66l-37,7c-3,-20,-3,-42,12,-72c-19,22,-29,47,-17,57c8,20,-24,35,-12,0c-30,-11,15,-75,35,-83z;M98,74c42,16,72,56,66,68c2,30,-28,28,-16,-5c-18,-20,-23,-28,-43,-30c3,3,8,23,-5,56l-40,10c4,-23,4,-45,19,-75c-19,22,-29,47,-12,49c23,-22,23,38,0,10c-57,7,-22,-77,19,-81z;M99,70c41,5,76,30,78,60c10,15,-32,15,-22,0c0,-30,-38,-40,-48,-30c10,30,10,50,5,70l-56,-2c-1,-20,9,-40,19,-73c-40,20,-11,15,9,5c11,-20,22,10,3,20c-77,30,-77,10,-3,-50Z" begin="1s" dur="2s" fill="freeze" repeatCount="indefinite"/> <animate xlink:href="#legs1" attributeName="d" values="M112,170c11,20,18,40,13,50c40,-40,5,80,-25,35c7,-30,0,-55,-3,-82c-7,3,-14,3,-21,0c-8,17,-2,27,16,49c-8,68,-67,28,-12,3c-30,-15,-30,-45,-24,-57l56,2Z;M115,170c28,20,35,40,0,70c50,0,15,40,-26,10c26,-25,31,-50,8,-70c-7,-4,-14,-4,-21,0c-18,10,-12,20,14,20c-6,90,-45,50,-23,19c-37,-9,-27,-39,-1,-61l49,12Z;M105,160c5,20,35,50,0,90c70,0,25,40,-15,5c15,-20,15,-55,10,-85c-10,6,-15,6,-25,0c-35,20,-25,30,-15,20c60,-40,-25,90,0,10c-55,10,-20,-20,5,-42l40,2Z;M122,150c4,40,2,80,-7,118c50,-8,15,52,-25,-13c20,-20,20,-55,10,-85c-10,2,-15,2,-22,-5c-18,0,-8,25,-3,35c40,60,-90,-20,-10,-8c-40,-22,-25,-47,10,-42l47,0Z;M106,168c20,2,-2,59,0,70c34,22,-6,42,-21,-3c0,-20,5,-40,11,-62c-6,3,-11,3,-16,2c10,10,-10,25,-12,70c27,75,-73,-25,-10,-5c-3,-20,-3,-40,7,-65l41,-7Z;M106,168c24,17,29,37,-1,59c45,38,-20,63,-12,-22c22,-10,-8,-18,0,-32c-7,-1,-10,-1,-15,2c-13,20,-18,50,11,75c16,30,-94,40,-27,-5c-22,-15,-17,-55,5,-75l39,-2Z;M104,163c31,22,41,47,4,44c67,51,-53,8,0,-12c14,7,17,-8,-10,-18c-12,-3,-15,-3,-20,0c-3,18,-8,48,8,73c19,30,-91,35,-18,5c-18,-25,-13,-65,-1,-85l37,-7Z;M100,163c35,-28,55,-13,12,35c88,-53,-32,82,-8,7c18,-45,-4,-18,-12,-17c-3,2,-6,2,-10,0c-7,7,-12,37,4,62c9,60,-91,30,-14,15c-24,-35,-19,-75,-12,-92l40,-10Z;M112,170c11,20,18,40,13,50c40,-40,5,80,-25,35c7,-30,0,-55,-3,-82c-7,3,-14,3,-21,0c-8,17,-2,27,16,49c-8,68,-67,28,-12,3c-30,-15,-30,-45,-24,-57l56,2Z" begin="1s" dur="2s" fill="freeze" repeatCount="indefinite"/> </svg>
In a realistic example, each hand, arm, leg, foot and facial features would most likely be different leading to a set of animate elements all with the same start time and same duration. Making changes to such an animation is prone to error and the problem with the start times can be eased by:
<animate xlink:href="#head1" attributeName="d" values="M84,70l1 ..." id="first" begin="1s" dur="2s" fill="freeze" repeatCount="indefinite"/> <animate xlink:href="#body1" attributeName="d" values="M99,70 ..." begin="first.begin" dur="2s" fill="freeze" repeatCount="indefinite"/> <animate xlink:href="#legs1" attributeName="d" values="M112,170..." begin="first.begin" dur="2s" fill="freeze" repeatCount="indefinite"/>
A simple but helpful extension to SVG content animation would be:
<animate xlink:href="#head1" attributeName="d" values="M84,70l1 ..." id="first" begin="1s" dur="2s" fill="freeze" repeatCount="indefinite"/> <animate xlink:href="#body1" attributeName="d" values="M99,70 ..." begin="first.begin" dur="first.dur" fill="freeze" repeatCount="indefinite"/> <animate xlink:href="#legs1" attributeName="d" values="M112,170..." begin="first.begin" dur="first.dur" fill="freeze" repeatCount="indefinite"/>
This does not make any major extension to the animate element as the ability to reference the begin attribute from another animate element already gives the syntax of how it would be achieved. To ensure other characteristics stay in step over a set of animate commands, the technique is appropriate for all the other attributes as well.
Below is a simple but more realistic example of SVG animation that we completed recently for the WWW Conference in Florence in May 2015. The full animation runs for about 6 minutes and the example below is a simple zoom and pan from one frame to the next that lasts for 9 seconds.
The start frame shows the Town Hall of Florence.
It started life as about 1500 paths which none of the browsers could animate smoothly. In consequence, optimisation of the original scene was needed to make it possible for the animation to proceed. After many transformations it was possible to reduce the number of paths to 707.
The requirement was to move to a zoomed in side view of the complete scene.
The 707 path descriptions also appear in the second scene and each path description has to have the same structure.
The complete scene full size is shown below. Hit the arrow at the bottom to see the SVG animation take place.
Here are 3 example paths out of the 707 used (three of the crest just below the bell tower), and their associated animate elements:
<path id="w24strt6a_1p32" class="w24crestg" d="M-260.1,799.2l0.6,17.1l-2.1,1.8l-0.6,-17.2l2.1,-1.7ZM-260.5,800.8l-1.3,1l0.2,5.7c0.2,3.5,0.7,5.9,0.9,6.5c0.2,-0.9,0.5,-4.1,0.4,-7.6l-0.2,-5.6Z"/> <path id="w24strt6a_1p33" class="w24crestw" d="M-260.1,797.5l-2.2,1.8c-0.4,-9.9,1.8,-11.7,2.2,-1.8ZM-260.1,798.6l-2.2,1.8l0.6,18.4l2.3,-2l-0.7,-18.2ZM-260.1,799.2l0.6,17.1l-2.1,1.8l-0.6,-17.2l2.1,-1.7ZM-260,807.4c0.1,2.8,-0.3,7.5,-0.6,8.6c-0.4,-0.4,-1.1,-4.2,-1.2,-7l0.3,8.5l1.8,-1.7l-0.3,-8.4"/> <path id="w24strt6a_1p34" class="w24crestb" d="M-260.2,797.6l-2.1,1.6c-0.3,-9.1,1.8,-10.7,2.1,-1.6ZM-259.8,814.7l0,-0.8l-0.1,0.1l0,0.9l0,0.7l0.1,-0.1l0,-0.8ZM-260,813.2l0,-0.7l-0.1,0l0,0.9l0,0.7l0.1,-0.1l0,-0.8ZM-261.3,816.1l-0.1,-0.8l-0.1,0.1l0,0.8l0.1,0.8l0.1,-0.1l0,-0.8ZM-261.2,814.3l-0.1,-0.7l-0.1,0.1l0,0.8l0.1,0.7l0,0l0.1,-0.9Z"/> <animate attributeName="d" values="M-260.1,799.2l0.6,17.1l-2.1,1.8l-0.6,-17.2l2.1,-1.7ZM-260.5,800.8l-1.3,1l0.2,5.7c0.2,3.5,0.7,5.9,0.9,6.5c0.2,-0.9,0.5,-4.1,0.4,-7.6l-0.2,-5.6Z;M-302.6,-1122l-0.4,63.3l12.3,1.7l0.5,-63.8l-12.4,-1.2ZM-300.3,-1117.1l7.7,0.8l-0.1,20.9c-0.1,13,-3,23.1,-4.1,25.6c-1.1,-2.7,-3.7,-13.5,-3.6,-26.5l0.1,-20.8Z" fill="freeze" begin="w24strt05.end" dur="9s" xlink:href="#w24strt6_1p32" keySplines="0.75 0 0.25 1" calcMode="spline"/> <animate attributeName="d" values="M-260.1,797.5l-2.2,1.8c-0.4,-9.9,1.8,-11.7,2.2,-1.8ZM-260.1,798.6l-2.2,1.8l0.6,18.4l2.3,-2l-0.7,-18.2ZM-260.1,799.2l0.6,17.1l-2.1,1.8l-0.6,-17.2l2.1,-1.7ZM-260,807.4c0.1,2.8,-0.3,7.5,-0.6,8.6c-0.4,-0.4,-1.1,-4.2,-1.2,-7l0.3,8.5l1.8,-1.7l-0.3,-8.4;M-303,-1128l13.3,1.2c0.3,-36.7,-13,-37.6,-13.3,-1.2ZM-303,-1124.1l13.3,1.2l-0.5,68l-13.3,-1.7l0.5,-67.5ZM-302.6,-1122l-0.4,63.3l12.3,1.7l0.5,-63.8l-12.4,-1.2ZM-302.1,-1091.8c-0.1,10.4,3.1,26.4,5.3,29.3c2.2,-2.3,5.6,-17.6,5.7,-28l-0.2,31.3l-11,-1.4l0.2,-31.2" fill="freeze" begin="w24strt05.end" dur="9s" xlink:href="#w24strt6_1p33" keySplines="0.75 0 0.25 1" calcMode="spline"/> <animate attributeName="d" values="M-260.2,797.6l-2.1,1.6c-0.3,-9.1,1.8,-10.7,2.1,-1.6ZM-259.8,814.7l0,-0.8l-0.1,0.1l0,0.9l0,0.7l0.1,-0.1l0,-0.8ZM-260,813.2l0,-0.7l-0.1,0l0,0.9l0,0.7l0.1,-0.1l0,-0.8ZM-261.3,816.1l-0.1,-0.8l-0.1,0.1l0,0.8l0.1,0.8l0.1,-0.1l0,-0.8ZM-261.2,814.3l-0.1,-0.7l-0.1,0.1l0,0.8l0.1,0.7l0,0l0.1,-0.9Z;M-302.5,-1127.9l12.4,1.1c0.2,-33.6,-12.2,-34.4,-12.4,-1.1ZM-302,-1065l0.3,-2.9l0.5,0.1l0.3,2.9l-0.3,2.9l-0.6,-0.1l-0.2,-2.9ZM-301.2,-1070.9l0.3,-2.8l0.6,0l0.2,3l-0.3,2.8l-0.5,0l-0.3,-3ZM-292.7,-1063.8l0.3,-2.9l0.6,0.1l0.2,2.9l-0.3,2.9l-0.5,-0.1l-0.3,-2.9ZM-293.5,-1069.9l0.3,-2.9l0.6,0.1l0.3,2.9l-0.3,2.9l-0.6,-0.1l-0.3,-2.9Z" fill="freeze" begin="w24strt05.end" dur="9s" xlink:href="#w24strt6_1p34" keySplines="0.75 0 0.25 1" calcMode="spline"/>
The low-level nature of the SVG code means that the complete scene is about 2Mbytes of SVG, half of which is animate commands. The nature of the animate commands is that they are all identical apart from the path they refer to and the d values.
The overall structure, if we made the changes proposed already, would look like:
<g id="scene1a"> <path id="path001a" d="M..."/> .... <path id="path703a" d="M..."/> </g> <defs> <g id="scene1b"> <path id="path001b" d="M..."/> .... <path id="path703b" d="M..."/> </g> </defs> <animate attributeName="d" values="#path001a;#path001b" fill="freeze" begin="strt.end" dur="9s" xlink:href="#path001a" keySplines="0.75 0 0.25 1" calcMode="spline"/> ... <animate attributeName="d" values="#path703a;#path703b" fill="freeze" begin="strt.end" dur="9s" xlink:href="#path001a" keySplines="0.75 0 0.25 1" calcMode="spline"/>
Most animations of any size will have this kind of structure. Rather than use the link to specify the individual path, it would be possible to reference the enclosing g element. The same provisos could be placed on the g element. The from and to structures must be the same. In this case the 707 animate elements could be reduced to a single element:
<animate xlink:href="#scene1a" to="#scene1b" dur="5s" fill="freeze" begin="strt.end" dur="9s" xlink:href="#path001a" keySplines="0.75 0 0.25 1" calcMode="spline"/>
If the href is to a g element the assumption is that it contains a sequence of path elements. The to attribute also points to a g element and gives the final position. The advantages are that the code is considerably shorter (703 animate lines become 1) and it gives the browser prior knowledge of what is to be animated and only has to decode 1 element rather than 707. If using a link to a g element is unacceptable, the same effect could be achieved by pointing at a defs element with an id attribute.
The current situation appears to be that the browsers want to have animation support for styling in CSS. This is because they want the animated control of multimedia and transitions there as well and only wish to define it in one place.
Having SVG content animation in CSS is not sensible for many reasons and, as shown above, it would introduce significant changes to the values used by CSS if it had to include path descriptions.
The main vehicle for content animation in SVG is animating the d attribute. This can only be done at the moment by using the SVG d attribute.
Content animation in SVG currently also animates SVG presentation attributes and CSS properties.
Almost all SVG content animations could be achieved by just animating SVG presentation attributes.
Therefore, a solution would be to remove the attributeType attribute from SVG animate commands. Only SVG attributes can be animated.
At the same time simplify the timing model to remove features that are only used by transitions and supporting SMIL multimedia.
This would leave a much simpler specification of animating SVG content via the SVG attributes.
CSS could then look at an SVG animation object in much the same way as it looks at a SMIL video object. If CSS wants to apply transitions on it fine. If it wants to make changes to the overall positioning of the SVG content in a multimedia presentation that would also be possible. Web Animations would then be a specification for CSS multimedia facilities.
Existing SVG content animations are probably a mixture of ones that use attributeType="CSS" and ones that don't. For any significant animation, it is unlikley that it will be generated completely by hand. In consequence changes required by the animation author may be significant but a tool that made the necessary changes would not be difficult to create.
A quick and not very thorough markup of the new Chapeter 19 in SVG 1.1 is attached as an Appendix. It gives some idea of what it might look like.
In summary we propose these changes to SVG content animation:
This might ease the load on the browsers somewhat and allow them to reconsider the decision to move SVG animation content to CSS.
(1) Bultermann, Dick C.A., Rutledge, Lloyd. SMIL 2.0 (ISBN 3-540-20234-X), Springer 2004.
Because the Web is a dynamic medium, SVG supports the ability to change vector graphics over time. SVG content can be animated using SVG's animation elements. SVG document fragments can describe time-based modifications to the document's elements. Users who which to define styling changes such as fade-in or fade-out effects, and objects that grow, shrink, spin or change color puely for styling should use CSS. SVG animation elements are designed to animate SVG content.
SVG has been designed to allow CSS to use animated or static SVG content as media components in the same way as it can provide such effects to video clips.
SVG's animation elements were developed in collaboration with the W3C Synchronized Multimedia (SYMM) Working Group, developers of the Synchronized Multimedia Integration Language (SMIL) 3.0 Specification [SMIL].
The full definition is now incorporated into this SVG specification and supercedes any description that refers to SMIL.
While having the same basic timing model as SMIL, SVG is a host language that introduces additional constraints and features specific to SVG. The normative definition for SVG's animation elements and attributes is this document.
SVG supports the following four animation elements which are defined in the SMIL Animation specification:
animate | allows scalar attributes to be assigned different values over time |
set | a convenient shorthand for animate , which is useful for assigning animation values to non-numeric attributes, such as the presentation attribute visibility |
animateMotion | moves an element along a motion path |
animateTransform | modifies one of SVG's transformation attributes over time, such as the transform attribute |
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 SVGLoad 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. However, nested svg elements within an SVG document do not constitute document fragments in this sense, and do not define a separate document begin; all times within the nested SVG fragment are relative to the document time defined for the root svg element.
For SVG, the term presentation time indicates the position in the timeline relative to the document begin of a given document fragment. For example, begin="0s" will cause the animation to start when the SVG document has been loaded.
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 four animation elements.
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="8cm" height="3cm" viewBox="0 0 800 300" xmlns="http://www.w3.org/2000/svg" version="1.1"> <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', 'animate' 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" /> <animate 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>
View this example as SVG (SVG-enabled browsers only)
The sections below describe the various animation attributes and elements.
The following attribute is common to all animation elements and identifies the target element for the animation.
Attribute definitions:
An IRI reference to the element which is the target of this animation and which therefore will be modified over time. The target is defined by an SVG element's id attribute.
The target element must be part of the current SVG document fragment.
<iri> must point to a target element which is capable of being the target of the given animation and part of the current SVG document fragment, otherwise the document is in error (see Error processing).
If the xlink:href attribute is not provided, then the target element will be the immediate parent element of the current animation element.
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.
The only attribute that can be used to specify the animation attribute target attribute is the id attribute of an SVG element.
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.1" 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>
View this example as SVG (SVG-enabled browsers only)
Paced animations assume a notion of distance between the various animation values defined by the to , from , by and values attributes. Distance is defined only for scalar types (such as <length>), colors and the subset of transformation types that are supported by animateTransform . In the list of distance functions below, Va and Vb represent the two values the distance between which is being calculated.
Since paced animation is intended to produce an animation with an even pace of change, it does not make sense to define distance functions for all data types. Distance can be usefully defined for types whose values are n-dimensional vectors (including scalars, which are 1-dimensional vectors). For example, a <length> value is a scalar value, and a <color> value is a 3-dimensional vector. Thus attributes of these types can have paced animation applied to them. On the other hand, a <list-of-length> (as used by stroke-dasharray ) is a list of scalars (1-dimensional vectors), and <list-of-points> (as used by the points attribute on a polygon ) is a list of 2-dimensional vectors. Therefore, these types do not have a distance function defined and cannot have paced animation applied to them.
The distance functions for types that support paced animation are as follows:
distance(Va, Vb) = |Va - Vb|
Examples: animating the x attribute on a rect , or the stroke-width attribute on a circle .
distance(Va, Vb) = sqrt((Va.red - Vb.red)2 + (Va.green - Vb.green)2 + (Va.blue - Vb.blue)2), where:
Each of the color component values is usually in the range [0, 1], where 0 represents none of that color component, and 1 represents the maximum amount of that color component, in the sRGB gamut [SRGB]. Since <color> values may specify colors outside of the sRGB gamut, these component values may lie outside the range [0, 1].
distance(Va, Vb) = sqrt((Va.tx - Vb.tx)2 + (Va.ty - Vb.ty)2), where:
Example (for all transform definition types): animating the transform attribute on a g using animateTransform .
distance(Va, Vb) = sqrt((Va.sx - Vb.sx)2 + (Va.sy - Vb.sy)2), where:
Note that, as when specifying scale transformations in a <transform-list>, if the y component of the scale is omitted it is implicitly equal to the x component.
distance(Va, Vb) = sqrt((Va.angle - Vb.angle)2), where:
Since the distance function for rotations is not in terms of the rotation center point components, a paced animation that changes the rotation center point may not appear to have a paced movement when the animation is applied.
Distance functions for all other data types are not defined. If calcMode="paced" is used on an animation of an attribute whose type is not one of those listed above, the animation effect is undefined. SVG user agents may choose to perform the animation as if calcMode="linear", but this is not required. Authors are recommended not to specify paced animation on types not listed above.
The following attributes are the animation timing attributes. They 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.
In the syntax specifications that follow, optional white space is indicated as "S", defined as follows:
S ::= (#x20 | #x9 | #xD | #xA)*
Attribute definitions:
Defines when the element should begin (i.e. become active).
The attribute value is a semicolon separated list of values.
begin
or end
to
identify whether to synchronize with the beginning or
active end of the referenced animation element.The begin of the animation will be determined by a "beginElement()" method call or a hyperlink targeted to the element.
The animation DOM methods are described in DOM interfaces.
Specifies the simple duration.
The attribute value can be one of the following:
The animation must have a dur attribute.
Defines an end value for the animation that can constrain the active duration. The attribute value is a semicolon separated list of values.
A value of 'indefinite' specifies that the end of the animation will be determined by an endElement method call (the animation DOM methods are described in DOM interfaces).
Specifies the minimum value of the active duration.
Value must not be negative.
The default value for min is '0'. This does not constrain the active duration at all.
Specifies the maximum value of the active duration.
Value must be greater than 0.
There is no default value for max . This does not constrain the active duration at all.
Specifies the number of iterations of the animation function. It can have the following attribute values:
Specifies the total duration for repeat. It can have the following attribute values:
f(t)
.This attribute can have the following values:
The animation effect is removed (no longer applied) when the active duration of the animation is over. After the active end of the animation, the animation no longer affects the target (unless the animation is restarted - see SMIL Animation: Restarting animation).
This is the default value.
The grammar for clock values is:
Clock-val ::= Full-clock-val | Partial-clock-val | Timecount-val Full-clock-val ::= Hours ":" Minutes ":" Seconds ("." Fraction)? Partial-clock-val ::= Minutes ":" Seconds ("." Fraction)? Timecount-val ::= Timecount ("." Fraction)? (Metric)? Metric ::= "h" | "min" | "s" | "ms" Hours ::= DIGIT+; any positive number Minutes ::= 2DIGIT; range from 00 to 59 Seconds ::= 2DIGIT; range from 00 to 59 Fraction ::= DIGIT+ Timecount ::= DIGIT+ 2DIGIT ::= DIGIT 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:
02:30:03
= 2 hours, 30
minutes and 3 seconds 50:00:10.25
= 50 hours, 10 seconds and
250 milliseconds
02:33
= 2 minutes and 33
seconds 00:10.5
= 10.5 seconds = 10 seconds and
500 milliseconds 3.2h
= 3.2 hours = 3
hours and 12 minutes 45min
= 45 minutes 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
00:00.005 = 5 milliseconds
The following attributes are the animation value attributes. They are common to elements animate , animateMotion and animateTransform . These attributes define the values that are assigned to the target attribute over time. The attributes below provide control over the relative timing of keyframes and the interpolation method between discrete values.
Attribute definitions:
Specifies the interpolation mode for the animation. This can take any of the following values. The default mode is 'linear', however if the attribute does not support linear interpolation (e.g. for strings), the calcMode attribute is ignored and discrete interpolation is used.
A semicolon-separated list of time values used to control the pacing of the animation. Each time in the list corresponds to a value in the 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.
For animations specified with a values list, the keyTimes attribute if specified must have exactly as many values as there are in the values attribute. For from/to/by animations, the keyTimes attribute if specified must have two values.
Each successive time value must be greater than or equal to the preceding time value.
The keyTimes list semantics depends upon the interpolation mode:
If the interpolation mode is 'paced', the keyTimes attribute is ignored.
If there are any errors in the keyTimes specification (bad values, too many or too few values), the document fragment is in error (see error processing).
If the simple duration is indefinite, any keyTimes specification will be ignored.
Because paced animation interpolation is unspecified for some value types, authors are encouraged to use 'linear' animation interpolation with calculated keyTimes to achieve particular interpolation behavior for these types.
Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for this attribute is the SMIL Animation specification. In particular, see SMIL Animation: 'keyTimes' attribute ([SMILANIM], section 3.2.3).
A set of B zier control points associated with
the keyTimes list, defining a cubic
B zier 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
B zier control points for one time segment. Note:
SMIL
allows these values to be separated either by commas with
optional whitespace, or by whitespace alone. 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 values must all be in the range 0 to 1.
This attribute is ignored unless the calcMode is set to 'spline'.
If there are any errors in the keySplines specification (bad values, too many or too few values), the document fragment is in error (see error processing).
Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for this attribute is the SMIL Animation specification. In particular, see SMIL Animation: 'keySplines' attribute ([SMILANIM], section 3.2.3).
The SMIL Animation specification [SMILANIM] defines the detailed processing rules associated with the above attributes. Except for any SVG-specific rules explicitly mentioned in this specification, the SMIL Animation 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 with the following exception.
In order to provide behavior that is intuitive and consistent between discrete animations with an explicitly specified from attribute (e.g. "from-to animation") and those where the underlying value is used (e.g. "to animation"), the behavior of discrete to-animation in SVG deviates from the definition in SMIL Animation. As with a discrete from-to animation, a discrete to animation will set the underlying value for the first half of the simple duration (or, if a keyTimes list is provided, until the simple duration specified by the second value in the keyTimes list) and the to value for the remainder of the simple duration.
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 function that the keySplines attribute defines. 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.
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:
Value of keySplines | 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 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.
The following attributes are the animation addition attributes, which are common to elements animate , animateMotion and animateTransform .
Attribute definitions:
Controls whether or not the animation is additive.
Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for this attribute is the SMIL Animation specification. In particular, see SMIL Animation: 'additive' attribute ([SMILANIM], section 3.3.6).
Controls whether or not the animation is cumulative.
This attribute is ignored if the target attribute value does not support addition, or if the animation element does not repeat.
Cumulative animation is not defined for "to animation".
This attribute will be ignored if the animation function is specified with only the to attribute.
Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for this attribute is the SMIL Animation specification. In particular, see SMIL Animation: 'accumulate' attribute ([SMILANIM], section 3.3.1).
SVG allows attributes to be animated. If a given attribute is inheritable by descendants, then animations on a parent element such as a g element has the effect of propagating the attribute animation values to descendant elements as the animation proceeds; thus, descendant elements can inherit animated attributes from their ancestors.
The animate element is used to animate a single attribute 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>
For a list of attributes that can be animated using the animate element, see Elements, attributes 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.
Attribute definitions:
For a list of attributes that can be animated using the set element, see Elements, attributes that can be animated.
The animateMotion element causes a referenced element to move along a motion path.
Except for any SVG-specific rules explicitly mentioned in this specification, the normative definition for this element is the SMIL Animation specification. In particular, see SMIL Animation: 'animateMotion' element ([SMILANIM], section 4.3).
Attribute definitions:
keyPoints takes a semicolon-separated list of floating point values between 0 and 1 and indicates how far along the motion path the object shall move at the moment in time specified by corresponding keyTimes value. Distance calculations use the user agent's distance along the path algorithm. Each progress value in the list corresponds to a value in the keyTimes attribute list.
If a list of keyPoints is specified, there must be exactly as many values in the keyPoints list as in the keyTimes list.
If there are any errors in the keyPoints specification (bad values, too many or too few values), then the document is in error (see Error processing).
The rotate attribute post-multiplies a supplemental transformation matrix onto the CTM of the target element to apply a rotation transformation about the origin of the current user coordinate system. The rotation transformation is applied after the supplemental translation transformation that is computed due to the path attribute.
The default value is '0'.
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.
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 and to . Regarding determining the points which correspond to the keyTimes attributes, the keyPoints attribute overrides path , which overrides values , which overrides from , by and 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"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="5cm" height="3cm" viewBox="0 0 500 300" xmlns="http://www.w3.org/2000/svg" version="1.1" 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>(SVG-enabled browsers only)
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) |
For a list of elements that can be animated using the animateMotion element, see Elements, attributes 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.
Attribute definitions:
The from , by and to attributes take a value expressed using the same syntax that is available for the given transformation type:
(See The transform attribute.)
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 animation effect for animateTransform is post-multiplied to the underlying value for additive animateTransform animations (see below) instead of added to the underlying value, due to the specific behavior of animateTransform .
From-to, from-by and by animations are defined in SMIL to be equivalent to a corresponding values animation. See the Animation function values section of SMIL Animation ([SMILANIM], section 3.2.2). However, to animations are a mixture of additive and non-additive behavior, as described in the How from, to and by attributes affect additive behavior section of SMIL Animation ([SMILANIM], section 3.3.6). To animations provide specific functionality to get a smooth change from the underlying value to the to attribute value, which conflicts mathematically with the requirement for additive transform animations to be post-multiplied. As a consequence, in SVG 1.1 the behavior of to animations for animateTransform is undefined. Authors are suggested to use from-to, from-by, by or values animations to achieve any desired transform animation.
If calcMode has the value 'paced', then the "distance" for the transformation is calculated 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)" ... />
Note that the zero value used when performing a by animation with type="scale" is indeed 0. Thus, performing the following animation causes the rectangle to be invisible at time 0s (since the animated transform list value is 'scale(0)'), and be scaled back to its original size at time 5s (since the animated transform list value is 'scale(1)'):
<rect width="100" height="100"> <animateTransform attributeName="transform" attributeType="XML" type="scale" by="1" dur="5s" fill="freeze"/> </rect>
When a transform animation has accumulate='sum', the accumulation that occurs for each completed repetition of the animation is computed on the values specified in the animateTransform element's animation value attributes (i.e., values , from , to and by ) and not on the transformation matrix that these values represent. For example, in the following code snippet, 3 is added to the scale value at the start of each repetition:
<rect width="100" height="100"> <animateTransform attributeName="transform" attributeType="XML" type="scale" from="2" to="3" repeatCount="3" dur="4s" fill="freeze"/> </rect>
Transform item types that can have multiple values 'translate', 'scale' and 'rotate' are treated as vectors and accumulation is performed with vector addition. Optional values that are omitted are taken to have their usual implied value: 1 for the <sy> component of a 'scale' and 0 for the <tx> component of a 'translate' and the <cx cy> components of a 'rotate'.
For example, consider the following code snippet, which has a cumulative transform animation of type 'rotate':
<rect width="100" height="100"> <animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0 30 40" to="10 30 40" repeatCount="2" dur="1s" fill="freeze"/> </rect>
At time 1 second, the animated value of transform on the rect will jump from 'rotate(10 30 40)' to 'rotate(10 60 80)', because the effect of the accumulation is to take the value at the end of the first repetition, '10 30 40', and add to it the value at simple duration t = 0s, which is '0 30 40'.
For a list of attributes that can be animated using the animateTransform element, see Elements, attributes that can be animated.
The following lists all of the elements which can be animated by an animateMotion element:
Each attribute within this specification indicates whether or not it can be animated by SVG's animation elements. Animatable attributes are designated as follows:
Animatable: yes.
whereas attributes that cannot be animated are designated:
Animatable: no.
Some attributes are defined as being animatable but only for non-additive animations:
Animatable: yes (non-additive).
SVG has a defined set of basic data types for its various supported attributes. For those attributesthat 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 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 | animateTransform | Notes |
---|---|---|---|---|---|
<angle> | yes | yes | yes | no | |
<color> | yes | yes | yes | no | Only additive if each value can be converted to an RGB color. |
<coordinate> | yes | yes | yes | no | |
<frequency> | no | no | no | no | |
<integer> | yes | yes | yes | no | |
<length> | yes | yes | yes | no | |
<list-of-Ts> | no | yes | yes | no | |
<number> | yes | yes | yes | no | |
<paint> | yes | yes | yes | no | Only additive if each value can be converted to an RGB color. |
<percentage> | yes | yes | yes | no | |
<time> | no | no | no | no | |
<transform-list> | yes | no | no | yes | Additive means that a transformation is post-multiplied to the base set of transformations. |
<iri> | no | yes | yes | no | |
All other data types used in animatable attributes | no | yes | yes | no |
Any deviation from the above table or other special note about the animation capabilities of a particular attribute is included in the section of the specification where the given attribute is defined.