跳到主要内容
版本:0.81

Animated 动画

Animated 库旨在使动画流畅、强大且易于构建和维护。Animated 专注于输入和输出之间的声明式关系、中间的可配置变换,以及用于控制基于时间的动画执行的 start/stop 方法。

创建动画的核心工作流程是创建一个 Animated.Value,将其连接到动画组件的一个或多个样式属性,然后通过使用 Animated.timing() 的动画来驱动更新。

备注

不要直接修改 animated value。你可以使用 useRef Hook 来返回一个可变的 ref 对象。该 ref 对象的 current 属性会以给定参数初始化,并在整个组件生命周期中持续存在。

示例​

以下示例包含一个 View,它将基于动画值 fadeAnim 进行淡入和淡出

参阅 动画 指南以查看 Animated 运行的更多示例。

概述​

你可以配合 Animated 使用两种值类型:

Animated.Value 可以绑定到样式属性或其他 props,也可以进行插值。单个 Animated.Value 可以驱动任意数量的属性。

配置动画​

Animated 提供三种类型的动画。每种动画类型提供特定的动画曲线,控制你的值如何从初始值动画到最终值:

在大多数情况下,你将使用 timing()。默认情况下,它使用对称的 easeInOut 曲线,传达物体逐渐加速到全速并通过逐渐减速到停止的过程。

使用动画​

通过在动画上调用 start() 来启动动画。start() 接受一个完成回调,该回调将在动画完成时调用。如果动画正常完成,完成回调将使用 {finished: true} 调用。如果动画是因为在完成之前调用了 stop() 而完成(例如,因为它被手势或另一个动画中断),那么它将收到 {finished: false}。

React TSX
Animated.timing({}).start(({finished}) => {
/* 完成回调 */
});

使用原生驱动​

通过使用原生驱动,我们在启动动画之前将有关动画的所有内容发送到原生端,允许原生代码在 UI 线程上执行动画,而不必在每一帧上都通过桥接。一旦动画开始,JS 线程可以被阻塞而不影响动画。

你可以通过在动画配置中指定 useNativeDriver: true 来使用原生驱动。请参阅 动画 指南以了解更多。

可动画组件​

只有可动画组件才能被动画化。这些独特的组件完成了将动画值绑定到属性的魔法,并进行有针对性的原生更新,以避免每一帧上 React 渲染和协调过程的成本。它们还处理卸载时的清理,因此默认情况下是安全的。

Animated 使用上述包装器导出以下可动画组件:

  • Animated.Image
  • Animated.ScrollView
  • Animated.Text
  • Animated.View
  • Animated.FlatList
  • Animated.SectionList

组合动画​

动画也可以使用组合函数以复杂的方式组合:

动画也可以通过将一个动画的 toValue 设置为另一个 Animated.Value 来链接在一起。请参阅动画指南中的 跟踪动态值。

默认情况下,如果一个动画停止或中断,则组中的所有其他动画也会停止。

组合动画值​

你可以通过加法、减法、乘法、除法或取模来组合两个动画值,以制作一个新的动画值:

插值​

interpolate() 函数允许输入范围映射到不同的输出范围。默认情况下,它将外推超出给定范围的曲线,但你也可以让它钳制输出值。默认情况下它使用线性插值,但也支持缓动函数。

在 动画 指南中阅读更多关于插值的信息。

处理手势和其他事件​

手势(如平移或滚动)和其他事件可以使用 Animated.event() 直接映射到动画值。这是通过结构化映射语法完成的,以便可以从复杂的事件对象中提取值。第一级是一个数组,允许跨多个参数进行映射,该数组包含嵌套对象。

例如,当使用水平滚动手势时,你将执行以下操作以将 event.nativeEvent.contentOffset.x 映射到 scrollX(一个 Animated.Value):

React TSX
onScroll={Animated.event(
// scrollX = e.nativeEvent.contentOffset.x
[{nativeEvent: {
contentOffset: {
x: scrollX
}
}
}]
)}

参考

方法​

当给定的值是 ValueXY 而不是 Value 时,每个配置选项可以是 {x: ..., y: ...} 形式的向量,而不是标量。

decay()​

React TSX
static decay(value, config): CompositeAnimation;

基于衰减系数将值从初始速度动画化到零。

Config 是一个对象,可能具有以下选项:

  • velocity: 初始速度。必填。
  • deceleration: 衰减率。默认 0.997。
  • isInteraction: 此动画是否在 InteractionManager 上创建“交互句柄”。默认 true。
  • useNativeDriver: 为 true 时使用原生驱动。必填。

timing()​

React TSX
static timing(value, config): CompositeAnimation;

沿定时缓动曲线动画化一个值。Easing 模块有很多预定义的曲线,或者你可以使用自己的函数。

Config 是一个对象,可能具有以下选项:

  • duration: 动画长度(毫秒)。默认 500。
  • easing: 定义曲线的缓动函数。默认是 Easing.inOut(Easing.ease)。
  • delay: 延迟后启动动画(毫秒)。默认 0。
  • isInteraction: 此动画是否在 InteractionManager 上创建“交互句柄”。默认 true。
  • useNativeDriver: 为 true 时使用原生驱动。必填。

spring()​

React TSX
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()​

React TSX
static add(a: Animated, b: Animated): AnimatedAddition;

创建一个由两个相加的 Animated 值组成的新 Animated 值。


subtract()​

React TSX
static subtract(a: Animated, b: Animated): AnimatedSubtraction;

创建一个由第一个 Animated 值减去第二个 Animated 值组成的新 Animated 值。


divide()​

React TSX
static divide(a: Animated, b: Animated): AnimatedDivision;

创建一个由第一个 Animated 值除以第二个 Animated 值组成的新 Animated 值。


multiply()​

React TSX
static multiply(a: Animated, b: Animated): AnimatedMultiplication;

创建一个由两个相乘的 Animated 值组成的新 Animated 值。


modulo()​

React TSX
static modulo(a: Animated, modulus: number): AnimatedModulo;

创建一个新 Animated 值,它是提供的 Animated 值的(非负)模。


diffClamp()​

React TSX
static diffClamp(a: Animated, min: number, max: number): AnimatedDiffClamp;

创建一个新 Animated 值,限制在 2 个值之间。它使用与最后一个值的差值,因此即使值远离边界,当值再次开始接近时它也将开始变化。(value = clamp(value + diff, min, max))。

这对于滚动事件很有用,例如,向上滚动时显示导航栏,向下滚动时隐藏它。


delay()​

React TSX
static delay(time: number): CompositeAnimation;

在给定的延迟后启动动画。


sequence()​

React TSX
static sequence(animations: CompositeAnimation[]): CompositeAnimation;

按顺序启动动画数组,等待每个动画完成后再启动下一个。如果当前运行的动画停止,则不会启动后续动画。


parallel()​

React TSX
static parallel(
animations: CompositeAnimation[],
config?: ParallelConfig
): CompositeAnimation;

同时启动动画数组。默认情况下,如果其中一个动画停止,它们都将停止。你可以使用 stopTogether 标志覆盖此行为。


stagger()​

React TSX
static stagger(
time: number,
animations: CompositeAnimation[]
): CompositeAnimation;

动画数组可以并行运行(重叠),但按顺序启动并具有连续的延迟。适合做拖尾效果。


loop()​

React TSX
static loop(
animation: CompositeAnimation[],
config?: LoopAnimationConfig
): CompositeAnimation;

连续循环给定的动画,以便每次到达结束时,它都会重置并从头开始。如果子动画设置为 useNativeDriver: true,则循环将不会阻塞 JS 线程。此外,循环可以防止基于 VirtualizedList 的组件在动画运行时渲染更多行。你可以在子动画配置中传递 isInteraction: false 来修复此问题。

Config 是一个对象,可能具有以下选项:

  • iterations: 动画应循环的次数。默认 -1(无限)。

event()​

React TSX
static event(
argMapping: Mapping[],
config?: EventConfig
): (...args: any[]) => void;

接受映射数组并从每个参数中提取值,然后在映射的输出上调用 setValue。例如:

React TSX
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {x: this._scrollX}}}],
{listener: (event: ScrollEvent) => console.log(event)}, // 可选的异步监听器
)}
...
onPanResponderMove: Animated.event(
[
null, // 原始事件参数被忽略
{dx: this._panX},
], // gestureState 参数
{
listener: (
event: GestureResponderEvent,
gestureState: PanResponderGestureState
) => console.log(event, gestureState),
} // 可选的异步监听器
);

Config 是一个对象,可能具有以下选项:

  • listener: 可选的异步监听器。
  • useNativeDriver: 为 true 时使用原生驱动。必填。

forkEvent()​

React JSX
static forkEvent(event: AnimatedEvent, listener: Function): AnimatedEvent;

用于监视通过 props 传递的动画事件的高级命令式 API。它允许向现有的 AnimatedEvent 添加新的 javascript 监听器。如果 animatedEvent 是一个 javascript 监听器,它将把 2 个监听器合并为一个,如果 animatedEvent 是 null/undefined,它将直接分配 javascript 监听器。尽可能直接使用值。


unforkEvent()​

React JSX
static unforkEvent(event: AnimatedEvent, listener: Function);

start()​

React TSX
static start(callback?: (result: {finished: boolean}) => void);

通过在动画上调用 start() 来启动动画。start() 接受一个完成回调,该回调将在动画完成运行或动画因在完成之前调用 stop() 而完成时调用。

参数:

名称类型必填描述
callback(result: {finished: boolean}) => void否动画正常完成运行后或动画因在完成之前调用 stop() 而完成时将调用的函数

带回调的启动示例:

React TSX
Animated.timing({}).start(({finished}) => {
/* 完成回调 */
});

stop()​

React TSX
static stop();

停止任何正在运行的动画。


reset()​

React TSX
static reset();

停止任何正在运行的动画并将值重置为其原始值。

属性​

Value​

用于驱动动画的标准值类。通常在类组件中使用 useAnimatedValue(0); 或 new Animated.Value(0); 进行初始化。

您可以在单独的 页面 上了解更多关于 Animated.Value API 的信息。


ValueXY​

用于驱动 2D 动画(例如平移手势)的 2D 值类。

您可以在单独的 页面 上了解更多关于 Animated.ValueXY API 的信息。


Interpolation​

导出以便在 flow 中使用 Interpolation 类型。


Node​

导出以便于类型检查。所有动画值均派生自此类。


createAnimatedComponent​

使任何 React 组件可动画化。用于创建 Animated.View 等。


attachNativeEvent​

用于将动画值附加到视图上的事件的命令式 API。如果可能,更推荐使用带有 useNativeDriver: true 的 Animated.event。