如何在React Native/Expo中实现带模糊效果的遮罩布局?
在React Native/Expo中实现地图局部模糊遮罩的方案
针对你遇到的@react-native-masked-view/masked-view不支持半透明遮罩、无法正确显示遮罩后方内容的问题,推荐两种实用方案:
方案一:分块模糊层(兼容性最优)
通过在地图上方放置四个独立的模糊层(上、下、左、右),中间留空露出清晰地图区域,完全规避MaskedView的缺陷,适配Expo和裸React Native项目。
步骤:
- 安装依赖(Expo环境):
expo install expo-blur
裸React Native项目则安装@react-native-community/blur:
npm install @react-native-community/blur # 或 yarn add @react-native-community/blur
- 实现代码:
import React from 'react'; import { View, StyleSheet, Dimensions } from 'react-native'; import MapView from 'react-native-maps'; import { BlurView } from 'expo-blur'; // 裸RN项目替换为import BlurView from '@react-native-community/blur' const MapWithPartialBlur = () => { // 自定义中间清晰区域的尺寸与位置 const clearArea = { width: 300, height: 200, top: 150, left: (Dimensions.get('window').width - 300) / 2, }; return ( <View style={styles.container}> {/* 底层地图 */} <MapView style={styles.map} initialRegion={{ latitude: 37.78825, longitude: -122.4324, latitudeDelta: 0.0922, longitudeDelta: 0.0421, }} /> {/* 模糊遮罩层容器 */} <View style={styles.blurOverlay}> {/* 顶部模糊区域 */} <BlurView style={[styles.blurSection, { height: clearArea.top }]} intensity={80} // 模糊强度,0-100 tint="light" // 模糊色调,可选light/dark/extraLight /> {/* 中间横向区域:左右模糊+中间留空 */} <View style={[styles.middleRow, { height: clearArea.height }]}> <BlurView style={[styles.blurSection, { width: clearArea.left }]} intensity={80} tint="light" /> {/* 中间留空,透出下方地图 */} <View style={{ width: clearArea.width }} /> <BlurView style={[ styles.blurSection, { width: Dimensions.get('window').width - clearArea.left - clearArea.width } ]} intensity={80} tint="light" /> </View> {/* 底部模糊区域 */} <BlurView style={[ styles.blurSection, { height: Dimensions.get('window').height - clearArea.top - clearArea.height } ]} intensity={80} tint="light" /> </View> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1 }, map: { ...StyleSheet.absoluteFillObject }, blurOverlay: { ...StyleSheet.absoluteFillObject }, middleRow: { flexDirection: 'row' }, blurSection: { backgroundColor: 'rgba(255,255,255,0.5)', // 叠加半透明白色,增强遮罩效果 }, }); export default MapWithPartialBlur;
方案二:SVG裁剪模糊层(支持复杂形状)
如果需要圆形、多边形等非矩形的清晰区域,可结合react-native-svg的裁剪功能实现。
步骤:
- 安装依赖:
expo install expo-blur react-native-svg
- 实现代码(圆形清晰区域示例):
import React from 'react'; import { View, StyleSheet, Dimensions } from 'react-native'; import MapView from 'react-native-maps'; import { BlurView } from 'expo-blur'; import { Svg, Defs, ClipPath, Rect, Circle } from 'react-native-svg'; const MapWithCircularClearArea = () => { const { width: windowWidth, height: windowHeight } = Dimensions.get('window'); const clearCircleRadius = 100; // 圆形清晰区域半径 return ( <View style={styles.container}> <MapView style={styles.map} initialRegion={{ latitude: 37.78825, longitude: -122.4324, latitudeDelta: 0.0922, longitudeDelta: 0.0421, }} /> {/* 模糊遮罩容器 */} <View style={styles.blurContainer}> {/* SVG定义裁剪路径:全屏矩形减去中间圆形 */} <Svg style={StyleSheet.absoluteFillObject}> <Defs> <ClipPath id="clearAreaClip"> <Rect x="0" y="0" width={windowWidth} height={windowHeight} /> <Circle cx={windowWidth/2} cy={windowHeight/2} r={clearCircleRadius} /> </ClipPath> </Defs> </Svg> {/* 应用裁剪的模糊层 */} <BlurView style={{ ...StyleSheet.absoluteFillObject, clipPath: 'url(#clearAreaClip)', }} intensity={80} tint="light" /> {/* 叠加半透明白色层,增强遮罩效果 */} <View style={{ ...StyleSheet.absoluteFillObject, clipPath: 'url(#clearAreaClip)', backgroundColor: 'rgba(255,255,255,0.5)', }} /> </View> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1 }, map: { ...StyleSheet.absoluteFillObject }, blurContainer: { ...StyleSheet.absoluteFillObject }, }); export default MapWithCircularClearArea;
注意事项:
- 方案一的分块方式兼容性最好,无平台适配问题;
- 方案二的
clipPath在Android部分版本可能需要调整,Expo环境下支持更稳定; - 可通过调整
intensity(模糊强度)和backgroundColor的透明度,匹配原型图的视觉效果。
内容的提问来源于stack exchange,提问作者Fez Vrasta
相关产品推荐
相关产品推荐

