1

This is what I am trying to do:

enter image description here

I'm trying to put a transparent circle on the map view (like a magnifying glass) with a dark blue overlay on the sides. This is what I have so far (it's purposely black):

enter image description here

import React from 'react';
import {
  StyleSheet,
  Text,
  View,
} from 'react-native';
import MapView from 'react-native-maps';

const GEOFENCE_RANGE = 0.01;

const OrderMap = props => {
  return (
    <View style={[props.style, styles.container]} >
      <MapView style={styles.map}
        scrollEnabled={false}
        initialRegion={{
          latitude: 37.78825,
          longitude: -122.4324,
        }}
      />
      <View style={styles.overlay}>
        <View style={styles.circle}/>
      </View>
    </View>
  )
};

const styles = StyleSheet.create({
  container: {
    position: 'relative',
  },
  map: {
    flex: 1,
  },
  overlay: {
    backgroundColor: 'rgba(21,31,53, 0.5)',
    position: 'absolute',
    top: 0,
    right: 0,
    bottom: 0,
    left: 0,
    alignItems: 'center',
    justifyContent: 'center',
  },
  circle: {
    backgroundColor: 'black', // <---------------------------
    borderRadius: 100,
    alignSelf: 'stretch',
    flex: 1,
    margin: 50,
  }
});

export default OrderMap;

When I try to change styles.overlay to use backgroundColor: 'transparent', it just makes the whole thing dark blue.

Is there a way to do this?

P.S. I'm using react native maps https://github.com/airbnb/react-native-maps

bigpotato
  • 26,262
  • 56
  • 178
  • 334
  • might want to check out http://stackoverflow.com/questions/8286550/transparent-hollow-or-cut-out-circle – Danny Jan 23 '17 at 16:00
  • This cannot be achieved with React Native styling alone. You could either use `react-native-svg`, or write a custom native module for rendering a masked circle with android.graphics/CoreGraphics. I have implemented this before, let me see if I can somehow package it for open source release. – jevakallio Jan 23 '17 at 16:20
  • thanks @jevakallio . i'm starting to look into that package, will let you know how it goes – bigpotato Jan 23 '17 at 16:20
  • 1
    do you have did it yet? I have sample problem. Please share your solution – Hoa.Tran Feb 13 '19 at 10:32

3 Answers3

6

I have tried the above examples but failed to produce any meaningful outcome. So, after a little bit of tinkering, I have managed to solve the issue and able to make a transparent circle with background image. Here is the full working code with screenshot.

Hope this will help someone ending up here.

import React from 'react'
import {
  StyleSheet,
  View,
  ImageBackground,
} from 'react-native';
import { Svg, Defs, Rect, Mask, Circle } from 'react-native-svg';

const SvgCircle = (props) => {
  return (
    <Svg height="100%" width="100%">
      <Defs>
        <Mask id="mask" x="0" y="0" height="100%" width="100%">
          <Rect height="100%" width="100%" fill="#fff" />
          <Circle r="30%" cx="50%" cy="50%"
            fill="black"
          />
        </Mask>
      </Defs>
      <Rect height="100%" width="100%" fill="rgba(0, 0, 0, 0.8)" mask="url(#mask)" fill-opacity="0" />
    </Svg>
  );
}

const App = (props) => {
  return (
    <View style={styles.container}>
      <ImageBackground source={require('./assets/img.jpg')} style={styles.image}>
        <SvgCircle />
      </ImageBackground>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: "column"
  },
  image: {
    flex: 1,
    resizeMode: "cover",
    justifyContent: "center"
  },
  text: {
    color: "grey",
    fontSize: 30,
    fontWeight: "bold"
  }
});

export default App;
Rahul Haque
  • 146
  • 2
  • 8
1

All I could figure out - as an easy way - is to do png with overlay and transparent circle on it.

Here's an example with image as background: https://rnplay.org/apps/mA780Q

Also notice that you need to set pointerEvents={'none'} property for circle image.

Samuli Hakoniemi
  • 18,740
  • 1
  • 61
  • 74
1

you can easily done with my code. i hope this will 100% work for you.

enter image description here

import { Svg, Defs, Rect, Mask, Circle } from 'react-native-svg';
const WrappedSvg = () => (
    <View style={{ aspectRatio: 1 }}>
        <Svg height="100%" width="100%" viewBox="0 0 100 100">
            <Defs>
                <Mask id="mask" x="0" y="0" height="100%" width="100%">
                    <Rect height="100%" width="100%" fill="#fff" />
                    <Circle r="45" cx="50" cy="50" />
                </Mask>
            </Defs>
            <Rect height="100%" width="100%" fill="rgba(0, 0, 0, 0.5)" mask="url(#mask)" fill-opacity="0" />
        </Svg>
    </View>
);

export class index extends Component {
    render() {
        return (
            <View style={{ backgroundColor: '#FFFFFF', flex: 1, justifyContent: 'center', alignItems: 'center' }}>

                <View style={{ width: Dimensions.get('window').width, height: 300, position: 'absolute' }}>
                    <WrappedSvg />
                </View>
            </View>
        );
    }
}

export default index;
Muhammad Numan
  • 23,222
  • 6
  • 63
  • 80