Stopping GIF Animation Programmatically

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


Solution 1:

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.

Solution 2:

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

Solution 3:

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

Solution 4:

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.