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时,框架不会等待上一个动画完成,而是会立即从上一个动画的当前位置开始进行新的过渡。
如果想要在上一个动画完成后再开始下一个动画,可以使用上一个动画完成的回调来进行操作。
如果想要在开始一个新动画之前取消当前正在运行的动画,可以使用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
分别在起点,终点或两端调整时序曲线就足够了。Timing动画的默认持续时间为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动画不将持续时间作为参数,而是由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" />
</>
);
}
twosprings.gif
动画修饰器
Reanimated目前有三个修饰器:withDelay
、withSequence
和withRepeat
。
-
withDelay
修饰的动画以给定的延迟开始 -
withSequence
修饰的动画依次开始运行 -
withRepeat
修饰的动画重复运行几次
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)
}}
/>
</>
);
}
上面代码中,第一个参数表示目标角度10,第二个参数表示重复6次,第三个参数反转标志为true表示动画每隔一个重复反向运行。
上面的代码使视图旋转仅在0到10度之间进行。 为了使视图也向左摆动,可以从-10开始并转到10度。 但是我们不能仅将初始值更改为-10,因为在这种情况下,矩形将从一开始就倾斜。 解决此问题的一种方法是使用
withSequence
修饰符,并从0开始,将第一个动画执行到-10,然后将视图从-10摆动到10几次,最后从-10变为0。
rotation.value = withSequence(
withTiming(-10, { duration: 50 }),
withRepeat(withTiming(10, { duration: 100 }), 6, true),
withTiming(0, { duration: 50 })
);
wobble.gif
网友评论