如何制作具有模糊效果的蒙版?

问题描述 投票:0回答:3

我试图在 React Native/Expo 中重现以下布局,我发现

@react-native-masked-view/masked-view
乍一看似乎可以满足我的需求。

我需要一张地图(我正在使用react-native-maps)并用一些模糊的半透明白色视图覆盖它的一部分。

但我意识到它不能正确支持半透明蒙版,因为如果我使用它们,我放在模糊区域顶部的任何内容也会继承蒙版透明度,即使位于 MAskedView 组件之外也是如此。

而且,它似乎不支持模糊蒙版后面的内容。

我如何在 React Native 上重现这个?

下面您可以看到一个模型来了解我想要实现的目标。

mockup

react-native
3个回答
2
投票

我几乎已经达到了你所需要的。几乎是因为 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;

这是截图。

enter image description here

更新

正如 Nikolas Charalambidis 所指出的,这个解决方案存在一个缺陷。背景不模糊,所以这是一个不完整的解决方案。我希望有人能提出更好的解决方案,或者我们等待react-native-svg支持过滤器或@react-native-community/blur来使用地图。


0
投票

你问的并不容易。无论如何,我找到了一种接近它的方法:

    <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> 

这会渲染出上半部分模糊、下半部分清晰的地图。也许只要稍微玩弄一下风格,就能得到你想要的!


0
投票

在多边形上使用孔参数

 <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
  />

此代码涵盖土耳其(伊斯坦布尔除外)。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.