Convert animated SVG to movie

Have you tried using squiggle to export a series of frames? I found squiggle a pain to get your line just where I wanted it to be to properly set up a series of frames. However, once you have that, you can use imagemagick - apparently my favorite answer this week ;-) to transform it however you like.

Assuming each you save the frames off as frame01.svg, frame02.svg, etc. Then this:

convert -delay 5 -loop 0 frame??.svg animated.gif

will make a single animate gif from your frames that loops forever, 5 ms between frames.

convert will convert svg to , but imagemagick doesn't process the animateTransform tag, so any output is static.

Update: I found squiggle so painful to work with (at least trying to stop the animation at just the right spot to grab an image, I was embarrassed to have even suggested it!

Here's a bash script using imagemagick to convert your svg into an animated gif: Before running this script I split your example svg into 2 parts: bg.svg contains the elipse and the 'pit' element and hand.svg contains just the 'sec' element

`#!/bin/bash`

rm *.png
rm anim.gif

convert bg.svg -crop 200x200+0+0 +repage bg.png
convert hand.svg -crop 200x200+0+0 +repage -transparent white hand.png

for ((i=1; i<=359; i=i+3))
do
  convert hand.png -gravity center -rotate $i tmp.png
  n=`printf "%03d" $i`
  composite -gravity center tmp.png bg.png hand${n}.png
  rm tmp.png
done

convert -delay 1  -loop 0 hand*.png anim.gif

~
I'm sure someone more clever than me could figure out how to merge the convert and combine all in one step without also rotating the bg.png, but this is what you get for free ;-)

Also, wanted to keep this simple, just in case it needs to be reimplemented as a windows bat file.

The i=i+5 is a trade-off between how smooth the animation looks vs. file size.

Note: Even with -delay 1 (1 ms between frames), firefox would not move the hand in a complete circle in 5 seconds. It was closer to 10 secs.

And here's what the script produced


I found a way to create the series of images with the help of canvg. To run the following page, you have to use a modified script of canvg.js in that the draw function is accessable.

Changes in script canvg.js (v1.0):

In line 2321 change from:

var draw = function() {

to:

svg.draw = function() {

In line 2361 and 2390 change from:

draw();

to:

svg.draw();

My generation script:

<html>
<head>
<script type="text/javascript" src="rgbcolor.js"></script> 
<script type="text/javascript" src="canvg.js"></script> 
<script type="text/javascript">

loadSVG = function() {
  canvg('canvas', '<animated SVG>', { ignoreMouse: true, ignoreAnimation: true });
}

function RenderNext(delta) {
    var c = document.getElementById("canvas");
    var svg = c.svg;

    for (var i=0; i<svg.Animations.length; i++) {
        svg.Animations[i].update(delta);
    }
    svg.draw();
}

function CreateImage(imgStr) {
    var oImg=document.createElement("img");
    oImg.setAttribute('src', imgStr);
    return oImg;
}

function start() {
    var c = document.getElementById("canvas");
    var result = document.getElementById("resultDiv");
    var maxDur = 5; // seconds
    var framerate = 5; // imgages per second

    for (var i = 0; i < framerate * maxDur; i++) {
        RenderNext(1000 / framerate);

        var oImg = CreateImage(c.toDataURL('image/png'));
        result.appendChild(oImg);
    }
}

</script>
</head>
<body onload="loadSVG()">

<canvas id="canvas" width="30px" height="30px"></canvas> 

<p>
<input type="button" id="start" value="Start" onclick="start()" /> 
</p>

<div id="resultDiv">
</div>

</body>
</html>

If you're using FireFox you might give SVG Render Plug in a try: http://adasek.cz/svgrender/

Tags:

Animation

Svg