如果你熟悉CSSAnimation,那么一定熟悉关键帧动画。在Framer-motion中,也是可以实现类似关键帧动画的效果的。

想要在motion元素上实现关键帧动画,关键就是要在设置属性的变化的值时,采用数组的方式,比如像这样:

<motion.div
// 这个元素的会进行从0移动到200,然后在回到0的x坐标
  animate={{ x: [0, 200, 0] }}
/>

通过数组的形式分段,理论上是可以无限分的。注意每个分段的变化时长,默认情况下是平均分,比如duration设置的是1秒,向上面这个案例,那么0-200变化是0.5秒,200-0变化是0.5秒。

关键帧动画的逻辑,其实就是让元素属性分多个阶段(目标变化),很多时候我们就是用来做这种让元素进行变化之后,然后又反向变化回一开始的状态的动画效果。

有时候,我们也会配合变化设置中repeat以及repeatType来实现一直重复变化的效果,很多时候这样的效果我们在做一些简单的loading加载动画的就会用到。

但是我们可以设置一个transition中的属性times,来手动设定每个分段的时长(transition设置的内容中我们已经介绍过的)。

times

过渡时间的分段

0-1数字组成的数组,最后一个肯定是1

配合关键帧动画模式的写法,对duration的值进行划分,让每一段动画都对应自己的变化时长

<motion.div
// 用数组的方式就是关键帧动画的写法,这里表示整个关键帧动画是从scale为0变化到scale为1
// 然后接着变化到scale为0.5,再最后变化到scale为1
// 整个关键帧动画分为了三段,分别是 0->1  1->0.5  0.5->1
  animate={{ scale: [0, 1, 0.5, 1] }}
// 这里times的写法,是按照时间的进度来写的,0就是0%,0.1就是10%,0.9就是90%,1就是100%
// 如果整个动画的duration是2秒
// 也就是它的时间 0-0.1 是给scale 0->1 这个变化时间是0.2秒
// 中间scale 1->0.5 的变化时间是1.6秒 10%到90%的时间
// 最后scale 0.5->1 的变化时间是0.2秒 90%到100%
  transition={{ times: [0, 0.1, 0.9, 1] }}
/>

而且,我们还可以手动的设置不同分段变化的ease曲线,同样要用数组:

<motion.div>
   transition={{
          duration:2,
          //0-200用的是linear的运动曲线,200-0用的是easeInOut运动曲线
          ease:['linear','easeInOut']
        }}
   animate={{x:[0,200,0]}}
</motion.div>

motion元素中,设置关键真动画,可用null开头,比如像下面这样:

<motion.div>
  style={{
      x:300
     }}
   animate={{
      // 元素会从x 300的位置开始变化,先变化到200,再变化到0
      x:[null,200,0]
     }}
</motion.div>

通过给数组的第一个数据设置null,元素的关键帧动画,会从元素该关键帧开始执行的当时的元素相应的属性的值为起始值,这样会让元素的整个关键帧动画启动时更自然,所以很多时候可以采用这样的方式来写关键帧动画。

<motion.div>
  transition={{
          duration:1,
          // 一直无限重复
          repeat:Infinity
        }}
   animate={{
      rotate:[0,180,0]
     }}
</motion.div>