跳到主要内容

Animated

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

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

不要直接修改动画值。您可以使用 useRef Hook 来返回一个可变 ref 对象。此 ref 对象的 current 属性被初始化为给定的参数,并在组件的整个生命周期内保持不变。

示例

以下示例包含一个 View,它将根据动画值 fadeAnim 淡入和淡出

请参阅 动画 指南,查看 Animated 实际应用的其他示例。

概述

Animated 中有两种可用的值类型

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

配置动画

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

在大多数情况下,您将使用 timing()。默认情况下,它使用对称的 easeInOut 曲线,该曲线传达对象逐渐加速到全速,并以逐渐减速到停止结束。

使用动画

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

tsx
Animated.timing({}).start(({finished}) => {
/* completion callback */
});

使用原生驱动

通过使用原生驱动,我们在启动动画之前将有关动画的所有内容发送到原生,从而允许原生代码在 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)

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

参考

方法

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

decay()

tsx
static decay(value, config): CompositeAnimation;

根据衰减系数将值从初始速度动画到零。

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

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

timing()

tsx
static timing(value, config): CompositeAnimation;

沿定时缓动曲线动画值。Easing 模块有大量预定义的曲线,或者您可以使用自己的函数。

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

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

spring()

tsx
static spring(value, config): CompositeAnimation;

根据基于 阻尼谐波振荡 的解析弹簧模型动画值。跟踪速度状态以在 toValue 更新时创建流畅的运动,并且可以链接在一起。

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

请注意,您只能定义弹跳/速度、张力/摩擦或刚度/阻尼/质量中的一个,但不能超过一个

摩擦/张力或弹跳/速度选项与 Facebook PopReboundOrigami 中的弹簧模型匹配。

  • friction:控制“弹跳”/过冲。默认值 7。
  • tension:控制速度。默认值 40。
  • speed:控制动画速度。默认值 12。
  • bounciness:控制弹跳。默认值 8。

将刚度/阻尼/质量指定为参数使 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()

tsx
static add(a: Animated, b: Animated): AnimatedAddition;

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


subtract()

tsx
static subtract(a: Animated, b: Animated): AnimatedSubtraction;

创建一个通过从第一个 Animated 值中减去第二个 Animated 值组成的新 Animated 值。


divide()

tsx
static divide(a: Animated, b: Animated): AnimatedDivision;

创建一个通过将第一个 Animated 值除以第二个 Animated 值组成的新 Animated 值。


multiply()

tsx
static multiply(a: Animated, b: Animated): AnimatedMultiplication;

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


modulo()

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

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


diffClamp()

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

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

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


delay()

tsx
static delay(time: number): CompositeAnimation;

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


sequence()

tsx
static sequence(animations: CompositeAnimation[]): CompositeAnimation;

按顺序启动一系列动画,等待每个动画完成,然后再启动下一个动画。如果当前正在运行的动画已停止,则不会启动后续动画。


parallel()

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

同时启动一系列动画。默认情况下,如果其中一个动画停止,则所有动画都将停止。您可以使用 stopTogether 标志覆盖此行为。


stagger()

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

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


loop()

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

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

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

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

event()

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

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

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()

jsx
static forkEvent(event: AnimatedEvent, listener: Function): AnimatedEvent;

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


unforkEvent()

jsx
static unforkEvent(event: AnimatedEvent, listener: Function);

start()

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

通过在动画上调用 start() 来启动动画。start() 接受一个完成回调,该回调将在动画完成时或动画完成是因为在完成之前对其调用了 stop() 时调用。

参数

名称类型必需描述
回调(result: {finished: boolean}) => void动画正常运行结束后或动画完成是因为在完成之前对其调用了 stop() 时将调用的函数

带回调的启动示例

tsx
Animated.timing({}).start(({finished}) => {
/* completion callback */
});

stop()

tsx
static stop();

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


reset()

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。如果可能,请首选使用 Animated.eventuseNativeDriver: true