跳到主要內容

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() 時調用。

參數

名稱類型必填描述
callback(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