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 是一個物件,可能具有以下選項。
請注意,您只能定義彈跳性/速度、張力/摩擦力或剛度/阻尼/質量中的一個,但不能超過一個
摩擦力/張力或彈跳性/速度選項與 Facebook Pop
、Rebound 和 Origami 中的彈簧模型相符。
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()
static add(a: Animated, b: Animated): AnimatedAddition;
建立一個新的 Animated 值,該值由兩個相加在一起的 Animated 值組成。
subtract()
static subtract(a: Animated, b: Animated): AnimatedSubtraction;
建立一個新的 Animated 值,該值通過從第一個 Animated 值中減去第二個 Animated 值來組成。
divide()
static divide(a: Animated, b: Animated): AnimatedDivision;
建立一個新的 Animated 值,該值通過將第一個 Animated 值除以第二個 Animated 值來組成。
multiply()
static multiply(a: Animated, b: Animated): AnimatedMultiplication;
建立一個新的 Animated 值,該值由兩個相乘在一起的 Animated 值組成。
modulo()
static modulo(a: Animated, modulus: number): AnimatedModulo;
建立一個新的 Animated 值,該值是所提供的 Animated 值的(非負數)模數
diffClamp()
static diffClamp(a: Animated, min: number, max: number): AnimatedDiffClamp;
建立一個新的 Animated 值,該值限制在 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。它允許將新的 javascript 監聽器添加到現有的 AnimatedEvent
。如果 animatedEvent
是 javascript 監聽器,它將把 2 個監聽器合併為一個,如果 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
匯出以在 flow 中使用 Interpolation 類型。
Node
匯出以便於類型檢查。所有動畫值都源自此類別。
createAnimatedComponent
使任何 React 組件都可動畫化。用於建立 Animated.View
等。
attachNativeEvent
命令式 API,用於將動畫值附加到視圖上的事件。如果可能,請優先使用 Animated.event
和 useNativeDriver: true
。