CSSアニメーション終了後に再度アニメーションを再生する - CSS

CSSアニメーション終了後に再度アニメーションを再生するコードを紹介します。

単純な実装:うまく動作しない例

コード

下記HTMLファイルを記述します。char.svg はSVG形式の画像ファイルです。
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
  <link rel="stylesheet" href="Replay01.css" />
  <script type="text/javascript">
    function startAnimation() {
      var elem = document.getElementById('img01');
      elem.classList.add("charmove");
    }
  </script>
</head>
<body>
  <div>
    <a href="javascript:startAnimation();">start</a>
  </div>
  <img id="img01" class="charimg" src="char.svg" />
 </body>
</html>
Replay01.css
.charimg {
  width:120px;
}

  .charimg.charmove {
    animation: moveframe 2s linear;
  }

@keyframes moveframe {
  0% {
    transform: translateX(0px);
  }

  100% {
    transform: translateX(320px);
  }

解説

[start]リンクをクリックすると、startAnimation() 関数を呼び出し、id="img01"の要素にcharmobeサブクラスを追加し、アニメーションを開始します。

実行結果

上記のHTMLファイルをWebブラウザで表示します。下図のページが表示されます。


[start]リンクをクリックするとアニメーションが開始され、画像が右に動き始めます。



アニメーションが終了すると、最初の状態に戻ります。この状態で再度[start]リンクをクリックします。リンクをクリックしてもアニメーションは再生されません。


クラスを削除して再度追加する実装:うまく動作しない例

上記のHTMLではリプレイが動作しなかったため、追加したサブクラスを削除して、再度追加する方法で動作するか確認します。

コード

下記のHTMLファイルを作成します。
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
  <link rel="stylesheet" href="Replay02.css" />
  <script type="text/javascript">
    function startAnimation() {
      var elem = document.getElementById('img01');
      elem.classList.add("charmove");
    }

    function restartAnimation() {
      var elem = document.getElementById('img01');
      elem.classList.remove("charmove");
      elem.classList.add("charmove");
    }
  </script>
</head>
<body>
  <div>
    <a href="javascript:startAnimation();">start</a><br />
    <a href="javascript:restartAnimation();">restart</a><br />
  </div>
  <img id="img01" class="charimg" src="char.svg" />
 </body>
</html>
Replay02.css
.charimg {
  width:120px;
}

  .charimg.charmove {
    animation: moveframe 2s linear;
  }

@keyframes moveframe {
  0% {
    transform: translateX(0px);
  }

  100% {
    transform: translateX(320px);
  }
}

解説

restartAnimation 関数でid="img01"の要素から、charmoveクラスを削除し、その後再度charmoveクラスを追加します。
    function restartAnimation() {
      var elem = document.getElementById('img01');
      elem.classList.remove("charmove");
      elem.classList.add("charmove");
    }

実行結果

上記のHTMLファイルをWebブラウザで表示します。下図のページが表示されます。
[start]リンクをクリックすると、アニメーションが開始します。アニメーション終了後に[restart]リンクをクリックしても、アニメーションは再度再生されません。

補足
上記のコードでは動作しませんが、restartAnimation関数のクラスのremoveとaddの間にalertメソッドが挿入されるとrestartAnimationメソッドの呼び出しでアニメーションが リプレイ再生されて動作します。

    function restartAnimation() {
      var elem = document.getElementById('img01');
      elem.classList.remove("charmove");
      a;ert("アラートダイアログです");
      elem.classList.add("charmove");
    }

対処方法

クラスを削除してすぐに追加した場合にはうまく動作しないため、アニメーションが終了した時点でサブクラスを削除し、再度リンクがクリックされたタイミングでサブクラスを追加する動作にします。
アニメーションの再生の終了はanimationendイベントを実装すると検出できます。

プログラム例

コード

下記のHTML、CSSファイルを作成します。
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
  <link rel="stylesheet" href="Replay03.css" />
  <script type="text/javascript">
    window.addEventListener('load', () => {
      var elem = document.getElementById('img01');
      elem.addEventListener('animationend', () => {
        elem.classList.remove('charmove');
      });
    });

    function startAnimation() {
      var elem = document.getElementById('img01');
      elem.classList.add('charmove');
    }
  </script>
</head>
<body>
  <div>
    <a href="javascript:startAnimation();">start</a><br />
  </div>
  <img id="img01" class="charimg" src="char.svg" />
 </body>
</html>
Replay02.css
.charimg {
  width:120px;
}

  .charimg.charmove {
    animation: moveframe 2s linear;
  }

@keyframes moveframe {
  0% {
    transform: translateX(0px);
  }

  100% {
    transform: translateX(320px);
  }
}

解説

ページの読み込み時に、id="img01" の要素の 'animationend' イベントを実装しています。
ページ読み込み時のイベント実装の詳細はこちらの記事を参照してください。

animationendイベントではclassListから、charmove サブクラスを削除する処理を実行しています。
  elem.addEventListener('animationend', () => {
    elem.classList.remove('charmove');
  });

他のコードは先のデモと同じです。

実行結果

上記のHTMLファイルをWebブラウザで表示します。下図のページが表示されます。


[start]リンクをクリックすると、アニメーションが再生され画像が右にアニメーションして移動します。


アニメーションが終了すると最初の状態に戻ります。この状態で再度[start]リンクをクリックします。


リンクをクリックすると、再度アニメーションが再生されます。


CSSアニメーション終了後に再度アニメーションを再生する処理が実装できました。
著者
iPentecのメインデザイナー
Webページ、Webクリエイティブのデザインを担当。PhotoshopやIllustratorの作業もする。
掲載日: 2022-04-30
iPentec all rights reserverd.