我试图在 React Native/Expo 中重现以下布局,我发现
@react-native-masked-view/masked-view
乍一看似乎可以满足我的需求。
我需要一张地图(我正在使用react-native-maps)并用一些模糊的半透明白色视图覆盖它的一部分。
但我意识到它不能正确支持半透明蒙版,因为如果我使用它们,我放在模糊区域顶部的任何内容也会继承蒙版透明度,即使位于 MAskedView 组件之外也是如此。
而且,它似乎不支持模糊蒙版后面的内容。
我如何在 React Native 上重现这个?
下面您可以看到一个模型来了解我想要实现的目标。
我几乎已经达到了你所需要的。几乎是因为 react-native-svg 目前不支持过滤器,并且 @react-native-community/blur 不能与 react-native-maps 一起使用,正如 Rohit S K 在评论中指出的那样。我们使用 SVG 形状。只要了解 mozilla 的这个cubic cruves,你就可以根据你的需要更好地控制它。 这是我的
App.tsx
文件的代码
import React, {JSX} from 'react';
import {SafeAreaView, StatusBar, StyleSheet, View} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import {BlurView} from '@react-native-community/blur';
import MapView from 'react-native-maps';
import Svg, {Path} from 'react-native-svg';
function App(): JSX.Element {
return (
<SafeAreaView style={styles.safeArea}>
<StatusBar
backgroundColor="rgba(245,245,245,0.3)"
barStyle={'dark-content'}
/>
<MapView
style={styles.mapView}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
<View style={styles.svgWrapper}>
<Svg
preserveAspectRatio="xMinYMax slice"
height="100%"
width="100%"
viewBox="0 0 100 100">
<Path
d="M 0 85 C 20 60, 80 60, 100 85 L 100 0 0 0"
fill="rgba(255,255,255,0.5)"
/>
<Path
d="M 0 85 C 20 60, 80 60, 100 85"
stroke="rgba(221,221,221,1)"
strokeWidth={0.5}
fill="transparent"
/>
</Svg>
<BlurView
style={styles.blurView}
blurType="light"
blurAmount={10}
reducedTransparencyFallbackColor="white"
/>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
safeArea: {
backgroundColor: Colors.lighter,
height: '100%',
position: 'relative',
},
mapView: {
minHeight: '100%',
},
blurView: {
position: 'absolute',
top: 0,
right: 0,
left: 0,
bottom: 0,
},
svgWrapper: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
width: '100%',
height: '55%',
aspectRatio: 1,
},
});
export default App;
这是截图。
正如 Nikolas Charalambidis 所指出的,这个解决方案存在一个缺陷。背景不模糊,所以这是一个不完整的解决方案。我希望有人能提出更好的解决方案,或者我们等待react-native-svg支持过滤器或@react-native-community/blur来使用地图。
你问的并不容易。无论如何,我找到了一种接近它的方法:
<MapView
style={styles.mapStyle}
initialRegion={initRegion}
>
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<BlurView intensity={50} style={[StyleSheet.absoluteFill]}></BlurView>
</View>
<View
style={{
flex: 1,
backgroundColor: "transparent",
}}
></View>
</View>
</MapView>
这会渲染出上半部分模糊、下半部分清晰的地图。也许只要稍微玩弄一下风格,就能得到你想要的!
在多边形上使用孔参数
<Polygon
holes={[
[
{ latitude: 41.3242, longitude: 28.6597 }, // North-West
{ latitude: 41.3291, longitude: 28.7604 }, // Northern area
{ latitude: 41.2687, longitude: 28.9809 }, // North-East
{ latitude: 41.0876, longitude: 29.2364 }, // East (Black Sea region)
{ latitude: 40.9718, longitude: 29.0972 }, // South-East (Asian side)
{ latitude: 40.9232, longitude: 29.0258 }, // South-East, closer to Bosphorus
{ latitude: 40.888, longitude: 29.0063 }, // South, Asian side
{ latitude: 40.8571, longitude: 28.9422 }, // South-West, near Avcılar
{ latitude: 40.9855, longitude: 28.7604 }, // South-West of European side
{ latitude: 41.1036, longitude: 28.648 }, // Return to North-West
],
]}
strokeColor={Platform.OS === "ios" ? "white" : "black"}
coordinates={[
{ latitude: 43.0, longitude: 25.0 }, // North-West
{ latitude: 43.0, longitude: 46.0 }, // North-East
{ latitude: 35.0, longitude: 46.0 }, // South-East
{ latitude: 35.0, longitude: 25.0 },
]}
//strokeColor="transparent" // No border
fillColor="black" // Dark color to simulate fog
/>
此代码涵盖土耳其(伊斯坦布尔除外)。