Animation.readyプロパティは、アニメーションの再生準備ができたときに解決されるPromiseオブジェクトを返します。これは、言い換えると、アニメーションの再生準備が確実に整うまで実行したくないコードが安心して記述できる、ということです。
Animation.finishedプロパティは、アニメーションの再生が完了したときに解決されるPromiseオブジェクトを返します。これは、言い換えると、アニメーションの再生が確実に終わるまで実行したくないコードが安心して記述できる、ということです。
次の例では、立体に見える面を1つずつ順番にアニメーションして配置し、三角錐を作成しています。
// 共通
const timings = {
iterations: 1,
duration: 3000,
easing: "ease-in-out",
fill: 'forwards'
};
// まず底面のアニメーションを単独で作成
const base = document.querySelector('.base');
const keyframesBase = {
transform: 'rotateX(90deg)'
};
const effectBase = new KeyframeEffect(base, keyframesBase, timings);
const animBase = new Animation(effectBase, document.timeline);
// そのほかの面への参照
const front = document.querySelector('.front');
const right = document.querySelector('.right');
const left = document.querySelector('.left');
const back = document.querySelector('.back');
// アニメーションをまとめて作成するので、面を配列に入れる
const partsArray = [front, right, left, back];
// キーフレームパラメータも、配列の中にオブジェクトとして入れる。
const keyframes = [{
transform: 'translate3d(0, 100px, 100px) rotateX(30deg)'
}, {
transform: 'translate3d(200px, -200px,0) rotateX(-90deg) rotateY(120deg)'
}, {
transform: 'translate3d(-200px, -400px,0) rotateX(-90deg) rotateY(-120deg)'
}, {
transform: 'translate3d(0, -500px, -100px) rotateX(-210deg)'
}];
// アニメーションを作成して返す関数
const setAnimation = (target, keyframes) => {
const effect = new KeyframeEffect(target, keyframes, timings);
const anim = new Animation(effect, document.timeline);
return anim;
}
// 作成したアニメーションを入れる配列。
// アニメーションはこの配列のインデックス位置を利用して使用する。
const animsArray = [];
// アニメーションをまとめて作成し、配列に入れる
for (let i = 0, len = partsArray.length; i < len; i++) {
const anim = setAnimation(partsArray[i], keyframes[i]);
animsArray.push(anim);
}
// AnimationオブジェクトのPromiseを使って、
// 前の再生が終わったら次の再生に移る仕組みを作成する。
animBase.finished.then(() => {
animsArray[0].play();
return animsArray[0].finished;
}).then(() => {
animsArray[1].play();
return animsArray[1].finished;
}).then(() => {
animsArray[2].play();
return animsArray[2].finished;
}).then(() => {
animsArray[3].play();
});
// [Start]ボタンのクリックで、底面のアニメーションを開始。
// これにより、各面が順にアニメーションして、ピラミッドを形成する。
document.getElementById('start-btn').addEventListener('click', () => {
animBase.play();
}, false)