CSSアニメーションをリスタートする方法
CSSアニメーションをリスタートさせる方法は、アニメーション用のCSSを一旦削除し、再度追加する必要がある。
リスタート的なメソッドは無い。
目次
結論
CSS変更時のスタイル再計算を考慮する為、requestAnimationFrame()を2段で呼び出して、2段目でアニメーション用のCSSを追加する。
結果、アニメーションのリスタートが発生する。
アニメーションCSSのサンプル
html
<div id="ani-div" class="animation">●</div>
css
.animation {
animation-name: animation;
animation-duration: 2s;
animation-iteration-count: 5;
animation-timing-function: linear;
animation-direction: alternate;
animation-fill-mode: forwards;
}
@keyframes animation {
0% {
color: yellow;
transform: translateX(0);
}
100% {
color: chartreuse;
transform: translateX(280px);
}
}
リスタートのデモ
( ● : animationクラスが外れた状態 )
toggle-auto CSSを削除してすぐにCSSを追加する
toggle-sw 手動のトグルSW。CSSの削除や追加をする。
requestAnimationFrame1 CSSを削除し、requestAnimationFrame()メソッドを使用してCSSを追加する。
requestAnimationFrame2 CSSを削除し、requestAnimationFrame()メソッドを2段使用してCSSを追加する。
toggle-auto
アニメーションCSS(.animation)を削除して、すぐにCSSを追加(戻し)している。wait的なものはなし。
結果: NG。アニメーションはリスタートしなかった。
理由: CSS削除後のスタイル再計算前にCSSが戻っているので次の再描画に影響していない。
let toggle_auto_f = () => {
const aniDiv = document.getElementById("ani-div");
aniDiv.classList.remove('animation');
aniDiv.classList.add('animation');
}
toggle-sw
手動のtoggleスイッチ
結果: OK。手動であればアニメーションのリスタート可能
CSSを削除するとアニメーションは停止する。CSSを追加するとアニメーションが最初から開始される。
アニメーションが削除される。停止とは違う。
let toggle_sw_f = (e) => {
const aniDiv = document.getElementById("ani-div");
aniDiv.classList.toggle("animation");
};
requestAnimationFrame(callback)
requestAnimationFrame()はcallbackされる関数を1つ引数に指定できる。
requestAnimationFrame()は、次の再描画の前に、アニメーションの更新要求とcallback関数を実行する。
このテストは、Firefox、Chrome で、実行結果が異なった。(2023年9月)
- Chrome v117: リスタート可能
- Firefox v118: リスタート不可
- Edge v117: リスタート可能
let reqfm1_f = () => {
const aniDiv = document.getElementById("ani-div");
aniDiv.classList.remove('animation');
window.requestAnimationFrame((time1) => {
aniDiv.classList.add('animation');
});
};
requestAnimationFrame(callback)*2
スタイル変更時の再計算を考慮して、requestAnimationFrame()の呼び出し中にrequestAnimationFrame()をもう一度呼び出す。この2回目でCSSを追加する
結果: OK
callback関数は、次の再描画の直前に実行される。
この間、再描画されていないはずなので、スタイルは再計算はされていない。
2回目の呼び出しは、スタイルの計算、再描画が実行された次の描画なので、意図したリスタートが実行される。
CSSの削除が画面に反映されアニメーションがリセットされ、CSSが戻されアニメーションがスタートする。
let reqfm2_f = () => {
const aniDiv = document.getElementById("ani-div");
aniDiv.classList.remove('animation');
window.requestAnimationFrame((time1) => {
window.requestAnimationFrame((time2) => {
aniDiv.classList.add('animation');
});
});
}
以上。
参考資料
Window.requestAnimationFrame()