FLIP で要素の移動のアニメーション

Vue.js のチュートリアルを読んでいて FLIP という要素の移動のためのアニメーションの手法を知りました。

要するに・・

  • First. 要素の最初の状態を取得
  • Last. 要素の最後の状態を取得
  • Invert. 要素の最初から最後までの状態変化を反転させた状態を適用
  • Play. 適用した状態を解除してアニメーションを開始

下記のように要素の移動をアニメーションさせられます。

要素の移動までの状態を取得して、

    // 要素の移動前の位置をマップに保存
    const map = new Map();
    for (const el of elem.querySelectorAll('li')) {
        const r = el.getBoundingClientRect();
        map.set(el, r);
    }

要素を実際に移動させます。どう移動するかは押したボタンによります。

    // コールバックで要素を移動させる
    callback();

移動後の要素の状態を取得して、

            // 移動後の要素の位置を得る
            const r2 = el.getBoundingClientRect();

反転して transform に適用します。

            // 要素の移動距離を反転して transform に適用する
            const x = r1.left - r2.left;
            const y = r1.top - r2.top;
            el.style.transitionProperty = 'none';
            el.style.transform = `translate(${x}px,${y}px)`;

そして transform を解除してアニメーションを開始します。

            requestAnimationFrame(() => {
                // 要素の transform を解除して本来の位置に戻す
                el.style.transitionProperty = '';
                el.style.transform = '';
            });

js で left や top を書き換えるよりもこちらのほうがだいぶパフォーマンス良いそうです。