I'm working on a project where I've been asked to support animated GIF on a fabric.js canvas.
As per https://github.com/kangax/fabric.js/issues/560, I've followed the advice to render on regular intervals, using fabric.util.requestAnimFrame. Video renders just fine with this method, but GIFs don't seem to update.
var canvas = new fabric.StaticCanvas(document.getElementById('stage'));
fabric.util.requestAnimFrame(function render() {
canvas.renderAll();
fabric.util.requestAnimFrame(render);
});
var myGif = document.createElement('img');
myGif.src = 'https://i.sstatic.net/e8nZC.gif';
if(myGif.height > 0){
addImgToCanvas(myGif);
} else {
myGif.onload = function(){
addImgToCanvas(myGif);
}
}
function addImgToCanvas(imgToAdd){
var obj = new fabric.Image(imgToAdd, {
left: 105,
top: 30,
crossOrigin: 'anonymous',
height: 100,
width:100
});
canvas.add(obj);
}
JSFiddle here: http://jsfiddle.net/phoenixrizin/o359o11f/
Any advice will be greatly appreciated! I've been searching everywhere, but haven't found a working solution.
According to specs about the Canvas 2DRenderingContext drawImage
method,
Specifically, when a CanvasImageSource object represents an animated image in an HTMLImageElement, the user agent must use the default image of the animation (the one that the format defines is to be used when animation is not supported or is disabled), or, if there is no such image, the first frame of the animation, when rendering the image for CanvasRenderingContext2D APIs.
This means that only the first frame of our animated canvas will be drawn on the canvas.
This is because we don't have any control on animations inside an img tag.
And fabricjs is based on canvas API and thus regulated by the same rules.
The solution is then to parse all the still-images from your animated gif and to export it as a sprite-sheet. You can then easily animate it in fabricjs thanks to the sprite class.