react-nativetouchableopacitypressable

Is it possible to create React Native precise press-able areas for rounded polygon components?


I want to create a component that is composed of press-able shapes with rounded edges. They will be close together so their press-able areas cannot extend beyond their design or they will overlap. The general idea is triangles with rounded corners that from to make a circle. I have created a mockup of this general design here: enter image description here

The final version will be more precise but in the design you can see that if I just used TouchableOpacity, Button, or Pressable, I will have overlapping press-able areas.

Does there exist a library, exiting GitHub repo that accomplished something similar or some approach that I can use to accomplish this?

Any ideas suggestions appreciated as well.

Thanks!


Solution

  • I think you could give it a try using react-native-svg. I played a bit with that and I made something close to what you need (but yeah, of course, if you spend a bit more time, I'm sure you'll be able to design exactly that).

    This is my triangle component:

    import React from 'react';
    import Svg, { Path } from 'react-native-svg';
    
    type Props = {
        colour: string
        size?: number
        style?: any
    }
    
    const RoundedTriangle = ({ size = 100, colour = 'orange', style}: Props) => {
    
      const onPress = () => {
        console.log('Triangle pressed');
      }
    
      return (
          <Svg style={[style, {backgroundColor: 'transparent'}]}  width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
            <Path
            onPress={onPress}
              d="M50 5
              Q55 5, 57 7
              L92 85
              Q94 90, 89 92
              L11 92
              Q6 90, 8 85
              L43 7
              Q45 5, 50 5
              Z"
              fill={colour}
            />
          </Svg>
      );
    };
    
    export default RoundedTriangle;

    And this is where it's used:

    function App(): React.JSX.Element {
      return (
        <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center' }}>
          <RoundedTriangle colour='green' style={{transform: [{rotate: '30deg',}], left: 40}}/>
          <RoundedTriangle colour='orange' style={{transform: [{rotate: '-30deg'}], left: 0}} />
        </View>
      );
    }

    Hope it helps, at least as a starting point