跳到主要内容

Animated

Animated 库旨在让动画的构建与维护都更流畅、更强大、也更省心。Animated 关注输入与输出之间的声明式关系、中间可配置的变换过程,以及用于控制基于时间动画执行的 start / stop 方法。

创建动画的核心流程是:先创建一个 Animated.Value,把它绑定到动画组件的一个或多个样式属性上,再通过 Animated.timing() 等动画方法驱动其更新。

note

不要直接修改动画值。你可以使用 useRef Hook 返回一个可变的 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}) => {
/* completion callback */
});

使用原生驱动​

使用原生驱动时,会在动画开始前将动画所需信息一次性发送到原生端。之后动画可在 UI 线程执行,不必每帧经过 bridge。动画启动后,即使 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;

基于衰减系数,让值从初速度逐渐衰减到 0。

config 可包含:

  • velocity:初始速度。必填。
  • deceleration:衰减率。默认 0.997。
  • isInteraction:是否创建 interaction handle。默认 true。
  • useNativeDriver:为 true 时使用原生驱动。必填。

timing()​

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

沿时间缓动曲线执行动画。Easing 模块提供大量预设曲线,也可使用自定义函数。

config 可包含:

  • duration:动画时长(毫秒)。默认 500。
  • easing:定义曲线的缓动函数。默认为 Easing.inOut(Easing.ease)。
  • delay:延迟多久后开始(毫秒)。默认 0。
  • isInteraction:是否创建 interaction handle。默认 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:是否创建 interaction handle。默认 true。
  • useNativeDriver:为 true 时使用原生驱动。必填。

add()​

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

创建一个由两个动画值相加得到的新动画值。


subtract()​

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

创建一个由第一个动画值减去第二个动画值得到的新动画值。


divide()​

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

创建一个由第一个动画值除以第二个动画值得到的新动画值。


multiply()​

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

创建一个由两个动画值相乘得到的新动画值。


modulo()​

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

创建一个新动画值,其值为给定动画值的(非负)取模结果。


diffClamp()​

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

创建一个限制在两值之间的新动画值。它使用“与上一次值的差值”来更新,因此即便当前值已经远离边界,只要变化趋势重新朝边界靠近,也会恢复变化(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)}, // 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()​

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

高级命令式 API,用于“旁路监听”通过 props 传入的动画事件。它可向现有 AnimatedEvent 添加一个新的 JavaScript 监听器。

如果 animatedEvent 本身是 JavaScript 监听器,会合并为一个监听器;如果 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}) => {
/* completion callback */
});

stop()​

React TSX
static stop();

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


reset()​

React TSX
static reset();

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

属性​

Value​

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

Animated.Value 的完整 API 请见单独页面 animatedvalue。


ValueXY​

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

Animated.ValueXY 的完整 API 请见单独页面 animatedvaluexy。


Interpolation​

导出该类型,便于在 Flow 中使用 Interpolation 类型。


Node​

为方便类型检查而导出。所有动画值都派生自此类。


createAnimatedComponent​

可将任意 React 组件转换为可动画组件。用于创建 Animated.View 等。


attachNativeEvent​

用于将动画值以命令式方式绑定到某个视图事件上。若可行,优先使用 Animated.event + useNativeDriver: true。