【React Native】文件翻譯閱讀紀錄 - 指南 - 動畫
facebook open source - React Native
動畫
React Native提供了兩個互補的動畫系統:動畫用於特定值的粒度和交互式控制,以及用於動畫全局佈局事務的LayoutAnimation。
動畫 API
動畫導出四種可動畫組件類型:View,Text,Image 和 ScrollView,但您也可以使用 Animated.createAnimatedComponent() 創建自己的組件類型。
例如,掛載時淡入的容器視圖可能如下所示:
當組件安裝時,不透明度設置為0.然後,在fadeAnim動畫值上啟動緩動動畫,該值將更新每個幀上的所有相關映射(在這種情況下,只是不透明度),因為值動畫為最終值為1。
這是以優化的方式完成的,比調用setState和重新渲染更快。
因為整個配置是聲明性的,所以我們將能夠實現進一步優化,以序列化配置並在高優先級線程上運行動畫。
配置動畫
動畫提供了幾種動畫類型,最常用的是Animated.timing()。它支持使用各種預定義的緩動函數之一隨時間設置值,或者您可以使用自己的。緩動功能通常用於動畫中以傳達物體的逐漸加速和減速。
默認情況下,時間將使用easeInOut曲線,該曲線將逐漸加速傳遞到全速,並通過逐漸減速到停止來結束。您可以通過傳遞緩動參數來指定不同的緩動函數。還支持自定義持續時間甚至動畫開始前的延遲。
例如,如果我們想要在移動到最終位置之前創建一個稍微備份的對象的2秒長動畫:Animated.timing(this.state.xPosition, {
toValue: 100,
easing: Easing.back(),
duration: 2000,
}).start();
撰寫動畫
例如,以下動畫慣性停止,然後在平行旋轉時彈回:Animated.sequence([
// decay, then spring to start and twirl
Animated.decay(position, {
// coast to a stop
velocity: {x: gestureState.vx, y: gestureState.vy}, // velocity from gesture release
deceleration: 0.997,
}),
Animated.parallel([
// after decay, in parallel:
Animated.spring(position, {
toValue: {x: 0, y: 0}, // return to start
}),
Animated.timing(twirl, {
// and twirl
toValue: 360,
}),
]),
]).start(); // start the sequence group
您可以在Animated API參考的Composing animations部分找到完整的合成方法列表。
撰寫動畫
在某些情況下,動畫值需要反轉另一個動畫值進行計算。一個例子是反轉比例(2x - > 0.5x):const a = new Animated.Value(1);
const b = Animated.divide(1, a);
Animated.spring(a, {
toValue: 2,
}).start();
插值
將0-1範圍轉換為0-100範圍的簡單映射將是:value.interpolate({
inputRange: [0, 1],
outputRange: [0, 100],
});
style={{
opacity: this.state.fadeAnim, // Binds directly
transform: [{
translateY: this.state.fadeAnim.interpolate({
inputRange: [0, 1],
outputRange: [150, 0] // 0 : 150, 0.5 : 75, 1 : 0
}),
}],
}}
value.interpolate({
inputRange: [-300, -100, 0, 100, 101],
outputRange: [300, 0, 1, 0, 0],
});
Input | Output
------|-------
-400| 450
-300| 300
-200| 150
-100| 0
-50| 0.5
0| 1
50| 0.5
100| 0
101| 0
200| 0
value.interpolate({
inputRange: [0, 360],
outputRange: ['0deg', '360deg'],
});
跟踪動態值
Animated.spring(follower, {toValue: leader}).start();
Animated.timing(opacity, {
toValue: pan.x.interpolate({
inputRange: [0, 300],
outputRange: [1, 0],
}),
}).start();
跟踪手勢
例如,在使用水平滾動手勢時,您將執行以下操作以將event.nativeEvent.contentOffset.x映射到scrollX(Animated.Value): onScroll={Animated.event(
// scrollX = e.nativeEvent.contentOffset.x
[{ nativeEvent: {
contentOffset: {
x: scrollX
}
}
}]
)}
onPanResponderMove={Animated.event(
[null, // ignore the native event
// extract dx and dy from gestureState
// like 'pan.x = gestureState.dx, pan.y = gestureState.dy'
{dx: pan.x, dy: pan.y}
])}
響應當前動畫值
使用本機驅動程序
使用本機驅動程序進行正常動畫非常簡單。只需在啟動時將useNativeDriver:true添加到動畫配置中即可。Animated.timing(this.state.animatedValue, {
toValue: 1,
duration: 500,
useNativeDriver: true, // <-- Add this
}).start();
本機驅動程序也適用於Animated.event。這對於跟隨滾動位置的動畫特別有用,因為沒有本機驅動程序,由於React Native的異步性質,動畫將始終在手勢後面運行一個幀。<Animated.ScrollView // <-- Use the Animated ScrollView wrapper
scrollEventThrottle={1} // <-- Use 1 here to make sure no events are ever missed
onScroll={Animated.event(
[
{
nativeEvent: {
contentOffset: {y: this.state.animatedValue},
},
},
],
{useNativeDriver: true} // <-- Add this
)}>
{content}
</Animated.ScrollView>
注意事項
動畫運行時,它可以防止VirtualizedList組件呈現更多行。如果您需要在用戶滾動列表時運行長動畫或循環動畫,則可以在動畫的配置中使用isInteraction:false來防止此問題。
記住
<Animated.View
style={{
transform: [
{scale: this.state.scale},
{rotateY: this.state.rotateY},
{perspective: 1000}, // without this line this Animation will not render on Android while working fine on iOS
],
}}
/>
其他例子
LayoutAnimation
API
請注意,儘管LayoutAnimation功能非常強大並且非常有用,但它提供的控制遠遠少於動畫和其他動畫庫,因此如果無法使LayoutAnimation執行您想要的操作,則可能需要使用其他方法。
請注意,為了使其在Android上運行,您需要通過UIManager設置以下標誌:UIManager.setLayoutAnimationEnabledExperimental &&
UIManager.setLayoutAnimationEnabledExperimental(true);
補充資料
requestAnimationFrame
setNativeProps
我們可以在Rebound示例中使用它來更新比例 - 如果我們正在更新的組件是深度嵌套的並且尚未使用shouldComponentUpdate進行優化,這可能會有所幫助。
如果您發現您的動畫具有丟幀(執行低於每秒60幀),請查看使用setNativeProps或shouldComponentUpdate來優化它們。或者您可以使用useNativeDriver選項在UI線程而不是JavaScript線程上運行動畫。您可能還希望使用InteractionManager將任何計算密集型工作推遲到動畫完成之後。您可以使用應用程序開發人員菜單“FPS監視器”工具監視幀速率。
0 意見