Programmgesteuertes Beenden der GIF-Animation

73

Ich entwickle eine Twitter-Anwendung, die direkt von Twitter auf die Bilder verweist. Wie kann ich verhindern, dass animierte Gifs abgespielt werden?

Die Verwendung window.stop()am Ende der Seite funktioniert in Firefox bei mir nicht.

Gibt es einen besseren JavaScript-Hack? Dies sollte vorzugsweise für alle Browser funktionieren

Karussell
quelle
Wenn Sie über eine serverseitige Sprache verfügen, sollten Sie den ersten Frame besser mit serverseitigem Code aufnehmen, auf Ihrem Server speichern und stattdessen anzeigen.
Schatten-Assistent ist Ear For You
Das Problem ist, dass 15 bis 60 Bilder von Twitter geändert werden müssen. Siehe jetwick.com (Open Source).
Karussell
Ja, aber Sie ändern es nur einmal, damit es kein Problem ist.
Schatten-Assistent ist Ohr für Sie

Antworten:

63

Inspiriert von der Antwort von @Karussell schrieb ich Gifffer. Überprüfen Sie es hier https://github.com/krasimir/gifffer

Es fügt automatisch eine Stop / Play-Steuerung über Ihrem Gif hinzu.

Krasimir
quelle
4
Ich wünschte, ich könnte +5 dies.
Ned Twigg
1
Ich wünschte, ich könnte +5 den vorherigen Kommentar hier ... :) Dies ist ein großartiger kleiner (aber sehr kluger) Code für den Umgang mit solchen animierten GIFs. Vielen Dank
TheCuBeMan
Mir ist klar, dass dies 3 1/2 Jahre alt ist. Es ist mir egal, das heißt nicht, dass dies immer noch nicht herausragend ist. Heute in eine Seite eingesteckt, funktioniert wunderbar.
Ron
Wenn ich darf, warum das extra g?
Marvin
@ Marvin Ich denke du fragst warum das extra "f". Ich nehme an, "gifer" wurde bereits genommen.
Krasimir
53

Dies ist keine browserübergreifende Lösung, aber dies funktionierte in Firefox und Oper (nicht in IE8: - /). Von hier genommen

[].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);
    }
}
Karussell
quelle
3
Soweit ich sehen kann, wird HTML5 verwendet. Es sollte in jedem Browser funktionieren, der HTML5 unterstützt. Demnach: deepbluesky.com/blog/-/browser-support-for-css3-and-html5_72 IE unterstützt dies immer noch nicht.
Schatten-Assistent ist Ohr für Sie
4
Ich denke, dies würde nur bei lokalen animierten
Gifs
3
Bibliothek basierend auf dieser Antwort
200_success
Mit dem Skript stimmt etwas nicht, oder? Wenn .drawImagedies nicht mit einem Fehler fehlschlägt, liegt kein CORS-Problem vor und der catchZweig wird nicht ausgeführt. Wenn jedoch ein CORS-Problem vorliegt, wird das Skript beendet und das Ganze try/catchwird nicht erreicht. Habe ich recht?
Tomáš Zato - Wiedereinsetzung Monica
Wenn ich mich richtig erinnere, haben GIF-Elemente in IE8 eine stopFunktion, die Sie aufrufen können, um die Animation zu stoppen.
Beschützer ein
11

In einem Versuch, Karussells Antwort zu verbessern, sollte diese Version browserübergreifend sein, alle Bilder einfrieren, einschließlich solcher, deren Dateiende falsch ist (z. B. Seiten zum automatischen Laden von Bildern), und nicht mit der Funktion des Originalbilds in Konflikt stehen Original, um mit der rechten Maustaste geklickt zu werden, als würde es sich bewegen.

Ich würde dafür sorgen, dass Animationen erkannt werden, aber das ist viel intensiver, als sie trotzdem einzufrieren.

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
quelle
4

Dies ist ein kleiner Hack, aber Sie können versuchen, das GIF in einen Iframe zu laden und window.stop()aus dem Iframe (auf sich selbst) heraus aufzurufen, sobald das Bild geladen wurde. Dies verhindert, dass der Rest der Seite angehalten wird.

Jason
quelle
1
Verlangsamt dies das Rendern von Seiten?
Karussell
Ich glaube nicht, nein. Versuch es!
Jason
Würde es Ihnen etwas ausmachen, mir ein Codebeispiel zu geben? Ich konnte es nicht mit Ihrer Methode zum Laufen bringen + siehe das Update
Karussell
Wenn Sie window.stop () aus dem iframe heraus aufrufen, wird auch die Ausführung des ursprünglichen Fensters gestoppt, oder wie würden Sie dies genau tun?
Karussell