Here is a simple example of using animateTransform to rotate three circles:
<circle . . . <animateTransform attributeName="transform" type="rotate" begin="crcl1.click" values="0;7200" dur="20s" /> <animateTransform attributeName="transform" type="scale" begin="crcl1.click" values="1,1;3,0.3;1,1" additive="sum" dur="20s"/> </circle> <g transform="translate(300 0)"> <circle style="fill:red" cx="0" cy="0" r="30"> <animateTransform attributeName="transform" type="rotate" begin="crcl1.click" values="0;7200" dur="10s" repeatCount="2"/> <animateTransform attributeName="transform" type="scale" begin="crcl1.click" values="1,1;2,0.1;1,1" additive="sum" dur="10s" repeatCount="2"/> </circle> </g> <g transform="translate(500 0)"> <circle style="fill:green" cx="0" cy="0" r="30"> <animateTransform attributeName="transform" type="rotate" begin="crcl1.click" values="0;-720" dur="5s" repeatCount="indefinite" repeatDur="6s" fill="freeze"/> <animateTransform attributeName="transform" type="scale" begin="crcl1.click" values="1,1;0.1,3;1,1" additive="sum" dur="5s" repeatCount="indefinite" repeatDur="6s" fill="freeze"/> </circle> </g>
The main points to notice are:
- type attribute specifies type of transformation, in this case whether it is a rotation or a scaling
- additive="sum" ensures two animations on the same attribute both take place
- Another way of doing the same thing would be to have nested <g> elements around the circle and apply one transformation to each
- Because of the need to have the type attribute, animateTransform cannot be replaced by the animate element
- The blue circle is straightforward: it rotates the circle 20 times while the scaling turns it into an ellipse for part of that time
- The red circle demonstrates the attribute repeatCount. The circle is rotating and scaling twice as fast completing the initial animation in 10s but the repeatCount causes it to perform the animation a second time so it also takes 20 secs to complete
- The green circle is much slower as it completes only two rotations in 5 secs and the repeatCount allows it to continue forever. However the repeatDur attribute stops the repeats after 6 secs before it has completed the cycle.
- Be careful with using repeatDur as not all the browsers implement it correctly. For example, Opera ignores it.
The additive animations can be on the same attribute:
<circle cx="100" cy="160" r="30" style="fill:green;stroke:none"> <animate attributeName="cx" values="0;100" begin="crcl2.click+1s" dur="1s" additive="sum" fill="freeze" /> <animate attributeName="cx" values"0;300" begin="crcl2.click+2.5s" dur="2s" additive="sum" fill="freeze" /> </circle>
The circle starts at the position x=100 and the first animation moves the circle to the right a further 100 from that position as it is to be added. Without the additive="sum" it would start at position x=0. The second starts from the point that the first has reached so far.
The situation gets more complicated when you have the animation being repeated. If you want to continue adding to the attribute value, you need:
<circle cx="100" cy="340" r="30" style="fill:red;stroke:none"> <animate attributeName="cx" values="0;100" begin="crcl3.click+1s" dur="1s" additive="sum" accumulate="sum" repeatCount="5" fill="freeze" /> </circle>
The default values for the two attributes are:
- additive default is replace
- accumulate default is none
So if neither attribute was set, the animation would go from cx=0 to cx=100 five times.
Here is a fun example that makes the text look as though it is 3 dimensions:
<g transform="skewX(10)"> <g transform="skewY(40)"> <text style="font-size:40px;fill:green"> <animateTransform attributeName="transform" type="rotate" values="0;360" begin="crcl4.click" dur="1.5s" repeatCount="indefinite"/> Hopgood</text> </g> <g>