公共API
Props
概述
useSpring({ from: { ... }, to: { ... }, delay: 100, onRest: () => ... })
以下是所有钩子的公共参数类型
| 属性 | 类型 | 描述 |
|---|---|---|
| from | obj | 基础值,可选 |
| to | obj/fn/array(obj) | 动画目标值 |
| loop | obj/fn/bool | 循环设置,请参阅循 prop具了解更多详情 |
| delay | number/fn | 动画开始前的延迟毫秒.也可以是一个函数:key => delay |
| immediate | bool/fn | 如果为true,则阻止动画.也可以是一个函数:key => immediate |
| config | obj/fn | spring配置(包含质量、张力、摩擦力等).也可以是一个函数:key => config |
| reset | bool | 如果设置为 true, 则spring将开始从头开始执行动画(from -> to) |
| reverse | bool | 如果设置为true,"from"和"to"会切换,这仅与"reset"标志结合使用才有意义 |
| cancel | bool/string/fn | 当为true时,cancel prop停止接收它的控制器拥有的每个执行中的动画值的动画.有关更多详细信息,请参阅cancel prop |
| pause | bool | pause prop可以及时冻结动画 |
events | fn | 多种回调事件(更多信息见事件 |
高级props
Loop Prop
使用loop:true来重复一个动画
loop函数
传入一个每次循环时都会执行的函数.此函数返回true则继续循环,返回false则停止循环.
loop函数也可以返回一个loop对象,这将在后面再详细介绍.当你想在上一个循环完成后立即决定下一个循环动画时,这很有用.
loop对象
定义一个loop对象,将循环动画与初始动画分开自定义.它可能包含任何useSpring的props。例如,如果使用reverse: true,则循环动画将在每个循环中反转.
继承props
loop对象总是合并到定义它的 props 对象的副本中.下面的示例显示了一个循环动画,它继承了它的config prop
请注意循环不会多次运行.那是因为有些props永远不会被继承.这些props包括
default,reset以及reverse.
若要循环动画,请尝试将reset:true添加到上例中的loop属性.或者,你可以添加from: {x: 0}开始添加以获得相同的效果.
最后,尝试将config: { friction: 5 }添加到loop prop.这会使用弹性动画覆盖继承的config.duration.
Cancel Prop
为true时,cancel prop停止所有接受它的Controller所有的动画值的动画
下面这个示例不会生成动画,因为cancel始终为true
useSpring({
cancel: true,
from: { x: 0 },
to: { x: 100 },
})
一旦cancel属性从true变为false,声明的动画将恢复或重置,具体取决于给定的props.
cancel prop从true变为false一次,则定义的动画将继续或重置,这依赖于给定的props.
延迟更新
cancel prop甚至可以防止延迟更新.😎
const [style, animate] = useSpring(() => ({ x: 0 }))
// Pass this to an element.
const onClick = () => {
animate({ x: 100, delay: 500 })
// Prevent the previous update. 🤣
animate({ cancel: true })
}
特定keys
取消特定键的动画,你可以传入单个key,一个keys数组,或者一个(key: string) => boolean函数
// Using a single key
cancel: 'x',
// Using an array of keys
cancel: ['x', 'y'],
// Using a function
cancel: key => key !== 'x',
reset和immediateprops支持这些相同的类型.
事件
| 事件名称 | 描述 |
|---|---|
| onStart | 当一个spring或者一个key即将设置动画时的回调 |
| onChange | 逐帧回调 |
| onRest | spring或key停止时的回调 |
| onPause | spring或key暂停时的回调 |
| onResume | 恢复spring或key时的回调 |
| onDelayEnd | spring或key结束延迟时的回调 |
| onProps | spring或key的props更新时的回调 |
事件作为函数
不包含onDelayEnd和onProps的事件都具有相同的参数传给它们:
(result: AnimationResult, spring: Controller | SpringValue, item?: Item) => void
让我们分析一下:
result(第一个参数): 一个动画结果,这是一个包含调用时的spring值的对象spring(第二个参数): 这是动画结果的Controller或SpringValue,这就是事件item(第三个参数): 这只在使用useTransition钩子和Transition组件时可用
警告: 目前在第一个动画tick之后调用
onStart,这个值被认为是脏的
onDelayEnd和onProps有下面这些参数传入:
(props: SpringProps, spring: SpringValue) => void
props(第一个参数): spring对象的props(与所有传入的新值合并后的值)spring(第二个参数): 受影响的springObject对象
事件作为对象
事件也像onRest一样可以在每个key的基础上定义
useSpring({
from: { x: 0, y: 0 },
onRest: {
x: () => console.log('x.onRest'),
y: () => console.log('y.onRest'),
},
})
动画结果
一些事件在回调时把AnimationResult作为它们的第一个参数.它包含以下属性:
value: any: 动画结束时的当前值.finished?: boolean: 当动画在停止或取消之前完成时为truecancelled?: boolean: 当动画在取消时为true
ref API的start方法resolved时返回的promise,包含一个AnimationResult对象.以及SpringValue和Controller类的start方法.
默认Props
default prop让你可以在同一更新中设置某些props的默认值
声明式更新
对于声明式 API,此prop默认为 true.在下面的示例中,除非定义了自己的onRestprop,否则传递给`animate的每个更新都会继承onRest处理器.
useSpring({
to: async animate => { ... },
onRest: () => { ... }
})
命令式更新
命令式更新可以使用default: true来设置默认的props.当一个异步的toprop被命令更新所定义,它将会像下面那样从命令更新继承props:
useSpring({
from: { x: 0 },
to: async animate => {
// The `config` prop below is inherited by
// both objects in the `to` array.
await animate({
to: [{ x: 100 }, { x: 0 }],
config: { tension: 100 },
})
},
})
默认 props 在SpringValue# _ merge方法中的内部差异算法处理更新时被继承.
比如,ref prop和animate方法都将继承下面定义的默认props(在useSpringprops函数中).
const ref = useSpringRef()
const [{ x }, api] = useSpring(() => ({
x: 0,
onRest: () => { ... },
ref,
}))
useEffect(async () => {
// Animate to 100 with the ref API.
await ref.current.start({ x: 100 })
// Animate to 0 with the returned API.
await api.start({ x: 0 })
}, [])
兼容props
在最后一个示例中,只有onReset prop被继承,因为一些props具有一个默认值.
下面这些props具有默认值:
cancelconfigimmediateonChangeonDelayEndonPropsonRestonStartpause
默认对象
除了传递`default: true 之外,你还可以传递一个对象来代替.只有在你的default对象中定义的props将被保存以供将来更新.
在此示例中,我们true设置为immediate的默认值.这会影响useSpring调用所拥有的所有未来的动画,无论它们是声明式的还是命令式的.
const { x } = useSpring({
x: 0,
default: { immediate: true },
})
useEffect(() => {
// This will be immediate.
x.start(100)
})
配置
Spring 是可配置的并且可以调整.如果你想调整这些设置,你应该提供一个config属性来useSpring:
useSpring({ config: { duration: 250 }, ... })
从v9开始config prop现在可以只更新一部分:
const { x } = useSpring({
from: { x: 0 },
config: { frequency: 1 },
})
useEffect(() => {
x.start({ config: { velocity: 0 } })
x.start({ config: { friction: 20 } })
}, [])
并且我们还添加了以下属性: frequency, damping, round, bounce, progress & restVelocity.
所有属性
| 属性 | 默认值 | 描述 |
|---|---|---|
| mass | 1 | 弹簧质量(重力) |
| tension | 170 | 弹簧动能载荷 |
| friction | 26 | 弹簧阻力 |
| clamp | false | 如果为True,则在弹簧超出其边界时停止 |
| precision | 0.01 | 在我们认为动画值"存在"之前,动画值与最终结果有多接近,这对于弹簧动画很重要 |
| velocity | 0 | 初始速度 |
| easing | t => t | 默认情况下是线性的,你可以使用任何你想要的缓动,例如 d3-ease,我们已经包含了各种缓动,参考这里 |
| damping | 1 | 阻尼比,它决定了弹簧如何减速.仅在frequency定义时有效.默认为1. |
| progress | 0 | 当与duration一起使用时,它决定了从缓动函数开始的距离.持续时间本身不受影响. |
| duration | undefined | 如果 大于 0 将切换到基于持续时间的动画而不是弹簧模式,值应该以毫秒为单位指示(例如duration: 250,持续时间为 250 毫秒) |
| decay | undefined | number的衰减率.如果为true默认为 0.998 |
| frequency | undefined | 固有频率(以秒为单位),它指示不存在阻尼时每秒的反弹次数.定义时,tension从 this派生,friction从tension和damping派生 |
| round | undefined | 制作动画时,四舍五入到该数字的最接近的倍数.from以及to以及任何传递给动画值的set方法的值的值永远不会四舍五入. |
| bounce | undefined | 当大于零时,弹簧将在超过其目标值时反弹而不是超调. |
| restVelocity | undefined | 动画之前的最小速度被认为是"不移动".未定义时,改为使用precision. |
预设
还有一些通用预设将涵盖一些共同点
import { ..., config } from 'react-spring'
useSpring({ ..., config: config.default })
| 属性 | 值 |
|---|---|
| config.default | { mass: 1, tension: 170, friction: 26 } |
| config.gentle | { mass: 1, tension: 120, friction: 14 } |
| config.wobbly | { mass: 1, tension: 180, friction: 12 } |
| config.stiff | { mass: 1, tension: 210, friction: 20 } |
| config.slow | { mass: 1, tension: 280, friction: 60 } |
| config.molasses | { mass: 1, tension: 280, friction: 120 } |
缓动
虽然 react-spring 应该是一个基于 spring 的动画库,但随着时间的推移,它随着一个多合一动画库的野心而发展着.
考虑到这一点,我们现在支持在设置duration时与配置一起使用的多种缓动函数
| In | Out | In Out |
|---|---|---|
| easeInBack | easeOutBack | easeInOutBack |
| easeInBounce | easeOutBounce | easeInOutBounce |
| easeInCirc | easeOutCirc | easeInOutCirc |
| easeInCubic | easeOutCubic | easeInOutCubic |
| easeInElastic | easeOutElastic | easeInOutElastic |
| easeInExpo | easeOutExpo | easeInOutExpo |
| easeInQuad | easeOutQuad | easeInOutQuad |
| easeInQuart | easeOutQuart | easeInOutQuart |
| easeInQuint | easeOutQuint | easeInOutQuint |
| easeInSine | easeOutSine | easeInOutSine |
它们的用法如下:
命令与Refs
虽然本节使用使用hooks的示例,但在类组件中使用createRef 会给你相同的结果.
命令式 API
示例:
from Prop
from Prop现在在命令式更新中表现不同.定义后,它意味着reset 属性为true.以前的版本,除非明确定义了 reset: true,否则from prop不会影响动画.
要阻止这种行为,可以定义reset: false.
const { x } = useSpring({ x: 0 })
useEffect(() => {
// This animates as expected, from 100 to 0.
x.start({ from: 100, to: 0 })
})
API方法
设置为SpringRef或作为Spring返回的数组的第二个参数返回的API对象具有以下方法:
const api = {
// start your animation optionally giving new props to merge e.g. a `to` object
start: (props) => AnimationResult,
// sets the spring to specific passed values
set: (props) => void,
// Add props to each controller's update queue.
update: (props) => this,
// Add a controller to the springRef
add: (ctrl) => this,
// Delete a controller from the springRef
delete: (ctrl) => this,
// Cancel some or all animations depending on the keys passed, no keys will cancel all.
stop: (cancel, keys) => this,
// pause specific spring keys of the spring function
pause: (keys) => this
// resume specific spring keys of the spring function
resume: (keys) => this
}
使用Refs
在以下情况下要使用useSpringRef来代替useRef:
const springRef = useSpringRef()
const { size, ...rest } = useSpring({
ref: springRef,
config: config.stiff,
from: { size: '20%', background: 'hotpink' },
to: {
size: '100%',
background: 'white',
},
})
useEffect(() => {
// this will give you access to the same API documented above
console.log(springRef.current)
}, [])
在内部,ref 使用 add 方法添加了Controller.因此,使用useRef会抛出错误.这在使用useChain时特别有用.
插值
value.to采用以下形状的对象:
| 值 | 默认 | 描述 |
|---|---|---|
| extrapolateLeft | extend | 左外推 |
| extrapolateRight | extend | 右外推 |
| extrapolate | extend | 设置左右外推的快捷方式 |
| range | [0,1] | 输入范围数组 |
| output | undefined | 映射的输出范围数组 |
| map | undefined | 应用于输入值的值过滤器 |
范围快捷方式: value.to([...inputRange], [...outputRange])
或者一个函数: value.to(v => ...)