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 を書き換えるよりもこちらのほうがだいぶパフォーマンス良いそうです。