Animierte GIFs per Shortcode einbinden

Animierte GIFs sind eine praktische Möglichkeit visuelle Vorgänge zu dokumentieren. Frank Staude hat dazu diese Woche einen Artikel bei unserem #projekt52. Das erinnerte mich an ein Kundenprojekt, wo ich ein sehr großes animiertes GIF einbinden musste, was leider nur sehr ruckelig möglich war …

Animierte GIFs bestehen aus mehreren Einzelbildern, die nach einer einstellbaren Verzögerung nacheinander angezeigt werden. Es gibt nur ein Problem bei sehr großen animierten GIFs, deren Ablauf möglichst flüssig aussehen soll: Der Browser lädt das Bild und versucht es direkt anzuzeigen.

Sollten also die ersten 10% der Animationsbilder geladen sein, dann läuft die Animation nur zu 10%, stockt dann und startet neu. Inzwischen sind vielleicht weitere 10% geladen, also läuft die Animation nun bis 20% – stockt und startet neu – solange bis das animierte GIF komplett geladen ist. Erst dann läuft die Animation flüssig durch.

Offensichtlich ist das keine gute Lösung.

Nach einer Suche im Netz bin ich auf eine smarte Lösung gekommen. Es wird ein Platzhalter-Bild eingebaut (das kann eine Lade-Animation sein oder zum Beispiel das erste Bild der Animation) und das Bild-Element für die Animation wird per Javascript angelegt. Ist die Animation geladen wird das Platzhalterbild mit dem animierten GIF ausgetauscht.

Zuerst definiere ich den Shortcode animatedgif mit den Attributen giflink für das aninimierte GIF (alternativ per Bild-ID über gifid) und placeholderlink (wiederum alternativ per ID über placeholderid).

    // Attributes
    $atts = shortcode_atts(
        array(
            'giflink' => '',
            'gifid' => '',
            'placeholderlink' => '',
            'placeholderid' => '',
        ),
        $atts,
        'animatedgif'
    );

Der nächste Block speichert dann das animierte GIF in einer Variablen, sofern ein Link angegeben ist. Falls nicht wird geprüft ob eine ID gesetzt ist. wp_get_attachment_image_src liefert ein Array zurück, von dem wir nur das erste Element benötigen, die URL. Als Bildgröße muss full gewählt werden, da durch das Umrechnen das animierte GIF kaputt gehen würde.

    if ( $atts['giflink'] ) {
        $imageurl = $atts['giflink'];
    }
    elseif ( $atts['gifid'] ) {
        $imageurl = wp_get_attachment_image_src( $atts['gifid'], 'full' );
        $placeholder = $placeholder[0];
    }

Im nächsten Block mache ich das gleiche nochmal für das Platzhalter-Bild mit dem Zusatz, dass wenn weder URL noch ID angegeben sind, ich noch einen Fallback auf eine Lade-Animation im (Child-)Theme gesetzt habe.

    if ( $atts['placeholderlink'] ) {
        $placeholder = $atts['placeholderlink'];
    }
    elseif ( $atts['placeholderid'] ) {
        $placeholder = wp_get_attachment_image_src( $atts['placeholderid'], 'full' );
        $placeholder = $placeholder[0];
    }
    else {
        $placeholder = get_stylesheet_directory_uri() . '/images/spinner.gif';
    }

Zuletzt wird die HTML-Ausgabe zusammengebaut und zurückgegeben. Hier passiert der eigentliche Trick. Als erstes wird das Platzhalter-Bild in einem normalen Image-Tag ausgegeben. Die vergebene ID ist hierbei wichtig! Als nächstes folgt ein kleines Javascript-Snippet. Darin wird ein neues Image-Element erstellt und mit der Bild-URL des animierten GIF befüllt. Erst wenn dieses Bild-Element (also das animierte GIF) geladen ist (onload) wird das Image-Tag mit der oben erwähnten ID mit dem nun vollständig geladenen animierten Bild befüllt.

    $html_output = '';

    $html_output .= '<img id="animatedgif" src="' . $placeholder . '">';

    $html_output .= '<script type="text/javascript">';
    $html_output .= '  var myanimatedgif = new Image();';
    $html_output .= '  myanimatedgif.src = "'. $imageurl .'";';
    $html_output .= '  myanimatedgif.onload = function() {';
    $html_output .= '    document.getElementById("animatedgif").src = myanimatedgif.src;';
    $html_output .= '};';
    $html_output .= '</script>';

    return $html_output;

Das Ergebnis ist ein Platzhalterbild oder eine Lade-Animation, die solange stehenbleibt bis das animierte GIF vollständig geladen ist. In diesem Moment wird das Bild getauscht und die Animation startet ruckelfrei und läuft sauber durch.

Hier nochmal der komplette Code am Stück:

/**
 * Anim GIF Shortcode ==============================================================================================
 * [animatedgif giflink="" gifid="" placeholderlink="" placeholderid=""]
 */
function studioseminar_gif_shortcode( $atts ) {

    // Attributes
    $atts = shortcode_atts(
        array(
            'giflink' => '',
            'gifid' => '',
            'placeholderlink' => '',
            'placeholderid' => '',
        ),
        $atts,
        'animatedgif'
    );

    if ( $atts['giflink'] ) {
        $imageurl = $atts['giflink'];
    }
    elseif ( $atts['gifid'] ) {
        $imageurl = wp_get_attachment_image_src( $atts['gifid'], 'full' );
        $placeholder = $placeholder[0];
    }

    if ( $atts['placeholderlink'] ) {
        $placeholder = $atts['placeholderlink'];
    }
    elseif ( $atts['placeholderid'] ) {
        $placeholder = wp_get_attachment_image_src( $atts['placeholderid'], 'full' );
        $placeholder = $placeholder[0];
    }
    else {
        $placeholder = get_stylesheet_directory_uri() . '/images/spinner.gif';
    }

    $html_output = '';

    $html_output .= '<img id="animatedgif" src="' . $placeholder . '">';

    $html_output .= '<script type="text/javascript">';
    $html_output .= '  var myanimatedgif = new Image();';
    $html_output .= '  myanimatedgif.src = "'. $imageurl .'";';
    $html_output .= '  myanimatedgif.onload = function() {';
    $html_output .= '    document.getElementById("animatedgif").src = myanimatedgif.src;';
    $html_output .= '};';
    $html_output .= '</script>';

    return $html_output;

}
add_shortcode( 'animatedgif', 'studioseminar_gif_shortcode' );

Das Ganze kommt in die functions.php eines (Child-)Themes oder in ein Functionality-Plugin.

Es geht einfacher, besser oder ich habe einen Fehler gemacht? Ab in die Kommentare damit. Du nutzt den Code und findest ihn praktisch? Dann freue ich mich über ein „Danke“ in den Kommentaren. Noch mehr freue ich mich allerdings, wenn du im Gegenzug ein Snippet aus deinem letzten Projekt teilst. So lernen wir alle weiter dazu!

2 Antworten auf Animierte GIFs per Shortcode einbinden

  1. Danke für den Beitrag! Was ich noch machen würde, ist id="animatedgif" gegen eine Klasse auszutauschen, z.B. mit einer Laufvariable wie im Gallery-Shortcode. Sonst kann man den Shortcode nicht problemlos mehrmals auf einer Seite verwenden, weil die ID mehrfach existiert.

    • Interessante Idee! In dem konkreten Projekt waren mehrere Animationen auf einer Seite (auch aufgrund der Ladezeiten) nicht notwendig/sinnvoll, aber du hast Recht, so könnte man den Shortcode noch allgemeiner benutzen. Danke für die Ergänzung 👍

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.