日別アーカイブ: 2022-11-12

アニメーション初期化

アニメーションの再使用

HTMLとCSSのanimationを用いるとかなり高度なアニメーションをすることができます。背景色を定期的に変えたり、画像を回転して多彩な表現が実現します。

当初、設定した動きが終了して再度、実行しようとするにはそう簡単ではありませんでした。そこで再使用の成功例を記録に残します。

再使用のつぼ

アニメーションは繰り返し表示されることが多く、そのため開始前に初期化が行われます。初期化は通常の使い方ならば開始前に一度、行われますが2度目以降の初期化はあいまいです。

正しく初期化されるには英文の言語解説書を詳読することになりますが、からくりをひとつ手に入れましたので成功例を以下にまとめました。

ある要素でanimationが定義され新しいクラス名に出会うとそのanimationが初期化されるようです。

よって、初回はおおむね大過なく正常動作になりますが、2回目以降も正しい動作にするにはアニメーション終了イベントを取り付けて、その中でクラスを削除することでanimationを再初期化可能にすることができます。

具体的には、開始する前にクラスを追加し、終了イベントでクラスを削除します。一方、Cssでは追加したクラスが定義された時に有効になるようにanimationを条件設定します。

処理を繰り返すにはそこで次のアニメーションを呼び出します。

例題においてはカウンタを用意して3回繰り返しています。

例題では、1.8秒でアニメーションが完了し、終了イベントでクラスを削除して2秒後に再起動されるようにプログラミングされています。

タイミングのあり様と処理の関連を下図にしましたので参考にしてください。

最後にソースコードを掲載しましたので参考になれば幸いです。丁寧なコメントはあなたのコード理解に役立つことでしょう。

CSSクラスの追加や削除する方法

要素にクラスを追加したり削除するにはclassListメソッドを使います。詳しくはHTML解説書をご覧ください。

RESULT
パンダ画像の回転が止まっているときはリロードボタンを押してください。

プログラミングコード

<!DOCTYPE html>							<!--- &copy;2022 TacM, Ver0.30 -->
<html>
<head>
<meta charset="utf-8" />
<style>
.charimg {								/* 基本の要素を定義 */
  width:280px;
  height:280px;
}
.charimg.charmove {						/* charimgとcharmove両方が指定されているタグにのみ有効になりanimation開始 */
  animation: moveframe 900ms linear 2;	/* 0.9秒/周 2回転, 1.8秒で終了 */
  width:280px; height:280px;
  transform-origin: 140px 140px;
}
@keyframes moveframe {					/* 回転keyframe */
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
</style>
</head>
<body onload="finishEventInstall();startAnimation();">
<Div style="position:relative; width:640px; height:480px; border:0px solid red;">
  <div style="position:absolute; top:50%; left:50%; margin-right:-50%; transform:translate(-50%, -50%); width:280px; height:280px; border:0px solid green;">
    <img id="img01" class="charimg" src="https://aidesign.lolipop.jp/wp-content/uploads/2022/11/panda.png" />
  </div>
</Div>
<script type="text/javascript">
const elem=document.getElementById('img01');
var ct=0;
function finishEventInstall(){					//アニメーション終了イベントを取り付ける
  console.log("window.addEventListener");
  elem.addEventListener('animationend', () => {	//終了イベント処理
    elem.classList.remove('charmove');			//クラスを削除することでanimationを再初期化可能にする
    if(++ct<3) setTimeout('startAnimation()', 2000);	//再起動を指令、条件が整っていればanimationが開始する
  });
}
function startAnimation() {						//animation処理
  console.log("startAnimation", ct);
  elem.classList.add('charmove');				//クラスを追加することでanimationを初期化する
}
</script>
</body>
</html>