10_9_4 Promise系

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)

コメントを残す

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

CAPTCHA