10_9_2 タイム系

Animation.timelineプロパティは、アニメーションのタイムラインを参照します。現状では、アニメーションの基準として使用できるタイムラインは、ドキュメントのタイムラインしかありません。

タイムラインは、”時間”ととらえるよりも、左から右に進む時間軸、または左右に伸びたビデオテープの上を進む再生ヘッドととらえた方が分かりやすいでしょう。何秒という時間の値が、位置として見なせるようになります。

Animation.startTime

アニメーションの再生が開始されるべきタイム値の取得と設定を行う。ミリ秒単位。初期値はnull。

delayプロパティとの違い:delayを設定してもアニメーションは自動的にスタートしませんが、startTimeを設定すると、play()を呼び出さなくても、アニメーションはその時間がくれば自動的にスタートします。

Animationオブジェクト(anim)のstartTimeに、document.timeline.currentTime + タイム値を設定すると、その時点からタイム値ミリ秒後に、アニメーションは自動的にスタートします。タイム値にマイナス値を設定すると、すでにそのアニメーションはスタートしたものとして、途中から開始されます。

Animation.currentTime

アニメーションの現在のタイム値の取得と設定を行う。playbackRateの影響は受けない。再生開始前はnull。

たとえば、startTimeをdocument.currentTime + 10に設定した場合、物事は次のように進行します。

  1. ページが開かれると、window.performaceのnavigationStart値をタイム値0として、document.timelineが作成され、document.timeline.currentTimeが発生する。これは、ドキュメントのタイムラインが動き出すことを意味する。
  2. startTimeはdocument.currentTime + 10なので、アニメーションはまだ再生されず、anim.currentTimeはnullの状態。
  3. 10ミリ秒たつと、document.timelineがanim.startTimeの位置に達するので、anim.currentTimeが発生し、アニメーションの再生が始まる。
  4. document.timeline.currentTimeは右に進む。anim.currentTimeはアニメーション終了まで右に進む。

図にすると、次のようになります。

次の例では、アニメーションのstartTimeを少しずつずらして設定し、波型のアニメーションを作成しています。また右のボタンをクリックすると、同期させることができます。

startTimeとcurrentTime、アニメーションの同期

// NodeList
const divs = document.querySelectorAll('.box');
const divsArray = Array.from(divs);
const keyframes = {
    transform: ['translateY(0)', 'translateY(250px)', 'translateY(0)']
};
const timings = {
    iterations: 5,
    duration: 4000,
    easing: "ease-in-out"
};

const animArray = [];

// <div>を1つずつ処理
divsArray.forEach((target, index) => {
    // delayは使わない
    // timings.delay = index*500;

    const effect = new KeyframeEffect(target, keyframes, timings);
    const anim = new Animation(effect, document.timeline);

    anim.id = target.childNodes[0].nodeValue;
    // startTimeを使って、アニメーションの開始時刻を操作する
    // document.timeline.currentTimeに足すことで、未来の時刻になる
    anim.startTime = document.timeline.currentTime + index * 500;

    animArray.push(anim);
    // play()しない
    // anim.play();
})
const syncBtn = document.getElementById('sync-btn');
syncBtn.addEventListener('click', () => {
    // [A]の現在時刻を調べる
    const current = animArray[0].currentTime;
    for (let i = 1, len = animArray.length; i < len; i++) {
        // [B]->[E]の現在時刻を[A]の現在時刻に合わせる
        // 同期する
        animArray[i].currentTime = current;;
    }
}, false);<

<textarea>要素に表示されるのは、ボックスAの各プロパティ値です。currentTime値にstartTime値を足すと、概ねdocumet.timeline.currentTime値に一致します。

複数のアニメーションを同期させるということは、AnimationオブジェクトのcurrentTimeを同じ値にする、ということで、言い方を換えると、それぞれ異なるアニメーションの再生ヘッドの位置を全部同じにする、ということです。

コメントを残す

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

CAPTCHA