LoginSignup
0
0

More than 1 year has passed since last update.

APNG/GIF画像を複数表示する方法(連続表示/最初からアニメーション)

Posted at

はじめに

APNGもしくはGIF画像を画面内に複数表示する必要があり、いくつか問題にぶつかりました。
私が直面した問題と解決策を残します。

この記事の対象者

  • 連続で同じAPNG/GIF画像を連続表示したい人
  • 一度使用したAPNG/GIF画像を最初からアニメーションさせたい

同じAPNG/GIF画像を連続表示させる

Vueで作成していきます。最小限のtemplateを共通で利用して、scriptの部分に手を加えていきます。

共通template部分

<template>
    <button @click="createImg">
        画像追加
    </button>
    <div class="gif-list" ref="list"></div>
</template>

扱うGIFアニメーション画像

以下のカウントダウンアニメーションGIF画像を利用します。再生時間は10秒で、繰り返し再生はしません。

1. 何も手を加えずGIF画像を連続表示する

まずはシンプルにref属性listが指定されているdivタグの下にcreateElementで生成したimgタグを追加していく処理を試してみます。

createImg() {
    const newElement = document.createElement("img");
    newElement.src = "画像パス";
    this.$refs.list.prepend(newElement);
}

以下のようになりました。
Videotogif.gif

同じGIF画像を追加していくと、最初に表示したGIFアニメーションと同じアニメーションが実行されてしまいます。後から追加したGIF画像を各々最初からアニメーションさせるにはどうすれば良いでしょうか。

2. 連続表示したGIF画像を各々最初からアニメーションさせる

URLパラメータを付与して別のファイル名で呼び出すことで、追加したGIF画像がそれぞれ独立して最初からアニメーションするようになります。

createImg() {
    this.count++;
    const newElement = document.createElement("img");
    newElement.src = "画像パス" + `&${this.count}`; // URLパラメータを適当に追加する
    this.$refs.list.append(newElement);
}

以下のようになりました。
Videotogif (1).gif

追加したGIF画像が最初からアニメーションするようになりましたね。

連続表示の際に通信量を削減する

これで連続表示で最初からアニメーションさせる件は解決しましたが、パフォーマンス面の問題があります。以下が連続表示した際の通信状況です。

スクリーンショット 2022-12-03 11.04.31.png

毎回通信発生してるじゃん…

サイズは少量ですが、高速で連打を長時間されたらサイトに負荷がかかってしまいます。なのでこちらも対策を取ります。

繰り返しで同じファイル名を利用する

createImg() {
    this.count++;
    const newElement = document.createElement("img");
    newElement.src = "画像パス" + `&${this.count}`;
    newElement.id = `gif-${this.count}`
    this.$refs.list.prepend(newElement);
  
    // 5個表示したらカウントを0にする
    if (this.count === 5) {
        this.count = 0;
    }
}

画像を5個表示したらカウントを0に戻し、同じファイル名のGIFアニメーションを表示するようにしました。

以下のようになりました。
スクリーンショット 2022-12-03 11.56.04.png

これで画像取得の最大回数は5回になり、大量の通信発生の心配はありませんね!
しかし実際に表示される内容は以下のようになりました。

Videotogif (3).gif
一度表示したファイル名と同じURLパラメータだと最初からアニメーションしない…

それでは最初からGIFアニメーションを最初から再生させたい場合は、通信を大量に発生させるしかないのでしょうか。

アニメーションを最初から再生させる

最終的に以下のようになりました。

createImg() {
    this.count++;
    // 再度表示する場合は一度srcを空にする
    const removeElement = document.querySelector(`#gif-${this.count}`);
    if (removeElement) {
        removeElement.src = "";
        removeElement.remove();
    }

    const newElement = document.createElement("img");
    newElement.src = "画像パス" + `&${this.count}`;
    newElement.id = `gif-${this.count}`
    this.$refs.list.prepend(newElement);
  
    // 5個表示したらカウントを0にする
    if (this.count === 5) {
        this.count = 0;
    }
}

以下結果です。

Videotogif (4).gif

追加したGIF画像が最初から再生されているのがわかりますでしょうか?通信も5回しか発生していません。

追加したのは以下の部分になります。

// 再度表示する場合は一度srcを空にする
const removeElement = document.querySelector(`#gif-${this.count}`);
if (removeElement) {
    removeElement.src = "";
    removeElement.remove();
}

画像を最初から再生するために重要なのは既に表示中のGIF画像のsrcを空にしている部分です。画面上に表示されているGIF画像のimg要素のsrcを空にすることで、後から同じGIF画像を挿入したら最初からアニメーションされることがわかりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0