How to make a gif? e.g. from an SVG

Anybody got any good ideas?

1 Like
  1. Turn the SVG markup into a data URL
  2. Assign URL to image src
  3. Draw image onto canvas
  4. Fetch image data and pass to library of your choice (e.g. gif.js)

Expect this to be slow, though. Example:

const img = new Image;
img.src = `data:image/svg+xml;utf8,${encodeURIComponent(svg.outerHTML)}`;
await img.decode();

If you don’t care about dropped frames, there’s also the MediaStream API:


observable-prerender might be an option here, if you’re alright with generating it from outside observable (and if you’re comfortable with the command line). This notebook has an example of making PNG screenshots of a cell for every frame of an animation, then using ffmpeg to convert those frames to MP4 (though you can do something very similar with SVGs and GIFs). There’s also a CLI that makes it slightly easier

1 Like

If you’re talking about an animated GIF, you could take a look at what I did in (cells “rasterize” and “makezip”).
Each frame is a separate SVG that I convert to PNG using the approach from Then I zip the frames using npm package jszip, in order to download them all at once. On my local machine I use convert (imagemagick) to create the animated gif:
convert -delay 2 -loop 0 frames/frame*.png out.gif

1 Like

Thanks for the ideas. Excellent technical approaches but I might try a different form of distribution.

How about this?

I used @mootari suggestion of gif.js. I tried to make this a “generic” notebook which can be used against any public svg timeseries. So you don’t have to “import” anything to use it.

I’ve been recently playing with some WASM libs, and here is one experiment using WASM-ImageMagick to generate a GIF.

I’ve used rasterize function from @sanderevers post and originally from Mike’s notebook.

It’s cool that this WASM lib works on mobile as well. Unfortunately I couldn’t find a way to invalidate, abort the calls to the WASM lib as noted here so you have to be careful I guess.