Animationオブジェクトでは、finishイベントとcancelイベントが定義されており、AnimationオブジェクトのaddEventListener()メソッドで、発生を待ち受けることができます。名前から容易に想像できるように、finishイベントは、アニメーションの再生が完了したときに発生し、cancelイベントは、アニメーションの再生がキャンセルされたときに発生します。
イベントの発生時addEventListener()メソッドには、引数として、AnimationPlaybackEventオブジェクトが渡されます。このオブジェクトは次のプロパティを持っています。
currentTime
イベントが発生したアニメーションの、その時点でのタイム値(再生スピードは加味しない)。
timelineTime
イベントが発生したアニメーションのタイムラインのタイム値
次の例では、Web Animations APIのイベントと、CSS Animationsのイベントを使って、アニメーション再生のリレーを行っています。リレーするときには同時に聖火のイメージも渡します。
コードは以下のものを使用しています。
HTML
<div class="square ball-a"><img src="images/seika.png" id="seika"></div>
<div class="square"></div>
<div class="square ball-b"></div>
<input type="button" id="play-btn" value="Play">
<textarea id="textarea" rows="5" cols="40"></textarea>
CSS
.square {
position: absolute;
width: 20px;
height: 20px;
border: solid 3px #000;
top:100px;
left:220px;
background-color:rgb(189, 240, 70);
}
.css-anim{
animation: go-left 1s forwards;
}
@keyframes go-left {
0%{
transform: translateX(0);
}
100%{
transform: translateX(450px);
}
}
.square.ball-a{
top:20px;
left:20px;
border-radius: 50%;
background-color:rgb(211, 12, 128);
}
.square.ball-b{
top:180px;
left:670px;
border-radius: 50%;
background-color:chocolate;
}
#play-btn{
position: absolute;
width: 100px;
height:30px;
top:300px;
left: 30px;
}
textarea{
position: absolute;
top:400px;
left: 30px;
}
JavaScript
// 情報を<textarea>に出力
const info = (msg)=>{
const textarea = document.getElementById('textarea');
textarea.value += msg + '\n';
}
const ballA = document.querySelector('.ball-a');
const ballB = document.querySelector('.ball-b');
const square = document.querySelectorAll('.square')[1];
const playBtn = document.getElementById('play-btn');
const seikaImg = document.getElementById('seika');
// seikaImagをリレー渡しする関数
const relay =(prev, next) =>{
prev.removeChild(seikaImg);
next.appendChild(seikaImg);
}
// ボールA、ボールB共通のタイミングパラメータ
const timings = { duration:2000, iterations:1, fill:'forwards'};
// ボールAとボールBのキーフレームパラメータ
const keyframes1 = {transform:['translateX(0)','translateX(200px)']};
const keyframes2 = {transform:['translateX(0)','translateX(-450px)']};
// ターゲットとキーフレームパラメータを受け取り、アニメーションを返す関数
const getNextAnim =(target, keyframes)=>{
const effect = new KeyframeEffect(target, keyframes, timings);
const anim = new Animation(effect, document.timeline);
return anim;
}
// ボールAとボールBのアニメーションを作成
// play()を実行しないので、スタートしない
const anim1 = getNextAnim(ballA, keyframes1);
const anim2 = getNextAnim(ballB, keyframes2);
// ボールAのアニメーションが終わったら、四角形のCSSアニメーションを開始
anim1.addEventListener('finish', ()=>{
square.classList.add('css-anim');
info('anim1のfinishイベント発生');
relay(ballA, square);
}, false);
// 四角形のアニメーションが終わったら、ボールBのアニメーションを開始
square.addEventListener('animationend', ()=>{
anim2.play();
info('CSS Animationsのanimationendイベント発生');
relay(square, ballB);
}, false);
// ボールBのアニメーションが終わったら、文字を出力
anim2.addEventListener('finish', ()=>{
info('anim2のfinishイベント発生');
relay(ballB, ballA);
playBtn.disabled = true;
}, false);
// [Play]ボタンのクリックで、ボールAのアニメーションを開始
playBtn.addEventListener('click', ()=>{
anim1.play();
}, false);
下図はサンプルの実行順を示した図です。①はスタート画面で、[Play]ボタンをクリックすると、Web Animations APIのanim1が再生をスタートします(図の②)。anim1では、finishイベントの発生を監視しています。anim1の再生が終了すると、CSS Animationsのsquareが再生を開始ます。squareでは、animationendイベントを監視します。これが発生すると、Web Animations APIのanim2が再生を開始する(図の③)、といった順番です。
Web Animations APIでは、Animationオブジェクトでイベント発生を監視します。CSS Animationsでは、HTML要素で監視します。
transform:[‘translateX(0)’,’translateX(200px)’]は、今の位置から正のX方向に200px移動する、という意味です。