I recently learned more than I ever wanted to know about animated SVGs, browser support of SVGs, and Inkscape. I had some fairly simple animated illustrations I wanted to create, so I drew the pictures I needed in Inkscape. I then added a little code to animate the images. This was surprisingly easy. Safari, Chromium, and Opera worked as expected. I then spent way too much time making the results work in Firefox and Internet Explorer.

To save time and keep everything consistent across multiple illustrations, I use the <image xlink:href="otherimage.svg" ... /> tag. This allows me to keep the elements that are used multiple times in a separate file. This way I can change an icon once, and it will be updated in all the files. I usually export illustrations as a PDF to include in a LaTeX file, or as a PNG for a website, so I’ve never had problems with this. But <image> doesn’t work consistently across browsers: Firefox supports <image> for raster but not SVG images. The solution is to include a copy of each icon in each illustration and replicate them with the <use> tag.

The Inkscape folks are still discussing how to implement animations, so animating SVGs still requires coding by hand. This means I had to dive into the Inkscape generated files. I learned that Inkcape doesn’t produce clean code, even when exporting as a plain SVG instead of an Inkscape SVG. It makes unnecessarily large and complex images. For example, when resizing a rectangle, the way you resize it matters in the code generated. If you use the rectangle tool to resize it, the code is good. But if you use the regular select tool to resize or move a rectangle, Inkscape keeps the original rectangle and applies a transform for the size change and move. This made it so that the icons were based on the original size I drew them, instead of the shrunken size I eventually settled on. This is usually fine, but was something I needed to be aware of when using the <image> tag to include one SVG in another. I’d like to have a command to redo the sizes so that the transform isn’t needed for the final size, but can see why they wrote it as is. To make the Inkscape code fit better with my handwritten code, I used a script called Scour to clean the Inkscape files.

After animating the illustrations, I added playback controls. Instead of creating a constant distraction from unwanted animations, this makes the webpage more readable by only playing the animation when the user chooses. It also provides a clear version for printing. Adding a play button required a little JavaScript, fortunately there are good examples online, so I was able avoid spending too much time digging through the documentation. Unfortunately, Firefox doesn’t support SVG animations. The best way to get around this limitation is to tweak the design of the illustration so that it works both as a still and a moving image. I did this by setting the initial image to a version that was legible even when still. Fortunately, I had already created this view for the PNG version required in Internet Explorer. Once the still version is loaded, a JavaScript enables the play control for browsers that support animation. In a browser without animation support, the play button appears grayed out. When the play button is pressed, the initial image is hidden, and the animation plays. When the reset button is pressed, the animation stops, and the original image is again shown. Using these steps, I was able to make a clear presentation that degrades gracefully in older browsers.

I also needed to find the best way to insert the SVGs into the webpages. For some reason, the <img src="foo.svg"> tag doesn’t work in all browsers. To make things worse, Internet Explorer doesn’t recognize SVG files. After a little reading, I chose to use an <object> tag around a PNG version of the image:


<div>

<object data="image.svg" width="400" height="100" type="image/svg+xml">

<img src="image.png" width="400" height="100" alt="alt text" />

</object>

</div>

This works in WebKit browsers, Firefox, Opera, and even Internet Explorer.

For most illustrations, the need to include both a SVG and PNG version eliminates much of the benefit of publishing an SVG. For an animation like this, SVG is the best format to use. I wanted to be able to scale the images without creating many versions, unfortunately I ended up having to use both.


Recommended resources: