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>