10_5 Animationオブジェクトのイベント

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移動する、という意味です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA