重现framer的神奇布局动画的指南。
到目前为止,我最喜欢 Framer Motion 的部分是它神奇的布局动画–将 layout prop 拍在任何运动组件上,看着该组件从页面的一个部分无缝过渡到下一个部分。
<motion.div layout />
在这篇文章中,我们主要介绍:
- 布局变化:它们是什么,何时发生。
- 基于CSS的方法以及为什么它们并不总是有效。
- FLIP:是Framer Motion使用的技术。
布局变化
当页面上的一个元素影响其他元素改变位置时,就会发生布局变化。例如,改变一个元素的宽度或高度就是一种布局变化,因为任何相邻的元素都必须移动,以便为该元素的新尺寸腾出空间。
同样,改变元素的justify-content
属性也是一种布局变化,因为它导致该元素的子元素改变位置。
不过,像scale
属性的变化并不是布局的改变,因为它的变化不影响页面上的其他元素。
用CSS做动画
那么,我们如何将布局变化做成动画呢?一种方法是直接使用 CSS过渡使属性产生动画:
.square {transition: width 0.2s ease-out;
}
现在,当 square
改变宽度时,它将在其大小之间无缝动画化:
// Motion.js
import React from 'react'
import './styles.css'
export default function Motion({ toggled }) {return <div className={`active ${toggled ? 'toggled' : ''}`} />
}
style.css
.active {border: 1px solid hsl(208, 77.5%, 76.9%);background: hsl(209, 81.2%, 84.5%);width: 120px;height: 120px;border-radius: 8px;transition: width 0.5s ease-out;
}
.toggled {width: 200px;
}
看上去,CSS 也可以做动画,但它有两个主要的缺点:
- 不能把所有东西都做成动画。例如,不能对
justify-content
的变化制作动画,因为justify-content
不是一个可动画的属性。* 性能问题。涉及布局变化的CSS动画通常比基于 transform 的动画更昂贵,所以你可能会发现你的动画在低端设备上不那么流畅。我们先来看看性能问题。
性能
- 不要预先优化 如果在低端设备上没有注意到任何性能问题,而且CSS transition 对你有效,那么就不要担心!只有在需要时才进行优化。
涉及布局变化的CSS动画通常比其他CSS动画更昂贵,因为它影响到周围的其他元素。这是因为浏览器必须在动画的每一帧中重新计算页面的布局–对于一个60FPS的动画来说,这意味着每秒钟要计算60次!
回顾上面动画。注意到灰色的盒子看起来也在做动画,尽管我们只过渡了蓝色的盒子:
发生这种情况的原因是,每次蓝框的尺寸发生变化时,浏览器都会重新计算灰框的位置。
另一方面,浏览器可以更快地对 transform
等CSS属性进行动画处理,因为它们不影响布局。
注意,随着蓝色方框的增长,灰色方框保持原状!
所以,如果 transform
的动画成本更低,我们是否可以用 transform
来代替布局变化?
是的,可以!
FLIP
FLIP 是 First, Last, Inverse, Play
的缩写,它是一种技术,可以让我们使用 “快速” 的 CSS 属性(如transform
)对 “slow” 的布局变化制作动画。FLIP甚至可以对 “不可动画” 的属性(如justify-content
)进行动画处理。Framer Motion使用FLIP来实现其布局动画。
顾名思义,FLIP是一种四步技术,它通