NodeJS SVG to Animated Gif
Needed an to take an SVG and individually grab frames of the same SVG and place them into an animated gif. This lib simplifies it to await gif.addFrame(svgString, delay)
.
The SvgGif
util below simplified the use of gif-encoder
, convert-svg-to-png
, and png-js
.
const fs = require('fs');
const GifEncoder = require('gif-encoder');
const { convert } = require('convert-svg-to-png');
const Png = require('png-js');
function decode(data) {
return new Promise((resolve) => {
new Png(data).decode((pixels) => {
resolve(pixels);
});
});
}
class SvgGif {
constructor({ width, height, fileName = 'img.gif', repeat = 0 }) {
// Create GIF
this.gif = new GifEncoder(width, height);
this.gif.setRepeat(0);
this.gif.on('error', (err) => console.log(err));
// Collect output
const file = fs.createWriteStream('img.gif');
this.gif.pipe(file);
this.gif.writeHeader();
}
async addFrame(svg, delay = 1000) {
this.gif.setDelay(delay);
const data = await convert(svg);
const pixels = await decode(data);
this.gif.addFrame(pixels);
}
finish() {
this.gif.finish();
}
}
module.exports = SvgGif;
Example usage:
const SvgGif = require('./SvgGif');
const width = 1280;
const height = 720;
var svg = `
... place full svg file contents here ...
`;
(async () => {
const gif = new SvgGif({
width,
height,
fileName: 'img.gif'
});
console.log(`Generating...`);
// Render 1 frame for 1 second
await gif.addFrame(svg, 1000);
// Modify SVG here and render frame
await gif.addFrame(svg, 1000);
// Done
gif.finish();
console.log(`Done.`);
})();