Fabric.js: How to show animated gif image?

Created on 14 Apr 2013  Â·  23Comments  Â·  Source: fabricjs/fabric.js

With Raphael, I can do it just as

var paper = Raphael(domEl, 600, 600);
var img = paper.image('Images/girl.gif', 0, 0, 435, 600);

but in fabric, when do it as

fabric.Image.fromURL('Images/girl.gif', function (img) {
canvas.add(img);
});
the gif image is not animated, just as the discussion in http://stackoverflow.com/questions/7281646/why-does-drawing-an-animated-gif-on-canvas-only-update-after-reselecting-the-tab

in fabric, it seems related to fabric.util.requestAnimFrame.

What's the easiest way to solve it? Tks

stale

Most helpful comment

Here is my implementation, made it to deal with stickers, so it's very efficient with small Gifs, not so well with larger ones (memory limits).

https://codesandbox.io/s/red-flower-27i85 (Did my best to make the code as clear as possible, adding comments where needed)

Using two methods, the first gifToSprite.js with "gifuct-js" library import and convert the gif to a dataURL sprite sheet, the second fabricGif.js mainly a wrapper for the first method, return a fabric.Image instance of the gif, override the _render method to redraw the canvas after each delay, add three methods to play, pause, and stop.

As a bonus you can set a maxWidth, maxHeight to scale the gif and a maxDuration in millisecond to reduce the number of frames.

Hope this will help any one, Fabir.js is awesome thanks to @asturur and all the contributors for this great library.

All 23 comments

Perhaps try calling canvas.renderAll() continuously in some intervals. Feel free to ask questions on google group — groups.google.com/forum/#!forum/fabricjs

Ok, I have a solution that worked for me.

You need to add the gif as an element on the page so that the browser knows to update the image when it is on the canvas. Its a strange fix, but if you make the height 0 and dynamically add it with javascript then it shouldn't affect you that much.

        var tempImg = document.createElement('img');
        tempImg.setAttribute('src','Images/girl.gif');
        tempImg.setAttribute('height','0px');
        document.body.appendChild(tempImg);

Whenever I googled how to do this with fabricjs I always ran into this page, hopefully now it will help someone else save time.

Just to update, the solution given by @rnw159 no longer seems to work (Fabric 1.6.2). If anybody else has a solution to this I'd love to hear it, otherwise it looks like converting GIFs into sprite sheets and animating that way might be the only reliable way to achieve this.

@TomFromThePool : did you find a solution to use gif in the canvas ? Even if i suppose using a sprite is the only way.

Hi @kangax,

I tried the gif on canvas as suggested by you. It is as similar like video element. But unfortunately, img element is not refreshing with renderAll(). Below my code is given. Please help. This is supper urgent.

this.canvas.add(new fabric.Image(this.effect.nativeElement, {subtype: "fx",top:0, left:0, height: 300, width: 300}));

function render() {
if(_th.isPlaying){
c.fire ('seek:event');
c.renderAll();
requestId = window.requestAnimationFrame(render);
} else
window.cancelAnimationFrame(requestId);
};

I think it's a limitiation added to the chrome Browser. The renderAll() continuiosly added doesn't work with Chrome.
But it work with Safari on the IPAD.
Converting to sprite seems to be the only way.

Still nothing, eh? Looks like conversion is the way to go then..

Some browsers want the gif to be in dom to play it. Did you try of that fix?

I have. It does not work consistently across all browsers 😞

Still no solutions 😢 ?

It has nothing to do with fabric.js. It depends on the browser, if the Canvas-element refreshes animated GIFs.
Safari does it, most other not ( I checked Chrome, Firefox, Internet Explorer).

So you have to ask Mozilla, Google and Microsoft to enhance their browsers.

did you try appending the gif to the dom and see if something change?

No.
I use basically this snipped from Paul Canning to import images:
https://groups.google.com/forum/#!searchin/fabricjs/pages/fabricjs/ud-ks-hl3Gw/RYYQpRTv1AYJ

When I load an animated GIF with Safari, the animation is progressing with requestRenderAll().
With other browsers only the first picture is shown static (Chrome, Firefox, Internet Explorer).

Some answers at StackOverflow and other sources say, that only Safari refreshes animated GIFs in a Canvas element. They generally hint at sprites as a work-around or to overlay them in front of the Canvas with CSS tricks.

Blindman67 at StackOverflow gives an example to decode the animated GIF into single images and play them at the Canvas. It is memory hungry as each frame is converted to a full RGBA image, making the loaded GIF significantly larger than the GIF file size.
Here: https://stackoverflow.com/questions/48234696/how-to-put-a-gif-with-canvas

I haven't tried it myself, postponed this feature in my app (even thouh it would be cool).
Maybe converting the sequence of the images into a sprite is a possible way too.

try to append it to DOM, it could just play.

Appen the gif to an image element in the dom ( without hiding as a test ) then use that imageElement ( not the src ) to initialize a fabric.Image element.

Ok, thanks for the hint.

Currently I'm working on the upgrade to Release 2, but I will report back later.

Gave it a quick try, but of no avail (Firefox 62):

http://jsfiddle.net/awehring/ucat3jh6/1/

Yeah i see it does not work

Il giorno lun 15 ott 2018 alle ore 15:49 awehring notifications@github.com
ha scritto:

Gave it a quick try, but of no avail (Firefox 62):

http://jsfiddle.net/awehring/ucat3jh6/1/

—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
https://github.com/fabricjs/fabric.js/issues/560#issuecomment-429859580,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABI4QKTtu0_fkDKSdWAfz0P0s0xdnjEyks5ulJJcgaJpZM4Ak40_
.

Any update on this issue?

I don't expect one. It is a limitation of most browsers. (See my answer above, Oct. 15th, 2018)

As a workaround you can use animated sprites. Here is an example with fabric.js: http://fabricjs.com/animated-sprite

Here is an explanation of the technique: http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Here is my implementation, made it to deal with stickers, so it's very efficient with small Gifs, not so well with larger ones (memory limits).

https://codesandbox.io/s/red-flower-27i85 (Did my best to make the code as clear as possible, adding comments where needed)

Using two methods, the first gifToSprite.js with "gifuct-js" library import and convert the gif to a dataURL sprite sheet, the second fabricGif.js mainly a wrapper for the first method, return a fabric.Image instance of the gif, override the _render method to redraw the canvas after each delay, add three methods to play, pause, and stop.

As a bonus you can set a maxWidth, maxHeight to scale the gif and a maxDuration in millisecond to reduce the number of frames.

Hope this will help any one, Fabir.js is awesome thanks to @asturur and all the contributors for this great library.

Thank you so much @local-dev-31 for your solution, you saved me!!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

urcoder picture urcoder  Â·  5Comments

f987002856 picture f987002856  Â·  3Comments

semiadam picture semiadam  Â·  3Comments

keanass picture keanass  Â·  5Comments

eddieyangtx picture eddieyangtx  Â·  5Comments