我使用React Native和Expo,在最新版本的SDK 49中,他们提到我们可以使用react-native-reanimated对BlurView强度进行动画处理。问题是它不起作用。
这是我的主屏幕,其中有 ScrollView
import { Dimensions, View } from "react-native";
import Animated, {
useAnimatedScrollHandler,
useSharedValue,
} from "react-native-reanimated";
const { height } = Dimensions.get("window");
const HomeScreen = () => {
const scrollOffset = useSharedValue(0);
const scrollHandler = useAnimatedScrollHandler({
onScroll: (event) => {
scrollOffset.value = event.contentOffset.y;
},
});
return (
<View className="flex-1 bg-white">
<View className="absolute w-full z-10">
<Headerbar scrollOffset={scrollOffset} />
</View>
<Animated.ScrollView
onScroll={scrollHandler}
showsVerticalScrollIndicator={false}
snapToAlignment={"start"}
snapToInterval={height * 0.22}
decelerationRate={"fast"}
>
<Header scrollOffset={scrollOffset} />
<View className="pt-5 pb-2 rounded-t-2xl -mt-4 bg-white">
<CategoryList />
</View>
<View className="py-5 bg-[#F7F7F7] rounded-t-2xl">
<BestSales />
</View>
</Animated.ScrollView>
</View>
);
};
这是我的标题,其中有我想要设置动画的 BlurView
import { BlurView } from "expo-blur";
import React from "react";
import { Text, TouchableNativeFeedback, View } from "react-native";
import {
Extrapolation,
SharedValue,
interpolate,
} from "react-native-reanimated";
import { useSafeAreaInsets } from "react-native-safe-area-context";
const Headerbar: React.FC<HeaderbarProps> = ({ scrollOffset }) => {
const { top } = useSafeAreaInsets();
const blurIntensity = interpolate(
scrollOffset.value,
[0, 172],
[0, 50],
Extrapolation.CLAMP
);
return (
<BlurView intensity={blurIntensity} style={{ flex: 1 }}>
<View
style={[
{
paddingTop: top * 1.2,
paddingBottom: top * 0.4,
paddingHorizontal: 16,
},
]}
/>
</BlurView>
)
我的缺点是什么?
我找到了解决方案,
默认情况下,BlurView 是不可动画的(我以为默认情况下是这样的)。因此,要使用 react-native-reanimated 为 BlurView 制作动画,您需要使用
Animated.createAnimatedComponent(BlurView)
创建 AnimatedBlurView 组件,但在此阶段您无法制作动画。最后一步是使用 useAnimatedProps 创建animatedProps,并将它们作为 props 传递给 AnimatedBlurView
const App = ()=>{
const AnimatedBlurView = Animated.createAnimatedComponent(BlurView);
const animatedProps = useAnimatedProps(() => {
const intensity = interpolate(
scrollY.value,
[0, 150, 172],
[0, 0, 50],
Extrapolation.CLAMP
);
return {
intensity,
};
});
return (
<AnimatedBlurView animatedProps={animatedProps} style={{ flex: 1 }}>
<View
style={{
paddingTop: top * 1.2,
paddingBottom: top * 0.4,
paddingHorizontal: 16,
}}
>
</AnimatedBlurView>
)
}
您可以使用 react-native-animated-blur-view 库来动画模糊视图强度。
只需传递
blurStart
、blurEnd
、animationDuration
属性并通过 ref 调用 start
方法即可启动动画。这个比 https://github.com/Kureev/react-native-blur 库运行得更流畅。如果模糊量为 1,原生模糊效果视图有时会添加白色叠加事件。
例如
const blurViewRef = useRef<AnimatedBlurViewMethods>();
useEffect(() => {
blurViewRef.current?.start(true);
}, []);
return (
<View style={styles.container}>
<Text>React Native Animated Blur View</Text>
<AnimatedBlurView
ref={blurViewRef}
style={StyleSheet.absoluteFillObject}
blurStart={10}
blurEnd={20}
animationDuration={2}
/>
</View>
);
它还支持
gradient
选项。