This short tutorial will provide some tips on editing SVG pictures in Inkscape in order to add some SVG-SMIL animation and interactivity with other tools. Inkscape doesn't allow SVG code editing, but it is useful to learn some Inkscape tricks to prepare the SVG for adding animation code to animations made from complex clipart that you could find on http://openclipart.org.
Alternatively, you can try SVG animation assistant, a frame-by-frame animation tool. You either can compile the source code or buy a very cheap windows version (as of nov. 2018 for $2.25 AUD).
Examples in this page were tested on Jan 2014 with Firefox and Chrome.
Prerequisites:
See also:
Below we will use the following examples:
Since Inkscape is primairly a drawing tool and not a web drawing tool, it includes extensions that add functionality to the editor (e.g. layers) and power to "plain" SVG. According to the XML standard this is perfectly legal if a namespace mechanism is used. Web browsers do not understand the "inkscape" and "sodipodi" elements and simply ignore these.
In addition, drawings may use weird coordinates, include unused definitions, the drawing canvas may be too big, etc. As a consequence you should optimize the drawing, even if in theory this is not strictly necessary. Cleaning and optimizing is particularly important if you plan to import SVG drawings to HTML5 via the object or the img element.
Anyhow, in order to insure that pictures show as intended, you should try both optimizing and translating to plain SVG. This may not always work, but most of the time it does. Ok, so if possible, do the following (as also explained in the Using SVG with HTML5 tutorial:
In order to write animation code, it is probably best to give special meaninful ID's to the objects that you would like to manipulate. E.g. avoid working with path3404 etc. and call it leg_left for example.
Procedure:
Set
According to the tutorial advanced, the main use of the Simplify command (Ctrl+L) is reducing the number of nodes on a path while almost preserving its shape. “The amount of simplification (called the threshold) depends on the size of the selection. Therefore, if you select a path along with some larger object, it will be simplified more aggressively than if you select that path alone. Moreover, the Simplify command is accelerated. This means that if you press Ctrl+L several times in quick succession (so that the calls are within 0.5 sec from each other), the threshold is increased on each call. (If you do another Simplify after a pause, the threshold is back to its default value.) By making use of the acceleration, it is easy to apply the exact amount of simplification you need for each case.” (retrieved Jan 2014).
Sometimes, e.g. in the dragon head silhouette drawing, the whole SVG picture is just a single path. If you plan to animate some detail, you will have to cut it off.
Procedure:
(2) Select the path you plan to edit
+
button on the keyboard or by using the View
menu. Try View->Zoom->Drawing or View->Zoom-SelectionBreak path at selected nodes
in the upper toolbarPath->Break Apart
will break the path into two pathsSome extra tips:
Alternative:
Example showing cut Dragon tongue (don't try this with a live one)
Constructive solid geometry is a popular 2D/3D modelin technique that allows to create interesting shapes from other shapes. See the Subtractive geometry in Adobe Flash CS6 where we show how to create a Moon symbol by subtracting a circle from a circle. A similar functionaly exist in Stich Era, Stich Era, an embroidery software. OpenScad is a 3D CAD tool where people design models by coding.
Read:
Tips:
Example to create an eye from a dragon head outline
CTRL-
You cannot ! Therefore, we suggest to export the drawing to simple SVG and to use a text editor.
If you added objects to animated and if you did change the id's names as suggested above, programming will now be much easier. Make sure to add xmlns:xlink="http://www.w3.org/1999/xlink"
declaration in the SVG root if you use any sort of links !!
The animation code we added at the end of the file (using linking) is:
<animate xlink:href="#eye"
dur="12s" begin="1s"
to="#000000" from="#CC9933"
repeatCount="indefinite"
calcMode="linear" attributeName="fill"/>
<animate id="nose_anim1"
xlink:href="#nose"
dur="2s" begin="0s; nose_anim2.end"
from="yellow" to="red"
attributeType="CSS"
calcMode="linear" attributeName="fill"/>
<animate id="nose_anim2"
xlink:href="#nose"
dur="2s" begin="nose_anim1.end"
to="yellow" from="red"
calcMode="linear" attributeName="fill"/>
<animate id="tongue_anim1"
xlink:href="#tongue"
dur="12s" begin="1s"
values="#501616;black;#501616"
repeatCount="indefinite"
calcMode="linear" attributeName="fill"/>
<animateTransform id="tongue_anim1a"
xlink:href="#tongue"
dur="6s" begin="1s; tongue_anim2a.end"
to="0.99" from="1.0"
attributeName="transform" type="scale"
/>
<animateTransform id="tongue_anim2a"
xlink:href="#tongue"
dur="6s" begin="tongue_anim1a.end"
from="0.99" to="1.0"
attributeName="transform" type="scale"
/>
Notice:
Animating the size of a path element or doing a motion animation with a path element can be very hairy, since this type of animation actually changes the coordinate system of the element. For example, when you grow a path using a animateTransform
, the element may just move somewhere. If you understand math, you probably could figure out a good solution. I can't, therefore I suggest the following strategy:
svg
elementThe following example includes a modified eye that is animated, i.e. we substituted the original left eye by a new version.
Code excerpt:
<desc>-------------------------------------------------------------------------</desc>
<desc>Below is some substituted code for the eye. We use a embedded svg element</desc>
<svg viewBox="0 0 28.5 33.2"
width="28.5" height="33.2"
x="369" y="143"
>
<defs id="defs6005">
<linearGradient id="eyeGrad" y2="193.43" gradientUnits="userSpaceOnUse" y1="159.23"
gradientTransform="matrix(0.95876002,-0.28420001,0.28420001,0.95876002,-353.16135,-55.73074)" x2="315.38" x1="314.7">
<stop stop-color="#000000" offset="0"/>
<stop stop-color="#b9b9b9" offset="1"/>
</linearGradient>
<linearGradient id="eyeGrad2" y2="193.43" gradientUnits="userSpaceOnUse" y1="159.23"
gradientTransform="matrix(0.95876002,-0.28420001,0.28420001,0.95876002,-353.16135,-55.73074)" x2="315.38" x1="314.7">
<stop stop-color="#000000" offset="0"/>
<stop stop-color="#00ffff" offset="1"/>
</linearGradient>
</defs>
<g id="eye_left" transform="translate(14.286238,-7.203961)">
<path id="path4885" stroke-linejoin="round"
d="m12.943,19.954a16.25,13.5,73.489,0,1,-25.887,7.6734,16.25,13.5,73.489,0,1,25.887,-7.6734z"
stroke="#000000" stroke-linecap="square" stroke-width="1.09999478" fill="url(#eyeGrad2)"/>
</g>
<circle id="pupil_left" r="1" cx="15" cy="15" fill="#8b0000"/>
</svg>
<!-- original eye removed
<g
id="eye_left">
<path
d="m 329.5,176.61218 a 13.5,16.25 0 1 1 -27,0 13.5,16.25 0 1 1 27,0 z"
transform="matrix(0.95876,-0.2842,0.2842,0.95876,28.837,77.84)"
id="path4885"
style="fill:url(#linearGradient6649);stroke:#000000;stroke-width:1.10000002;stroke-linecap:square;stroke-linejoin:round" />
</g>
......
-->
<animateTransform id="eye_anim5"
xlink:href="#eye_left"
dur="6s" begin="1s"
values = "1.0;0.9;1.0"
repeatCount="indefinite"
additive="sum"
attributeName="transform" type="scale"/>
<animate id="eye_anim6"
xlink:href="#pupil_left"
dur="6s" begin="1s"
values = "1;2;1"
repeatCount="indefinite"
attributeName="r"/>
In order to move the object along a path you will need two objects. The object that you want to animate and the object that represents the path.
Example: http://tecfaetu.unige.ch/etu-maltt/tetris/karanis0/stic-2/ex11/drawingThree.svg
You will see the following code:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="744.09448"
height="1052.3622"
id="svg2">
<metadata
id="metadata3007">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3005" />
<g
id="layer1">
<!--ellipseObj-->
<path
d="m 511.42859,652.36218 a 42.857145,17.142858 0 1 1 -85.71429,0 42.857145,17.142858 0 1 1 85.71429,0 z"
transform="translate(0,-202)"
id="ellipseObj"
style="fill:#1d0075;fill-opacity:0.96808543;stroke:#000000;stroke-width:3.7420001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<!--ellipsePath-->
<path
d="m 382.85714,235.21933 a 85.714287,34.285713 0 1 1 -171.42857,0 85.714287,34.285713 0 1 1 171.42857,0 z"
transform="matrix(1.8089222,0,0,2.480639,-168.9369,-401.13206)"
id="ellipsePath"
style="fill:#1d0075;fill-opacity:0.02659577;stroke:#000000;stroke-width:3.7420001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
</svg>
By repairing the code you will end up with something like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="744.09448"
height="1052.3622"
id="svg2">
<g
id="layer1">
<path
d="m 511.42859,652.36218 a 42.857143,17.142857 0 1 1 -85.71429,0 42.857143,17.142857 0 1 1 85.71429,0 z"
transform="translate(0,-202)"
id="ellipseObj"
style="fill:#1d0075;fill-opacity:0.96808543;stroke:#000000;stroke-width:3.7420001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
d="m 382.85714,235.21933 a 85.714287,34.285713 0 1 1 -171.42857,0 85.714287,34.285713 0 1 1 171.42857,0 z"
transform="matrix(1.8089222,0,0,2.480639,-168.9369,-401.13206)"
id="ellipsePath"
style="fill:#1d0075;fill-opacity:0.02659577;stroke:#000000;stroke-width:3.7420001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
</svg>
In order to animate the ellipseObj you can add the following code under the last path
<--in order to have an elliptic animation you have to copy-paste the path of the ellipsePath-->
<animateMotion xlink:href="#ellipseObj"
repeatCount="indefinite"
dur="10s"
path="382.85714,235.21933 a 85.714287,34.285713 0 1 1 -171.42857,0 85.714287,34.285713 0 1 1 171.42857,0 z" />