0

FLIP 动画初步

 2 years ago
source link: https://nicodechal.github.io/2020/09/06/flip-animation-first-step/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

FLIP 介绍

FLIP 是 First、Last、Invert、Play 四个单词的缩写。代表了该动画技术的 4 个主要的步骤:

  • First: 记录元素原本的位置
  • Last: 记录元素完成动画后的位置
  • Invert: 计算从 Last 位置回到 First 位置的参数 ( 例如 translatexy),并将处于 Last 状态的元素移回 First 位置
  • Play: 添加动画并取消 Invert 步骤的位移使元素移动到 Last 位置

FLIP 原理

假设我们要实现一个元素插入效果,元素从前方插入,原本的元素需要向后移,这里希望元素后移时有过渡效果,而不知直接闪现。

transform.png

直接实现的问题在于,元素插入前,无法直接设定原本元素的动画,因为还不知道元素插入后原本的元素会出现在哪里。这时可以使用 FLIP 的方式实现过渡效果。下面说明一下实现的关键步骤:

  1. 在上图左侧状态时,计算浅蓝色方块的位置,这里利用 getBoundingClientRect API 得到元素的 topLeft
  2. 将深蓝色元素直接插入,此时,元素还没有真正渲染,但可以通过 getBoundingClientRect 得到深蓝色元素插入以后( 即右图状态时 ) 浅蓝色元素的位置。
  3. 计算浅蓝色元素从右图位置移回左图位置分别需要在 X 轴和 Y 轴上移动多少,关闭过渡 ( 例如 transition: none ) 并使用 transform: translate(X px, Y px) 的方式将元素移回原位,此时浏览器依旧还没有渲染。但是经过 transform 后,浅蓝色元素在之后的渲染后位置不变
  4. 在下一帧渲染时 ( 通过 requestAnimationFrame 等方式实现 ),打开过渡 ( 例如 transition: all .3s ),并将元素位置重置 ( 例如 transform: translate(0, 0) ),此时元素会从原始位置移回插入之后的位置。

下图说明一个元素从左上角移动到右下角通过 FLIP 实现的过程。

flip.png

下面说明使用 FLIP 如何实现上面提到的元素插入效果:

const container = document.querySelector('.container');
const box = create('div', { classes: ['new-box'] });

// 记录 First 位置 (F)
const brect = container.querySelector('.box').getBoundingClientRect();

prepend(container, box); // 插入元素

// 记录 Last 位置 (L)
const arect = container.querySelector('.box').getBoundingClientRect();

// 将元素从 Last 位置移回 First 位置 (I)
const oldBox = container.querySelector('.box');
const left = brect.left - arect.left;
const top = brect.top - arect.top;
oldBox.style.transition = 'none';
oldBox.style.transform = `translate(${left}px, ${top}px)`;

// 异步执行动画 (P)
setTimeout(() => {
oldBox.style.transform = `translate(0, 0)`;
oldBox.style.transition = 'transform .3s';
}, 0);


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK