Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to show animated gif image? #560

Closed
zhangzhzh opened this issue Apr 14, 2013 · 25 comments
Closed

How to show animated gif image? #560

zhangzhzh opened this issue Apr 14, 2013 · 25 comments
Labels
stale Issue marked as stale by the stale bot

Comments

@zhangzhzh
Copy link

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

@kangax
Copy link
Member

kangax commented Apr 16, 2013

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

@kangax kangax closed this as completed Apr 16, 2013
@rnw159
Copy link

rnw159 commented Sep 6, 2013

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.

@TomFromThePool
Copy link

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.

@asturur asturur reopened this Jun 22, 2016
@ncou
Copy link
Collaborator

ncou commented Feb 10, 2017

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

@monalisasaha79
Copy link

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.

<img src="https://img.clipartfest.com/4ed31b38da845a45da975eaa495310ac_-bubblesgif-animated-bubbles-clipart_290-200.gif" #effect>

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);
};

@ncou
Copy link
Collaborator

ncou commented Jul 9, 2017

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.

@mcdoolz
Copy link

mcdoolz commented Sep 13, 2018

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

@asturur
Copy link
Member

asturur commented Sep 14, 2018

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

@mcdoolz
Copy link

mcdoolz commented Sep 14, 2018

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

@kabrice
Copy link

kabrice commented Oct 11, 2018

Still no solutions 😢 ?

@awehring
Copy link

awehring commented Oct 12, 2018

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.

@asturur
Copy link
Member

asturur commented Oct 15, 2018

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

@awehring
Copy link

awehring commented Oct 15, 2018

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.

@asturur
Copy link
Member

asturur commented Oct 15, 2018

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

@asturur
Copy link
Member

asturur commented Oct 15, 2018

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.

@awehring
Copy link

Ok, thanks for the hint.

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

@awehring
Copy link

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

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

@asturur
Copy link
Member

asturur commented Oct 15, 2018 via email

@nartc
Copy link

nartc commented Aug 14, 2019

Any update on this issue?

@awehring
Copy link

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/

@stale
Copy link

stale bot commented Jan 25, 2020

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.

@stale stale bot added the stale Issue marked as stale by the stale bot label Jan 25, 2020
@stale stale bot closed this as completed Feb 1, 2020
@local-dev-31
Copy link

local-dev-31 commented Sep 3, 2020

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.

@omar-shahid
Copy link

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

@rafipatel93
Copy link

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.

With cdn It is not working I want without node js

@awehring
Copy link

I was thinking about a solution with animated SVG. And - to my surprise - it works quite well.

You can embed the animated GIF in a SVG and add it as a fabric.js image to the canvas. A little effort might be necessary to set properties. Could be a good solution for many use cases.

Besides animated GIFs, some other SVG features can be used (animated graphics, 3D lighting, etc.).

The whole idea is explained in the discussion area here: #8424

A working jsfiddle example is there too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale Issue marked as stale by the stale bot
Projects
None yet
Development

No branches or pull requests