#

Tween

Tween中文翻译叫补间动画,就是设定好一个初始值,一个目标值,然后程序帮我们按照我们的设定的变化曲线,补上中间的变化效果的一种变化模式。绝大部分的元素属性的变化默认都是Tween的模式。

type

类型

字符串

delay:'tween'

变化模式设置为Tween

duration

过渡时长

数字类型

duration:2

过渡时长2秒

ease

动画曲线/缓动函数

可设置三种类型数据

1 - 字符串,预设好的缓动曲线名称,比如 'linear'

2 - 数组,通过一个包含四个0-1数字的数组来设定自定义的cubic bezier曲线

3 - 函数,自己定义的缓动函数(很少会用,除非你自己会写缓动函数)

  • "linear"

  • "easeIn", "easeOut", "easeInOut"

  • "circIn", "circOut", "circInOut"

  • "backIn", "backOut", "backInOut"

  • "anticipate"

Framer内置的动画曲线名称

这个demo要打开之后尽量让显示区域全屏浏览👇

所有内置曲线的效果对比DEMO

from

从多少开始

数字|字符串类型

某个属性变化的起点,默认是该元素相应属性当下状态的值

<motion.div
  animate={{ rotate: 180 }}
  // 这里就表示从90度开始转 转到180度 
 transition={{ from: 90, duration: 2 }}
/>

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] }}
/>

#

Spring

Spring是模拟类似弹簧的弹性效果,和物理运动相关的属性变化默认的变化模式是Spring,比如x,y,scalerotate

type

类型

字符串

delay:'spring'

变化模式设置为Spring

duration

过渡时长

数字类型

duration:2

过渡时长2秒

bounce

决定弹性效果的弹性程度

数字类型

0表示没有弹性,1是表示最大的弹性,只能是0-1的值

如果设置了duration属性,bounce的值自动被设置成0.25

注意:如果stiffness,damping或者mass被设置了,会影响到bounce和duration的值,它们两的值可能会失去效果

<motion.div
  animate={{ x: 100 }}
  transition={{ type: "spring", bounce: 0.25 }}
/>

damping

反方向的阻力

数字类型

默认是10,当设置为0,弹性变化会一直不停下来,设置越大阻力越大,停的越快

<motion.a
  animate={{ rotate: 180 }}
  transition={{ type: 'spring', damping: 300 }}
/>

mass

模拟物体的质量大小的值

数字类型

这值默认是1,值设定的越大,就表示这个物体越重,越重的物体弹性变化自然就越不明显

<motion.feTurbulence
  animate={{ baseFrequency: 0.5 } as any}
  transition={{ type: "spring", mass: 0.5 }}
/>

stiffness

决定弹性表现硬度的数值

数字类型

这个默认值是100,这个值越大就表示弹性效果越干脆利落,值越小弹性效果就越柔和

<motion.section
  animate={{ rotate: 180 }}
  transition={{ type: 'spring', stiffness: 50 }}
/>

velocity

弹性动画开始时的初始速度

数字类型

这个值如果不设置,默认就是元素自身的初速度

<motion.div
  animate={{ rotate: 180 }}
  transition={{ type: 'spring', velocity: 2 }}
/>

restSpeed

设定一个临界速度值,低于这个变化速度就停止动画

数字类型

当变化的绝对速度(每秒变化的单位数量)低于设定的这个值,同时剩余的需要变化的值小于restDelta,那么就让变化过程停止。

<motion.div
  animate={{ rotate: 180 }}
  transition={{ type: 'spring', restSpeed: 0.5 }}
/>

restDelta

设定一个临界速度值,剩余需要变化的值低于它就让变化停止

数字类型

当余下需要变化的值小于这个临界值,同时值变化的速度小于restSpeed,那么就让变化停止。当变化停止,需要变化的值会直接跳到最终值。默认这个值是0.01.

<motion.div
  animate={{ rotate: 180 }}
  transition={{ type: 'spring', restDelta: 0.5 }}
/>

在Framer-motion中,有三种元素变化模式,分别是Tween(补间动画)Spring(弹性),Inertia(惯性)。这三种模式的排名是分先后的,排在最前面的是我们最常用,最后的Inertia我们甚至都不会主动去使用它。

我们先来介绍下这三种模式的使用场景:

Tween的变化模式是我们生活中最常见的物体运动的模式,比如加速运动、减速运动、匀速运动,其实都能通过Tween运动模式来实现。当一个元素的样式变化采用的是Tween模式,不管是元素位移还是透明度、还是颜色、尺寸大小等等属性的变化,只要它选择使用了合理的ease(动画曲线),那么看起来就会很自然,很有灵性。像我们在CSS中动画效果中使用的各种ease曲线产生的变化效果,在这里都属于Tween的变化模式。

因此Tween是我们最常会去使用的一种变化模式,使用率可能高达90%

👇motion中预置的ease曲线效果👇

所以,我们平时在给元素属性设置变化模式的时候,横竖就是在TweenSpring之间做选择,而绝大部分时候我们其实都会选择用Tween模式,而使用Tween模式,我们一般都会设置duration或者ease或者两个一起设置,那么我的方式就是,如果我要用Tween模式,我不写type:'tween',因为我知道设置了相关的duration或者ease就算它本来是Spring也会变成Tween模式了

而当我想要元素的动态变化呈现Spring效果,我会特意写一下type:'spring',然后再写其他的Spring相关的设置,这样能防止比如只写了一个duration让变化模式自动变成Tween的情况。这样的话我也就不用去记到底哪些元素的属性默认是Spring,到底哪些属性的变化模式默认是Tween了。

以上是我自己的思路,你可以借鉴使用。

接下来,我们主要来看看三个模式各有哪些属性可以进行设置,虽然Inertia我们不会主动去使用,但是它配套了一些属性是可以让我们去改变元素被拖拽后的惯性效果的。

SpringFramer-motion中自己实现的一种模拟弹簧效果的变化模式,在CSS中是没有的。使用之后就会让元素属性的变化呈现一种弹簧似的效果,这个模式,也是元素位移、缩放、旋转以及一些和尺寸大小相关的比如宽高之类的属性变化时的默认变化模式,总的来说,只要是能让元素产生动态的属性变化,都是默认Spring变化模式。这样的设定,会让元素的动起来的状态有一种q弹的感觉,这样元素的动态看起来不会那么呆板。

最后一个是Inertia,也就是惯性变化模式,这个变化模式我们主动去使用的概率不会超过0.1%。因为这个模式就是模拟元素被拖拽,然后放开之后的惯性运动,这个模式99.99%的情况下只会在可被拖拽元素上出现,我们一般情况下也不会去给一个元素主动设置这样一个变化模式。所以,我们不用去想着说这个模式什么时候用,我们99.99%的情况下是不会主动去用它的,该它起作用的时候,就是元素可以被拖拽的时候,一切都是自动设定好的。

由于和元素动态相关的变化,默认都是Spring的模式,而一些透明度、颜色等其他属性变化我们一般也不会去设置Spring的模式,所以其实我们实际上很少会给元素的属性主动设置为Spring模式,反倒是很多时候元素的的一些动态效果不太适合用弹簧效果,我们就要把一些本来是Spring的模式的样式设置成Tween模式。

因此Spring模式是我们会很少会去主动使用的一种变化模式,可能使用率不会超过9.9%

👇可以尝试拖拽甩出去👇

#

Inertia

Inertia是用来模拟惯性衰减的减速效果,通常用在元素被拖拽后的产生的惯性滚动效果上。

Inertia相关的设置,只有type需要设置在元素的transition这个属性上。其他的都要设置在dragTransition这个属性上,而且要搭配drag属性才能起效果,这个drag就是能让元素可以被拖拽的属性,关于拖拽的一些更多的知识,我们会放到交互部分再讲。

但是一般来说,当我们给元素设置了drag之后,没有必要给他设置transitiontypespring,因为这个时候元素默认就是Spring的模式了。

<motion.div
  drag // 元素能被拖拽
  transition={{ type: "inertia" }} // 这个设置其实是多此一举
  dragTransition={{xxxxx}}
/>

type

类型

字符串

delay:'Inertia'

变化模式设置为Inertia

modifyTarget(v)

这个一个函数,传入的参数是预算出的目标值

返回 数字类型

首先要说明,其实我们每次拖拽放手之后,代码都会计算出一个目标值,然后通过默认的代码逻辑让元素向这个目标值靠近,你可以简单的把这个目标值理解为目标的位置,但是这个目标位置的值并不是像我们常规理解的有x和y的坐标值,它就是一个值,这个值它是会变化的,相当于元素在运动过程中这个值也在不断变化

你给这个属性设定一个函数,这个函数会接受到一个参数,这个参数就是拖拽后产生的目标位置的值,然后你可以对这个值进行处理,一定要也返回一个数字类型的数据

这个方法一般用在让元素贴到特定的位置的一些场景

<motion.div
  drag
  dragTransition={{
    power: 0,
    // 这样处理其实就会让元素会贴到一个50的整数倍的位置
    modifyTarget: target => Math.round(target / 50) * 50
  }}
/>

bounceStiffness

决定弹性表现硬度的数值

数字类型

默认值是500

当元素在拖拽状态时设置了拖拽边界,那么元素在拖出边界范围后放手,元素就会有回弹的类似Spring的效果。

这个属性需要同时设置了min或者max属性时才会起作用

这个属性就是用来设置这个弹性效果利落程度的,它和Spring模式中的siffness是一样的作用,设置得越大元素的弹性效果越干净利落,值越小那么越柔和

<motion.div
  drag
  dragTransition={{
    min: 0,
    max: 100,
    bounceStiffness: 100
  }}
/>

bounceDamping

决定弹性表现反方向阻力的数值

数字类型

默认值 10

当元素在拖拽状态时设置了拖拽边界,那么元素在拖出边界范围后放手,元素就会有回弹的类似Spring的效果。

和bounceStiffness类似,这个属性需要同时设置了min或者max属性时才会起作用

这个属性用来设置类似摩擦阻力的效果,如果设置为0,那么弹性效果不会停下来

<motion.div
  drag
  dragTransition={{
    min: 0,
    max: 100,
    bounceDamping: 8
  }}
/>

power

力量越大,元素惯性越大,会运动到越远

数字类型

默认值 0.8

<motion.div
  drag
  dragTransition={{ power: 0.2 }}
/>

power

力量越大,元素惯性越大,会运动到越远

数字类型

默认值 0.8

<motion.div
  drag
  dragTransition={{ power: 0.2 }}
/>

timeConstant

设置衰减的时间(类似)

数字类型

默认值 700(并不是秒数)

<motion.div
  drag
  dragTransition={{ timeConstant: 200 }}
/>

restDelta

余下距离的差值

和Spring属性中的同名属性一样的作用,都是对拖拽可能会产生的弹性效果起作用

<motion.div
  drag
  dragTransition={{ restDelta: 10 }}
/>

min

最小偏移值

数字类型

min和max可以单独设置,也可以一起设置,其实两个是用来快速的设置一个拖拽的限制区域(以元素本身为基准),min就是左侧和上方区域的边界,max就是右侧和下方区域的边界,相应的min和max的值其实就是元素按照这个数值移动x和y之后,对应边界的x和y的值。

如果元素被拖拽出边界,是有一个回拉力的,如果放手的时候元素在边界外,元素会自动回弹回边界内

<motion.div
  drag
  dragTransition={{ power: 0.2 }}
/>

max

最大偏移值

数字类型

min和max可以单独设置,也可以一起设置,其实两个是用来快速的设置一个拖拽的限制区域(以元素本身为基准),min就是左侧和上方区域的边界,max就是右侧和下方区域的边界,相应的min和max的值其实就是元素按照这个数值移动x和y之后,对应边界的x和y的值。

如果元素被拖拽出边界,是有一个回拉力的,如果放手的时候元素在边界外,元素会自动回弹回边界内

<motion.div
  drag
  dragTransition={{ power: 0.2 }}
/>