Animation.timelineプロパティは、アニメーションのタイムラインを参照します。現状では、アニメーションの基準として使用できるタイムラインは、ドキュメントのタイムラインしかありません。
タイムラインは、”時間”ととらえるよりも、左から右に進む時間軸、または左右に伸びたビデオテープの上を進む再生ヘッドととらえた方が分かりやすいでしょう。何秒という時間の値が、位置として見なせるようになります。
Animation.startTime
アニメーションの再生が開始されるべきタイム値の取得と設定を行う。ミリ秒単位。初期値はnull。
delayプロパティとの違い:delayを設定してもアニメーションは自動的にスタートしませんが、startTimeを設定すると、play()を呼び出さなくても、アニメーションはその時間がくれば自動的にスタートします。
Animationオブジェクト(anim)のstartTimeに、document.timeline.currentTime + タイム値を設定すると、その時点からタイム値ミリ秒後に、アニメーションは自動的にスタートします。タイム値にマイナス値を設定すると、すでにそのアニメーションはスタートしたものとして、途中から開始されます。
Animation.currentTime
アニメーションの現在のタイム値の取得と設定を行う。playbackRateの影響は受けない。再生開始前はnull。
たとえば、startTimeをdocument.currentTime + 10に設定した場合、物事は次のように進行します。
- ページが開かれると、window.performaceのnavigationStart値をタイム値0として、document.timelineが作成され、document.timeline.currentTimeが発生する。これは、ドキュメントのタイムラインが動き出すことを意味する。
- startTimeはdocument.currentTime + 10なので、アニメーションはまだ再生されず、anim.currentTimeはnullの状態。
- 10ミリ秒たつと、document.timelineがanim.startTimeの位置に達するので、anim.currentTimeが発生し、アニメーションの再生が始まる。
- 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を同じ値にする、ということで、言い方を換えると、それぞれ異なるアニメーションの再生ヘッドの位置を全部同じにする、ということです。