react-native-reanimated系列(一)
react-native-reanimated系列(二)
react-native-reanimated系列(三)
動畫
Reanimated提供了許多動畫修飾器以及如何自定義動畫的方法。
useAnimatedStyle
Shared Value過渡不是啟動和運行動畫的唯一方法,還可以直接在 useAnimatedStyle中指定動畫過渡。
import Animated, { useSharedValue, useAnimatedStyle } from 'react-native-reanimated';
function Box() {
const offset = useSharedValue(0);
const animatedStyles = useAnimatedStyle(() => {
return {
transform: [
{
translateX: withSpring(offset.value * 255),
},
],
};
});
return (
<>
<Animated.View style={[styles.box, animatedStyles]} />
<Button onPress={() => (offset.value = Math.random())} title="Move" />
</>
);
}
中斷動畫更新
更新Shared Value時,框架不會等待上一個動畫完成,而是會立即從上一個動畫的當(dāng)前位置開始進行新的過渡。
如果想要在上一個動畫完成后再開始下一個動畫,可以使用上一個動畫完成的回調(diào)來進行操作。
如果想要在開始一個新動畫之前取消當(dāng)前正在運行的動畫,可以使用cancelAnimation方法。
自定義動畫
Reanimated目前有三個動畫輔助方法:withTiming、withSpring和withDecay。
<Button
onPress={() => {
offset.value = withSpring(Math.random(), {}, (finished) => {
if (finished) {
console.log("ANIMATION ENDED");
} else {
console.log("ANIMATION GOT CANCELLED");
}
});
}}
title="Move"
/>
Timing
Reanimated包提供了Easing.bezier方法,因此可以使用貝塞爾曲線來描述緩動。通常使用Easing.in,Easing.out或Easing.inOut分別在起點,終點或兩端調(diào)整時序曲線就足夠了。Timing動畫的默認持續(xù)時間為300毫秒,默認緩動為in-Out二次曲線(Easing.inOut(Easing.quad))。

import { Easing, withTiming } from 'react-native-reanimated';
offset.value = withTiming(0, {
duration: 500,
easing: Easing.out(Easing.exp),
});
Spring
與Timing動畫不同,Spring動畫不將持續(xù)時間作為參數(shù),而是由spring物理特性、初始速度和行進距離決定。
import Animated, {
withSpring,
useAnimatedStyle,
useSharedValue,
} from 'react-native-reanimated';
function Box() {
const offset = useSharedValue(0);
const defaultSpringStyles = useAnimatedStyle(() => {
return {
transform: [{ translateX: withSpring(offset.value * 255) }],
};
});
const customSpringStyles = useAnimatedStyle(() => {
return {
transform: [
{
translateX: withSpring(offset.value * 255, {
damping: 20,
stiffness: 90,
}),
},
],
};
});
return (
<>
<Animated.View style={[styles.box, defaultSpringStyles]} />
<Animated.View style={[styles.box, customSpringStyles]} />
<Button onPress={() => (offset.value = Math.random())} title="Move" />
</>
);
}

動畫修飾器
Reanimated目前有三個修飾器:withDelay、withSequence和withRepeat。
-
withDelay修飾的動畫以給定的延遲開始 -
withSequence修飾的動畫依次開始運行 -
withRepeat修飾的動畫重復(fù)運行幾次
import Animated, { useSharedValue, useAnimatedStyle } from 'react-native-reanimated';
function WobbleExample(props) {
const rotation = useSharedValue(0);
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [{ rotateZ: `${rotation.value}deg` }],
};
});
return (
<>
<Animated.View style={[styles.box, animatedStyle]} />
<Button
title="wobble"
onPress={() => {
rotation.value = withRepeat(withTiming(10), 6, true)
}}
/>
</>
);
}
上面代碼中,第一個參數(shù)表示目標角度10,第二個參數(shù)表示重復(fù)6次,第三個參數(shù)反轉(zhuǎn)標志為true表示動畫每隔一個重復(fù)反向運行。

上面的代碼使視圖旋轉(zhuǎn)僅在0到10度之間進行。 為了使視圖也向左擺動,可以從-10開始并轉(zhuǎn)到10度。 但是我們不能僅將初始值更改為-10,因為在這種情況下,矩形將從一開始就傾斜。 解決此問題的一種方法是使用
withSequence修飾符,并從0開始,將第一個動畫執(zhí)行到-10,然后將視圖從-10擺動到10幾次,最后從-10變?yōu)?。
rotation.value = withSequence(
withTiming(-10, { duration: 50 }),
withRepeat(withTiming(10, { duration: 100 }), 6, true),
withTiming(0, { duration: 50 })
);
