84

I am developing a Twitter application which references to the images directly from Twitter. How can I prevent animated gifs from being played?

Using window.stop() at the end of the page does not work for me in Firefox.

Is there a better JavaScript hack? Preferable this should work for all browsers

Jeremy
  • 1
  • 85
  • 340
  • 366
Karussell
  • 17,085
  • 16
  • 97
  • 197

4 Answers4

75

Inspired by the answer of @Karussell I wrote Gifffer. Check it out here https://github.com/krasimir/gifffer

It automatically adds stop/play control on top of your Gif.

Krasimir
  • 13,306
  • 3
  • 40
  • 55
63

This is not a cross browser solution but this worked in firefox and opera (not in ie8 :-/). Taken from here

[].slice.apply(document.images).filter(is_gif_image).map(freeze_gif);

function is_gif_image(i) {
    return /^(?!data:).*\.gif/i.test(i.src);
}

function freeze_gif(i) {
    var c = document.createElement('canvas');
    var w = c.width = i.width;
    var h = c.height = i.height;
    c.getContext('2d').drawImage(i, 0, 0, w, h);
    try {
        i.src = c.toDataURL("image/gif"); // if possible, retain all css aspects
    } catch(e) { // cross-domain -- mimic original with all its tag attributes
        for (var j = 0, a; a = i.attributes[j]; j++)
            c.setAttribute(a.name, a.value);
        i.parentNode.replaceChild(c, i);
    }
}
sodimel
  • 864
  • 2
  • 11
  • 24
Karussell
  • 17,085
  • 16
  • 97
  • 197
  • 3
    It's using HTML5 so as far as I can see, it should work on any browser supporting HTML5. According to this: http://www.deepbluesky.com/blog/-/browser-support-for-css3-and-html5_72/ IE still does not support it. – Shadow The GPT Wizard Nov 25 '10 at 11:59
  • 4
    I *think* this would only work on local animated gifs as opposed to those hosted on a different domain – donohoe Aug 19 '11 at 20:45
  • 3
    [Library](http://krasimirtsonev.com/blog/article/stop-autoplaying-your-gifs-stop-play-control) based on this answer – 200_success Jun 20 '14 at 06:08
  • There is something wrong with the script, isn't it? If `.drawImage` doesn't fail with an error, there is no CORS problem and `catch` branch won't execute. If, however there is a CORS issue, the script ends and whole `try/catch` is not reached. Am I right? – Tomáš Zato Jul 07 '14 at 21:49
  • If I remember correctly, in IE8 gif elements have a `stop` function you can call to stop the animation. – Protector one Feb 19 '16 at 09:40
  • On one hand, this is a solution from 2010. On the other hand, this worked for me nicely on Chrome (Windows 7). The fact that I mention also the OS is that suprisingly, it didn't work on Chrome based on Linux, for some reason. On my Chrome it changes the "src" of all the GIF files to binary (src="data:..."). On the Linux Chrome it changed everything to "canvas" and the images weren't displayed correctly on the page. Does anyone know why is that? – TheCuBeMan Apr 14 '16 at 09:06
12

In an attempt to improve on Karussell's answer, this version should be cross-browser, freezes all images including those that have an incorrect file ending (e.g. automated image loading pages), and does not conflict with the function of the original image, allowing the original to be right clicked as if it were moving.

I would make it detect animation but that is much more intensive than just freezing them regardless.

function createElement(type, callback) {
    var element = document.createElement(type);

    callback(element);

    return element;
}

function freezeGif(img) {
    var width = img.width,
    height = img.height,
    canvas = createElement('canvas', function(clone) {
        clone.width = width;
        clone.height = height;
    }),
    attr,
    i = 0;

    var freeze = function() {
        canvas.getContext('2d').drawImage(img, 0, 0, width, height);

        for (i = 0; i < img.attributes.length; i++) {
            attr = img.attributes[i];

            if (attr.name !== '"') { // test for invalid attributes
                canvas.setAttribute(attr.name, attr.value);
            }
        }

        canvas.style.position = 'absolute';

        img.parentNode.insertBefore(canvas, img);
        img.style.opacity = 0;
    };

    if (img.complete) {
        freeze();
    } else {
        img.addEventListener('load', freeze, true);
    }
}

function freezeAllGifs() {
    return new Array().slice.apply(document.images).map(freezeGif);
}

freezeAllGifs();
Makaze
  • 1,076
  • 7
  • 13
5

This is a bit of a hack, but you could try loading the gif into an iframe and calling window.stop() from inside the iframe (on itself) once the image has loaded. This prevents the rest of the page from stopping.

Jason
  • 51,583
  • 38
  • 133
  • 185