library(minisvg)
There are at least 5 methods of animating SVG. These methods are detailed on the w3.org pages).
The 5 methods are as follows:
This vignette assumes you are familiar with SVG tags and document structures.
This document describes method 1 - SMIL animation
SMIL stands for Synchronized Multimedia Integration Language.
The way it works is to add an animate
, animateTransform
or animateMotion
tag as a child of the element to be animated.
The animate
tag describes the parent attribute to be modified and a list of states for that attribute, or perhaps a path to be followed.
The following examples are adaptions of the MDN docs on SMIL animation
animate
taganimate
with from
and to
An easy way to use animate
is to just specify the start and end values of an attribute.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Build a small SVG with a circle #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ doc <- svg_doc(width = 240, height = 100) doc$title("Attribute animation with SMIL") doc$rect(x=0, y=0, width=240, height = 100, stroke='black', fill='white', stroke_width = 1) circle <- doc$circle(cx = 20, cy = 50, r=15, fill = 'blue', stroke = 'none', stroke_width = 1)
Show SVG text (click to open)
<?xml version="1.0" encoding="UTF-8"?>
<svg width="240" height="100" viewBox="0 0 240 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>
Attribute animation with SMIL
</title>
<rect stroke="black" fill="white" stroke-width="1" x="0" y="0" width="240" height="100" />
<circle fill="blue" stroke="none" stroke-width="1" cx="20" cy="50" r="15" />
</svg>
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Add an 'animate' child to the circle #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ circle$animate(attributeName = 'cx', from=-20, to=260, dur=5, repeatCount = 'indefinite')
Show SVG text (click to open)
<?xml version="1.0" encoding="UTF-8"?>
<svg width="240" height="100" viewBox="0 0 240 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>
Attribute animation with SMIL
</title>
<rect stroke="black" fill="white" stroke-width="1" x="0" y="0" width="240" height="100" />
<circle fill="blue" stroke="none" stroke-width="1" cx="20" cy="50" r="15">
<animate attributeName="cx" from="-20" to="260" dur="5" repeatCount="indefinite" />
</circle>
</svg>
animate
with keyTimes
To have more control of the animation over time, you can set a particular value (values
) at a set of nominated key frames (keyTimes
)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Build a small SVG with a circle #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ doc <- svg_doc(width = 240, height = 100) doc$title("Attribute animation with SMIL") doc$rect(x=0, y=0, width=240, height = 100, stroke='black', fill='white', stroke_width = 1) circle <- doc$circle(cx = 20, cy = 50, r=15, fill = 'blue', stroke = 'none') #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Animate the X coordinate of the circle giving it key times and # corresponding values #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ circle$animate( attributeName = 'cx', keyTimes = c( 0, 0.25, 0.5, 0.75, 1), values = c(20 , 60, 220, 60, 20), dur = 5, repeatCount = 'indefinite' ) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Also animate the y coordinate #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ circle$animate( attributeName = 'cy', keyTimes = c( 0, 0.33, 0.66, 0.9, 1), values = c(50, 100, 50, 0, 50), dur = 5, repeatCount = 'indefinite' )
Show SVG text (click to open)
<?xml version="1.0" encoding="UTF-8"?>
<svg width="240" height="100" viewBox="0 0 240 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>
Attribute animation with SMIL
</title>
<rect stroke="black" fill="white" stroke-width="1" x="0" y="0" width="240" height="100" />
<circle fill="blue" stroke="none" cx="20" cy="50" r="15">
<animate attributeName="cx" dur="5" repeatCount="indefinite" values="20;60;220;60;20" keyTimes="0;0.25;0.5;0.75;1" />
<animate attributeName="cy" dur="5" repeatCount="indefinite" values="50;100;50;0;50" keyTimes="0;0.33;0.66;0.9;1" />
</circle>
</svg>
animateTransform
tagAs the name suggests animateTransform
lets you animate the transformation associated with its parent. We are no longer animating a simple attribute but the entire transformation which puts the object into the document.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Build a small SVG with a rectangle #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ doc <- svg_doc(width = 240, height = 100) doc$title("Attribute animation with SMIL") doc$rect(x=0, y=0, width=240, height = 100, stroke='black', fill='white', stroke_width = 1) rect <- doc$rect(x=80, y=40, width=15, height=34, fill = 'blue', stroke = 'none') rect$animateTransform( attributeName = 'transform', type = 'rotate', from = c(0 , 120, 50), to = c(360, 120, 50), dur = 5, repeatCount = 'indefinite' )
Show SVG text (click to open)
<?xml version="1.0" encoding="UTF-8"?>
<svg width="240" height="100" viewBox="0 0 240 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>
Attribute animation with SMIL
</title>
<rect stroke="black" fill="white" stroke-width="1" x="0" y="0" width="240" height="100" />
<rect fill="blue" stroke="none" x="80" y="40" width="15" height="34">
<animateTransform attributeName="transform" from="0 120 50" to="360 120 50" type="rotate" dur="5" repeatCount="indefinite" />
</rect>
</svg>
animateMotion
taganimateMotion
is a way of animating the position and rotation of an element by moving it along a path.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Build a small SVG with a circle #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ doc <- svg_doc(width = 300, height = 100) doc$title("Attribute animation with SMIL") doc$rect(x=0, y=0, width=300, height = 100, stroke='black', fill='white', stroke_width = 1) rect <- doc$rect(x=0, y=0, width=20, height=20, fill = 'blue', stroke = 'none') rect$animateMotion( path = "M 250,80 H 50 Q 30,80 30,50 Q 30,20 50,20 H 250 Q 280,20,280,50 Q 280,80,250,80Z", dur = 3, repeatCount = 'indefinite', rotate = 'auto' )
Show SVG text (click to open)
<?xml version="1.0" encoding="UTF-8"?>
<svg width="300" height="100" viewBox="0 0 300 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>
Attribute animation with SMIL
</title>
<rect stroke="black" fill="white" stroke-width="1" x="0" y="0" width="300" height="100" />
<rect fill="blue" stroke="none" x="0" y="0" width="20" height="20">
<animateMotion dur="3" repeatCount="indefinite" path="M 250,80 H 50 Q 30,80 30,50 Q 30,20 50,20 H 250 Q 280,20,280,50 Q 280,80,250,80Z" rotate="auto" />
</rect>
</svg>