react-native-reanimated系列(一)
react-native-reanimated系列(二)
react-native-reanimated系列(三)
react-native-reanimated系列(四)
事件
為了使APP對用戶體驗更自然,我們使用動畫來平滑用戶與APP用戶界面的交互。
處理手勢事件
const EventsExample = () => {
const pressed = useSharedValue(false);
const eventHandler = useAnimatedGestureHandler({
onStart: (event, ctx) => {
pressed.value = true;
},
onEnd: (event, ctx) => {
pressed.value = false;
},
});
const uas = useAnimatedStyle(() => {
return {
backgroundColor: pressed.value ? '#FEEF86' : '#001972',
transform: [{ scale: withSpring(pressed.value ? 1.2 : 1) }],
};
});
return (
<TapGestureHandler onGestureEvent={eventHandler}>
<Animated.View style={[styles.ball, uas]} />
</TapGestureHandler>
);
};

touch-final.gif
處理連續(xù)手勢
const EventsExample = () => {
const startingPosition = 100;
const x = useSharedValue(startingPosition);
const y = useSharedValue(startingPosition);
const pressed = useSharedValue(false);
const eventHandler = useAnimatedGestureHandler({
onStart: (event, ctx) => {
pressed.value = true;
ctx.startX = x.value;
ctx.startY = y.value;
},
onActive: (event, ctx) => {
x.value = ctx.startX + event.translationX;
y.value = ctx.startY + event.translationY;
},
onEnd: (event, ctx) => {
pressed.value = false;
x.value = withSpring(startingPosition);
y.value = withSpring(startingPosition);
},
});
const uas = useAnimatedStyle(() => {
return {
backgroundColor: pressed.value ? '#FEEF86' : '#001972',
transform: [{ translateX: x.value }, { translateY: y.value }],
};
});
return (
<PanGestureHandler onGestureEvent={eventHandler}>
<Animated.View style={[styles.ball, uas]} />
</PanGestureHandler>
);
};
當啟動新手勢時,事件中攜帶的轉(zhuǎn)換值是相對于手勢的開始位置而言的。結(jié)果,我們不能直接將手勢轉(zhuǎn)換映射到屏幕上的視圖偏移。解決方案是設(shè)置一個可以保持視圖起始偏移量的臨時狀態(tài)。為此,我們可以使用提供給每個手勢處理程序worklets的上下文參數(shù)。上下文只是在所有回調(diào)之間共享的JavaScript對象。換句話說,所有定義為手勢處理程序回調(diào)的方法都將接收相同的上下文對象實例。

final.gif
遷移
-
interpolate重命名interplolateNode
如果您使用的是類成員方法AnimatedValue.interpolate,則無需更改。 -
Easing重命名EasingNode
常見問題解決方案
TypeError: Cannot convert undefined value to object on someVariable._closure
清除metro緩存,確保安裝了babel插件
watchman watch-del-all
yarn start --reset-cache
undefined is not an object (evaluating '_toConsumableArray(Array(length)).map')
worklet不支持擴展運算符(...array),可以使用以下方法替代:
- 拷貝數(shù)組
array.slice() -
[...Array(length)].map的慣用語法Array(length).fill().map() - 合并對象
Object.assign() - 函數(shù)里傳遞參數(shù)
func.apply()