Animated
Animated
库旨在使动画流畅、强大且易于构建和维护。Animated
专注于输入和输出之间的声明性关系,中间可配置的转换,以及控制基于时间的动画执行的 start
/stop
方法。
创建动画的核心工作流程是创建一个 Animated.Value
,将其连接到一个或多个动画组件的样式属性,然后使用 Animated.timing()
通过动画驱动更新。
不要直接修改动画值。您可以使用
useRef
Hook 返回一个可变的 ref 对象。此 ref 对象的current
属性初始化为给定参数,并在组件生命周期中保持不变。
示例
以下示例包含一个 View
,它将根据动画值 fadeAnim
淡入淡出
请参阅 动画 指南,查看 Animated
实际应用的更多示例。
概述
您可以将两种值类型与 Animated
配合使用
Animated.Value()
用于单个值Animated.ValueXY()
用于向量
Animated.Value
可以绑定到样式属性或其他 props,也可以进行插值。单个 Animated.Value
可以驱动任意数量的属性。
配置动画
Animated
提供三种动画类型。每种动画类型都提供特定的动画曲线,控制您的值如何从初始值动画到最终值
Animated.decay()
以初始速度开始,并逐渐减速至停止。Animated.spring()
提供基本的弹簧物理模型。Animated.timing()
使用 缓动函数 在一段时间内动画一个值。
在大多数情况下,您将使用 timing()
。默认情况下,它使用对称的 easeInOut 曲线,传达物体逐渐加速到全速,然后逐渐减速到停止。
使用动画
通过在动画上调用 start()
来启动动画。start()
接受一个完成回调,该回调将在动画完成时调用。如果动画正常运行完成,则完成回调将使用 {finished: true}
调用。如果动画因为在完成之前调用了 stop()
而完成(例如,因为它被手势或另一个动画中断),那么它将接收 {finished: false}
。
Animated.timing({}).start(({finished}) => {
/* completion callback */
});
使用原生驱动
通过使用原生驱动,我们在启动动画之前将所有关于动画的信息发送到原生层,允许原生代码在 UI 线程上执行动画,而无需在每一帧都通过桥接。一旦动画开始,JS 线程就可以被阻塞而不影响动画。
您可以通过在动画配置中指定 useNativeDriver: true
来使用原生驱动。有关更多信息,请参阅 动画 指南。
可动画组件
只有可动画组件才能动画。这些独特的组件通过将动画值绑定到属性来完成魔术,并进行有针对性的原生更新,以避免在每一帧上 React 渲染和协调过程的开销。它们还处理卸载时的清理,因此默认情况下是安全的。
createAnimatedComponent()
可用于使组件可动画。
Animated
使用上述包装器导出以下可动画组件
Animated.Image
Animated.ScrollView
Animated.Text
Animated.View
Animated.FlatList
Animated.SectionList
组合动画
动画也可以使用组合函数以复杂的方式组合
Animated.delay()
在给定延迟后启动动画。Animated.parallel()
同时启动多个动画。Animated.sequence()
按顺序启动动画,等待每个动画完成,然后启动下一个。Animated.stagger()
按顺序并行启动动画,但具有连续延迟。
动画也可以通过将一个动画的 toValue
设置为另一个 Animated.Value
来链式连接。请参阅动画指南中的 跟踪动态值。
默认情况下,如果一个动画停止或中断,则组中的所有其他动画也将停止。
组合动画值
您可以通过加、减、乘、除或模运算组合两个动画值以创建新的动画值
插值
interpolate()
函数允许输入范围映射到不同的输出范围。默认情况下,它将超出给定范围外推曲线,但您也可以使其限制输出值。它默认使用线性插值,但也支持缓动函数。
阅读 动画 指南中有关插值的更多信息。
处理手势和其他事件
手势,如平移或滚动,以及其他事件可以使用 Animated.event()
直接映射到动画值。这是通过结构化映射语法完成的,以便可以从复杂的事件对象中提取值。第一层是一个数组,允许跨多个参数进行映射,并且该数组包含嵌套对象。
例如,在使用水平滚动手势时,您将执行以下操作,以便将 event.nativeEvent.contentOffset.x
映射到 scrollX
(一个 Animated.Value
)
onScroll={Animated.event(
// scrollX = e.nativeEvent.contentOffset.x
[{nativeEvent: {
contentOffset: {
x: scrollX
}
}
}]
)}
参考
方法
当给定值是 ValueXY 而不是 Value 时,每个配置选项可以是 {x: ..., y: ...}
形式的向量而不是标量。
decay()
static decay(value, config): CompositeAnimation;
根据衰减系数将值从初始速度动画到零。
Config 是一个对象,可能包含以下选项
velocity
:初始速度。必需。deceleration
:衰减率。默认 0.997。isInteraction
:此动画是否在InteractionManager
上创建“交互句柄”。默认 true。useNativeDriver
:如果为 true,则使用原生驱动。必需。
timing()
static timing(value, config): CompositeAnimation;
沿时间缓动曲线动画一个值。 Easing
模块包含大量预定义曲线,或者您可以使用自己的函数。
Config 是一个对象,可能包含以下选项
duration
:动画时长(毫秒)。默认 500。easing
:用于定义曲线的缓动函数。默认值为Easing.inOut(Easing.ease)
。delay
:延迟后启动动画(毫秒)。默认 0。isInteraction
:此动画是否在InteractionManager
上创建“交互句柄”。默认 true。useNativeDriver
:如果为 true,则使用原生驱动。必需。
spring()
static spring(value, config): CompositeAnimation;
根据基于 阻尼谐振动 的解析弹簧模型动画一个值。跟踪速度状态以在 toValue
更新时创建流畅的运动,并且可以链式连接。
Config 是一个对象,可能包含以下选项。
请注意,您只能定义 bounciness/speed、tension/friction 或 stiffness/damping/mass 中的一个,不能定义多个
friction/tension 或 bounciness/speed 选项与 Facebook Pop
、Rebound 和 Origami 中的弹簧模型匹配。
friction
:控制“弹性”/过冲。默认 7。tension
:控制速度。默认 40。speed
:控制动画速度。默认 12。bounciness
:控制弹性。默认 8。
将 stiffness/damping/mass 指定为参数使 Animated.spring
使用基于 阻尼谐振动器 运动方程的解析弹簧模型。这种行为更精确,更忠实于弹簧动力学背后的物理原理,并与 iOS 的 CASpringAnimation 中的实现非常相似。
stiffness
:弹簧刚度系数。默认 100。damping
:定义弹簧的运动应如何因摩擦力而阻尼。默认 10。mass
:连接到弹簧末端的物体的质量。默认 1。
其他配置选项如下
velocity
:连接到弹簧的物体的初始速度。默认 0(物体静止)。overshootClamping
:布尔值,指示弹簧是否应被夹紧且不弹跳。默认 false。restDisplacementThreshold
:弹簧应被视为静止的位移阈值。默认 0.001。restSpeedThreshold
:弹簧应被视为静止的速度,单位为像素/秒。默认 0.001。delay
:延迟后启动动画(毫秒)。默认 0。isInteraction
:此动画是否在InteractionManager
上创建“交互句柄”。默认 true。useNativeDriver
:如果为 true,则使用原生驱动。必需。
add()
static add(a: Animated, b: Animated): AnimatedAddition;
创建一个由两个动画值相加组成的新动画值。
subtract()
static subtract(a: Animated, b: Animated): AnimatedSubtraction;
创建一个由第一个动画值减去第二个动画值组成的新动画值。
divide()
static divide(a: Animated, b: Animated): AnimatedDivision;
创建一个由第一个动画值除以第二个动画值组成的新动画值。
multiply()
static multiply(a: Animated, b: Animated): AnimatedMultiplication;
创建一个由两个动画值相乘组成的新动画值。
modulo()
static modulo(a: Animated, modulus: number): AnimatedModulo;
创建一个新的动画值,该值是提供的动画值的(非负)模
diffClamp()
static diffClamp(a: Animated, min: number, max: number): AnimatedDiffClamp;
创建一个限制在 2 个值之间的新动画值。它使用与最后一个值之间的差异,因此即使值离边界很远,当值再次接近时,它也会开始改变。(value = clamp(value + diff, min, max)
)。
这在滚动事件中很有用,例如,在向上滚动时显示导航栏,在向下滚动时隐藏导航栏。
delay()
static delay(time: number): CompositeAnimation;
在给定延迟后启动动画。
sequence()
static sequence(animations: CompositeAnimation[]): CompositeAnimation;
按顺序启动动画数组,等待每个动画完成,然后启动下一个。如果当前运行的动画停止,则不会启动后续动画。
parallel()
static parallel(
animations: CompositeAnimation[],
config?: ParallelConfig
): CompositeAnimation;
同时启动一组动画。默认情况下,如果其中一个动画停止,它们都将停止。您可以使用 stopTogether
标志覆盖此行为。
stagger()
static stagger(
time: number,
animations: CompositeAnimation[]
): CompositeAnimation;
动画数组可以并行运行(重叠),但按顺序启动,并具有连续延迟。适用于制作拖尾效果。
loop()
static loop(
animation: CompositeAnimation[],
config?: LoopAnimationConfig
): CompositeAnimation;
连续循环给定动画,使其每次到达末尾时都重置并从头开始。如果子动画设置为 useNativeDriver: true
,则会循环而不会阻塞 JS 线程。此外,循环可以阻止基于 VirtualizedList
的组件在动画运行时渲染更多行。您可以在子动画配置中传递 isInteraction: false
来解决此问题。
Config 是一个对象,可能包含以下选项
iterations
:动画循环的次数。默认-1
(无限)。
event()
static event(
argMapping: Mapping[],
config?: EventConfig
): (...args: any[]) => void;
接受一个映射数组并相应地从每个参数中提取值,然后对映射的输出调用 setValue
。例如
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {x: this._scrollX}}}],
{listener: (event: ScrollEvent) => console.log(event)}, // Optional async listener
)}
...
onPanResponderMove: Animated.event(
[
null, // raw event arg ignored
{dx: this._panX},
], // gestureState arg
{
listener: (
event: GestureResponderEvent,
gestureState: PanResponderGestureState
) => console.log(event, gestureState),
} // Optional async listener
);
Config 是一个对象,可能包含以下选项
listener
:可选的异步监听器。useNativeDriver
:如果为 true,则使用原生驱动。必需。
forkEvent()
static forkEvent(event: AnimatedEvent, listener: Function): AnimatedEvent;
用于窥探通过 props 传入的动画事件的高级命令式 API。它允许向现有的 AnimatedEvent
添加新的 javascript 监听器。如果 animatedEvent
是 javascript 监听器,它将把两个监听器合并为一个,如果 animatedEvent
为 null/undefined,它将直接分配 javascript 监听器。尽可能直接使用值。
unforkEvent()
static unforkEvent(event: AnimatedEvent, listener: Function);
start()
static start(callback?: (result: {finished: boolean}) => void);
通过在动画上调用 start() 来启动动画。start() 接受一个完成回调,该回调将在动画完成时调用,或者在动画因在完成之前调用 stop() 而完成时调用。
参数
姓名 | 类型 | 必需 | 描述 |
---|---|---|---|
callback | (result: {finished: boolean}) => void | 否 | 动画正常运行完成或动画因在完成之前调用 stop() 而完成时将调用的函数 |
带回调的启动示例
Animated.timing({}).start(({finished}) => {
/* completion callback */
});
stop()
static stop();
停止任何正在运行的动画。
reset()
static reset();
停止任何正在运行的动画并将其值重置为原始值。
属性
Value
用于驱动动画的标准值类。通常在类组件中使用 useAnimatedValue(0);
或 new Animated.Value(0);
进行初始化。
您可以在单独的 页面 上阅读有关 Animated.Value
API 的更多信息。
ValueXY
用于驱动 2D 动画(例如平移手势)的 2D 值类。
您可以在单独的 页面 上阅读有关 Animated.ValueXY
API 的更多信息。
Interpolation
导出以在流程中使用 Interpolation 类型。
Node
导出以方便类型检查。所有动画值都源自此类别。
createAnimatedComponent
使任何 React 组件可动画。用于创建 Animated.View
等。
attachNativeEvent
将动画值附加到视图上的事件的命令式 API。如果可能,首选使用 Animated.event
和 useNativeDriver: true
。