Using Inkscape for web animation: Difference between revisions
m (→Tutorials) |
|||
(38 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
<pageby nominor="false" comments="false"/> | <!-- <pageby nominor="false" comments="false"/> --> | ||
{{web technology tutorial|Intermediate}} | {{web technology tutorial|Intermediate}} | ||
{{ | {{incomplete}} | ||
== Introduction == | == Introduction == | ||
This short tutorial will provide some tips on editing SVG pictures in Inkscape in order to add some [[SVG-SMIL animation tutorial|SVG-SMIL animation]] and [[Interactive SVG-SMIL animation tutorial|interactivity]] with '''other tools'''. Inkscape doesn't allow SVG code editing, but it is useful to learn some | This short tutorial will provide some tips on editing SVG pictures in [[Inkscape]] in order to add some [[SVG-SMIL animation tutorial|SVG-SMIL animation]] and [[Interactive SVG-SMIL animation tutorial|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 [https://github.com/chr15m/svg-animation-assistant SVG animation assistant], a frame-by-frame animation tool. You either can compile the source code or [https://thebusiness.itch.io/svg-animation-assistant 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: | Prerequisites: | ||
Line 19: | Line 21: | ||
* [[SVG links]] (links to various SVG resources) | * [[SVG links]] (links to various SVG resources) | ||
Below we will use the following | Below we will use the following examples: | ||
; Dragon head silhouette | ; Dragon head silhouette | ||
: Original: [https://openclipart.org/detail/64849/dragon-head-silhouette-by-kuba dragon-head-silhouette-by-kuba] (openclipart.org) | : Original: [https://openclipart.org/detail/64849/dragon-head-silhouette-by-kuba dragon-head-silhouette-by-kuba] (openclipart.org) | ||
: Revised version: [http://tecfa.unige.ch/guides/svg/ex/html5/animation/dragon-head-silhouette.svg dragon-head-silhouette.svg] | : Revised version: [http://tecfa.unige.ch/guides/svg/ex/html5/animation/dragon-head-silhouette.svg dragon-head-silhouette.svg] | ||
: Animated version: [http://tecfa.unige.ch/guides/svg/ex/html5/animation/dragon-head-silhouette.svg dragon-head-silhouette-anim.svg] | : Animated version: [http://tecfa.unige.ch/guides/svg/ex/html5/animation/dragon-head-silhouette-anim.svg dragon-head-silhouette-anim.svg] | ||
; Manga girl | |||
: Original: [https://openclipart.org/detail/2364/girl-with-silver-hair-by-paulliu girl with silver hair] by Ying-Chun Liu PaulLiu | |||
: Cleaned version: [http://tecfa.unige.ch/guides/svg/ex/html5/animation/paulliu_girl_with_silver_hair-mod.svg paulliu_girl_with_silver_hair-mod.svg] | |||
: Animated version: [http://tecfa.unige.ch/guides/svg/ex/html5/animation/paulliu_girl_with_silver_hair-mod2.svg paulliu_girl_with_silver_hair-mod2.svg] | |||
== Optimizing and translating to plain SVG == | |||
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]]: | |||
; Optimizing and cleaning SVG | |||
# '''Fit the document size to the picture size:''' Menu File->Document Properties. In the Custom size panel, open '''Resize page to content''', then click '''Resize page to drawing or selection'''. | |||
# Remove unused DEF's: File->Vacuum Defs. | |||
# '''Optimize SVG''': File -> Save as... -> Optimized SVG''' (the item is somewhere down the list, search for it). Before doing so, keep a copy of the old file. | |||
#* Tick "Enable viewboxing'' in the save dialog. This operation will do two things, Insert correct viewBox, and set width and height attributes to 100%. | |||
# If the above optimizing does not work, use an SVG cleaning program such as: http://www.codedread.com/scour/ | |||
# '''Remove non-standard SVG/Inkscape XML''' (plain SVG): File -> Save as... -> plain SVG. Since this operation will remove layers and other Inkscape specific information, keep a copy of the old file if necessary. | |||
== Identifying and naming SVG elements == | == Identifying and naming SVG elements == | ||
In order to write animation code, it is probably best to give special ID's to the objects that you would like to manipulate. | 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: | '''Procedure:''' | ||
; (1) Open the XML Editor: | ; (1) Open the Inskscape XML Tree Editor: | ||
: ''Menu: Edit -> XML Editor'' or (Shift-CTRL-X) | : ''Menu: Edit -> XML Editor'' or (Shift-CTRL-X) | ||
; (2) Use the selection tool to identify objects in the drawing | ; (2) Use the selection tool to identify objects in the drawing | ||
: Hit '''F1''' (or the top button in the toolbar to the left) | : Hit '''F1''' (or the top button in the toolbar to the left) | ||
: Select the element, either in the drawing pane or by clicking on elements in the XML Editor | : Select the element, either in the drawing pane or by clicking on elements in the XML Editor. | ||
: You may have to ungroup an element in the drawing pane in order to make it clickable. We rather suggest to start from the parent projet in the drawing pane, then explore its children in the XML editor pane. However, some folks have strange ideas on grouping ... try the best. | |||
[[File:Inkscape-editor-1.svg|600px|thumbnail|none|Selecting an SVG element (either in the drawing tool or the XML editor)]] | [[File:Inkscape-editor-1.svg|600px|thumbnail|none|Selecting an SVG element (either in the drawing tool or the XML editor)]] | ||
Line 44: | Line 67: | ||
: In the bottom panel, change its name, then click <code>Set</code> | : In the bottom panel, change its name, then click <code>Set</code> | ||
[[File:Inkscape-editor-2.svg|600px|thumbnail|none|Changing a property value]] | [[File:Inkscape-editor-2.svg|600px|thumbnail|none|Changing a property value]] | ||
: Again, use meaningful id names ! | |||
== Path surgery == | == Path surgery == | ||
Line 49: | Line 73: | ||
=== Simplifying drawings === | === Simplifying drawings === | ||
According to the [http://inkscape.org/doc/advanced/tutorial-advanced.html tutorial advanced], | According to the [http://inkscape.org/doc/advanced/tutorial-advanced.html 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. {{quotation|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). | ||
=== Cutting a path in two parts === | === Cutting a path in two parts === | ||
Line 77: | Line 101: | ||
: If an object is not path (e.g. a rectangle), you can convert it to a path object: (Menu: Path -> Object to Path). But there is no way back ! | : If an object is not path (e.g. a rectangle), you can convert it to a path object: (Menu: Path -> Object to Path). But there is no way back ! | ||
: Use the XML Editor to select an element if necessary (i.e. if you can't select the one you need) | : Use the XML Editor to select an element if necessary (i.e. if you can't select the one you need) | ||
Alternative: | |||
: Redraw the object you plan to animate | |||
: Remove the points from the path that include the part that you wanted to cut off | |||
: Maybe combine the two strategies .... | |||
Example showing cut Dragon tongue (don't try this with a live one) | |||
* http://tecfa.unige.ch/guides/svg/ex/html5/animation/dragon-head-silhouette-anim.svg | |||
=== Kill part of path === | |||
* Hit F2 | |||
* Select a control point and hit the DELETE key | |||
* Kill other points, until the subpath / subshape you want to remove is gone .... | |||
* Then use the curve controls (little circles that stick out from the control points) to smoothen if necessary. | |||
== Constructive solid geometry == | == Constructive solid geometry == | ||
Line 103: | Line 142: | ||
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 <code>xmlns:xlink="http://www.w3.org/1999/xlink"</code> declaration in the SVG root if you use any sort of links !! | 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 <code>xmlns:xlink="http://www.w3.org/1999/xlink"</code> declaration in the SVG root if you use any sort of links !! | ||
=== Dragon example === | |||
* http://tecfa.unige.ch/guides/svg/ex/html5/animation/dragon-head-silhouette-anim.svg | * http://tecfa.unige.ch/guides/svg/ex/html5/animation/dragon-head-silhouette-anim.svg | ||
* http://tecfa.unige.ch/guides/svg/ex/html5/animation/dragon-head-silhouette-anim.html (HTML5 version that includes the SVG with an object element) | * http://tecfa.unige.ch/guides/svg/ex/html5/animation/dragon-head-silhouette-anim.html (HTML5 version that includes the SVG with an object element) | ||
Line 130: | Line 170: | ||
<animate id="tongue_anim1" | <animate id="tongue_anim1" | ||
xlink:href="#tongue" | xlink:href="#tongue" | ||
dur=" | dur="12s" begin="1s" | ||
values="#501616;black;#501616" | |||
repeatCount="indefinite" | |||
calcMode="linear" attributeName="fill"/> | calcMode="linear" attributeName="fill"/> | ||
Line 146: | Line 181: | ||
attributeName="transform" type="scale" | attributeName="transform" type="scale" | ||
/> | /> | ||
<animateTransform id="tongue_anim2a" | <animateTransform id="tongue_anim2a" | ||
xlink:href="#tongue" | xlink:href="#tongue" | ||
Line 152: | Line 188: | ||
attributeName="transform" type="scale" | attributeName="transform" type="scale" | ||
/> | /> | ||
</source> | </source> | ||
Notice: | Notice: | ||
* Rotations in the HTML file were made with CSS, i.e. we rotate the HTML object element. | * Rotations in the HTML file were made with CSS, i.e. we rotate the HTML object element. | ||
* Instead of chaining two animations (nose_anime1 and nose_anime2), rather use the values attribute (tongue_anim1). Less code, more elegant ... | |||
* The header of the SVG file (includes a viewBox and set width and height to 100% (good for inclusion in HTML5) | * The header of the SVG file (includes a viewBox and set width and height to 100% (good for inclusion in HTML5) | ||
* the chaining of the nose and tongue animation as explained in the [[SVG-SMIL animation tutorial]] | * the chaining of the nose and tongue animation as explained in the [[SVG-SMIL animation tutorial]] | ||
* Doing transform animations can be ''very'' hairy with imported pictures, because drawings are often transformed in various ways and animating these has strange effects on the coordinate system. The same is true for motion animation. E.g. instead of redrawing a tongue, we just cut it off an existing path. Scaling will scale the ''whole'' coordinate system used to define the tongue, not just the tongue itself ... | * Doing transform animations can be ''very'' hairy with imported pictures, because drawings are often transformed in various ways and animating these has strange effects on the coordinate system. The same is true for motion animation. E.g. instead of redrawing a tongue, we just cut it off an existing path. Scaling will scale the ''whole'' coordinate system used to define the tongue, not just the tongue itself ... | ||
== | === Dealing with path objects === | ||
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 <code>animateTransform</code>, 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: | |||
# From your animated SVG file, copy / paste the path you plan to animate to a new SVG file | |||
# Adjust the drawing Canvevas: Menu: File->Document Properties->Custom Size; Select Resize page to drawing or selection | |||
# Save the new file as optimized SVG | |||
# Insert an svg element into the animation file | |||
# Copy/paste the code from the new SVG file between the <code>svg</code> element | |||
# Adjust the the x and y position of the <svg>element</code> | |||
# Remove the old path if not already done so. | |||
The following example includes a modified eye that is animated, i.e. we substituted the original left eye by a new version. | |||
* http://tecfa.unige.ch/guides/svg/ex/html5/animation/paulliu_girl_with_silver_hair.svg (Copy of the [https://openclipart.org/detail/2364/girl-with-silver-hair-by-paulliu original] (from openclipart.org) | |||
* http://tecfa.unige.ch/guides/svg/ex/html5/animation/paulliu_girl_with_silver_hair-mod2.svg (Eye animation version, after surgery) | |||
* http://tecfa.unige.ch/guides/svg/ex/html5/animation/girl_eye_left.svg (just the eye that we extracted, optimized and copied pack) | |||
Code excerpt: | |||
<source lang="XML" enclose="div"> | |||
<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"/> | |||
</source> | |||
===Moving an object along a path=== | |||
====Introduction==== | |||
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 | |||
====Procedure==== | |||
* Create an object by using the ellipse tool and name it "ellipseObj" (Edit-->xml editor-->id"ellipseObj"-->set) -- this is the moving object | |||
* Create an ellipse and call it "ellipsePath" (Edit-->xml editor-->id"ellipsePath"-->set) -- this is the path | |||
:* If you want an anti-clock movement (select the object-->object-->Flip Vertical) | |||
* Save the file as plain svg | |||
* Open the file with an xml editor | |||
'''You will see the following code:''' | |||
<source lang="XML" enclose="div"> | |||
<?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> | |||
</source> | |||
* In order to avoid the errors it would be nice to clean up the code and add a few extra lines. | |||
'''By repairing the code you will end up with something like this:''' | |||
<source lang="XML" enclose="div"> | |||
<?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> | |||
</source> | |||
'''In order to animate the ellipseObj you can add the following code under the last path''' | |||
<source lang="XML" enclose="div"> | |||
<--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" /> | |||
</source> | |||
* If you want you can erase the ellipsePath in order to display only the ellipseObj | |||
== Links == | == Links == | ||
Line 199: | Line 400: | ||
[[Category: SVG]] | [[Category: SVG]] | ||
[[Category: | [[Category: Inkscape]] |
Latest revision as of 21:47, 17 December 2018
Introduction
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:
- Using SVG with HTML5 tutorial
- Static SVG tutorial
- SVG-SMIL animation tutorial
- Interactive SVG-SMIL animation tutorial (maybe ...)
See also:
Below we will use the following examples:
- Dragon head silhouette
- Original: dragon-head-silhouette-by-kuba (openclipart.org)
- Revised version: dragon-head-silhouette.svg
- Animated version: dragon-head-silhouette-anim.svg
- Manga girl
- Original: girl with silver hair by Ying-Chun Liu PaulLiu
- Cleaned version: paulliu_girl_with_silver_hair-mod.svg
- Animated version: paulliu_girl_with_silver_hair-mod2.svg
Optimizing and translating to plain SVG
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:
- Optimizing and cleaning SVG
- Fit the document size to the picture size: Menu File->Document Properties. In the Custom size panel, open Resize page to content, then click Resize page to drawing or selection.
- Remove unused DEF's: File->Vacuum Defs.
- Optimize SVG: File -> Save as... -> Optimized SVG (the item is somewhere down the list, search for it). Before doing so, keep a copy of the old file.
- Tick "Enable viewboxing in the save dialog. This operation will do two things, Insert correct viewBox, and set width and height attributes to 100%.
- If the above optimizing does not work, use an SVG cleaning program such as: http://www.codedread.com/scour/
- Remove non-standard SVG/Inkscape XML (plain SVG): File -> Save as... -> plain SVG. Since this operation will remove layers and other Inkscape specific information, keep a copy of the old file if necessary.
Identifying and naming SVG elements
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:
- (1) Open the Inskscape XML Tree Editor
- Menu: Edit -> XML Editor or (Shift-CTRL-X)
- (2) Use the selection tool to identify objects in the drawing
- Hit F1 (or the top button in the toolbar to the left)
- Select the element, either in the drawing pane or by clicking on elements in the XML Editor.
- You may have to ungroup an element in the drawing pane in order to make it clickable. We rather suggest to start from the parent projet in the drawing pane, then explore its children in the XML editor pane. However, some folks have strange ideas on grouping ... try the best.
- (3) Click on id in the XML editor
- In the bottom panel, change its name, then click
Set
- Again, use meaningful id names !
Path surgery
Simplifying drawings
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).
Cutting a path in two parts
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:
- (1) Get the path edit tool
- Hit F2 or select second tool in the left tool palette
(2) Select the path you plan to edit
- You now will see control points that you can use to change the shape (but that's not our purpose here)
- Zoom in, e.g.++ by hitting the
+
button on the keyboard or by using theView
menu. Try View->Zoom->Drawing or View->Zoom-Selection
- (3) Cut
- Hold down SHIFT key and select two (not linked) points that will define the cut
- Click
Break path at selected nodes
in the upper toolbar - Menu
Path->Break Apart
will break the path into two paths
Some extra tips:
- The breaking may fail, i.e. change the path itself. Undo if this happens.
- If an object is not path (e.g. a rectangle), you can convert it to a path object: (Menu: Path -> Object to Path). But there is no way back !
- Use the XML Editor to select an element if necessary (i.e. if you can't select the one you need)
Alternative:
- Redraw the object you plan to animate
- Remove the points from the path that include the part that you wanted to cut off
- Maybe combine the two strategies ....
Example showing cut Dragon tongue (don't try this with a live one)
Kill part of path
- Hit F2
- Select a control point and hit the DELETE key
- Kill other points, until the subpath / subshape you want to remove is gone ....
- Then use the curve controls (little circles that stick out from the control points) to smoothen if necessary.
Constructive solid geometry
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:
- Path Operations
- Tutorial advanced (Boolean operations section)
Tips:
- In order to achieve what you want you often will have to destroy objects. In other words, you may first have to create copies. Either move these away temporarily or just pile 2 objects on top of each other: CTRL-C, deselect, then CTRL-SHIFT-V
Example to create an eye from a dragon head outline
- Draw a yellow rectangle over the eye
- Move it backwards: Menu: Object -> Lower (or PageDown key) and position. You now should see a yellow eye
- Copy / Paste in place the dragon head. In the XML Editor, you now should see a new path
- Select both dragon head and a rectangle
- Menu: Path -> Difference or
CTRL-
- You know should have an eye.
Adding animation in Inkscape
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 !!
Dragon example
- http://tecfa.unige.ch/guides/svg/ex/html5/animation/dragon-head-silhouette-anim.svg
- http://tecfa.unige.ch/guides/svg/ex/html5/animation/dragon-head-silhouette-anim.html (HTML5 version that includes the SVG with an object element)
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:
- Rotations in the HTML file were made with CSS, i.e. we rotate the HTML object element.
- Instead of chaining two animations (nose_anime1 and nose_anime2), rather use the values attribute (tongue_anim1). Less code, more elegant ...
- The header of the SVG file (includes a viewBox and set width and height to 100% (good for inclusion in HTML5)
- the chaining of the nose and tongue animation as explained in the SVG-SMIL animation tutorial
- Doing transform animations can be very hairy with imported pictures, because drawings are often transformed in various ways and animating these has strange effects on the coordinate system. The same is true for motion animation. E.g. instead of redrawing a tongue, we just cut it off an existing path. Scaling will scale the whole coordinate system used to define the tongue, not just the tongue itself ...
Dealing with path objects
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:
- From your animated SVG file, copy / paste the path you plan to animate to a new SVG file
- Adjust the drawing Canvevas: Menu: File->Document Properties->Custom Size; Select Resize page to drawing or selection
- Save the new file as optimized SVG
- Insert an svg element into the animation file
- Copy/paste the code from the new SVG file between the
svg
element - Adjust the the x and y position of the <svg>element
- Remove the old path if not already done so.
The following example includes a modified eye that is animated, i.e. we substituted the original left eye by a new version.
- http://tecfa.unige.ch/guides/svg/ex/html5/animation/paulliu_girl_with_silver_hair.svg (Copy of the original (from openclipart.org)
- http://tecfa.unige.ch/guides/svg/ex/html5/animation/paulliu_girl_with_silver_hair-mod2.svg (Eye animation version, after surgery)
- http://tecfa.unige.ch/guides/svg/ex/html5/animation/girl_eye_left.svg (just the eye that we extracted, optimized and copied pack)
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"/>
Moving an object along a path
Introduction
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
Procedure
- Create an object by using the ellipse tool and name it "ellipseObj" (Edit-->xml editor-->id"ellipseObj"-->set) -- this is the moving object
- Create an ellipse and call it "ellipsePath" (Edit-->xml editor-->id"ellipsePath"-->set) -- this is the path
- If you want an anti-clock movement (select the object-->object-->Flip Vertical)
- Save the file as plain svg
- Open the file with an xml editor
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>
- In order to avoid the errors it would be nice to clean up the code and add a few extra lines.
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" />
- If you want you can erase the ellipsePath in order to display only the ellipseObj
Links
Official
- Tutorials
- Tutorial advanced shows tips and tricks to edit and to simplify drawings
Tutorials
- Inkscape: Guide to a Vector Drawing Program by Tavmjong Bah. This is a free online version of the Inkscape: Guide to a Vector Drawing Program, 4th Edition Print Book or Ebook
- Different versions are available at: http://tavmjong.free.fr/INKSCAPE/
- For example, have a look at Chapter 23. SVG and the Web