Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native - create curved edge for shape

Summary of problem

I have the following bottom navigation bar for an app I'm building and I'm not sure how to style it since it's more complex than anything I've styled in the past. I'm having trouble styling the curved top edge of the white part and the area between the blue/green circle and the white part.

I included what the navigation bar should look like from the mockups since one of them seems to blend in. The black background above the white part between the green/blue circle and the white part shouldn't be styled with this Navigation bar, that should be the background seen behind the navigation bar.

Any help would be greatly appreciated!

Navigation Bar Example Summary Code

  <View style={styles.container}>
  </View>

container: {
    width: windowWidth,
    height: windowHeight * 0.1020935961,
    backgroundColor: "white",
    flexDirection: "row",
    justifyContent: "space-around",
    borderTopLeftRadius: -50,
    borderTopRightRadius: -50
  }

Full Code

const CustomTabNav = () => (
  <View style={styles.container}>
    <TouchableOpacity
      style={styles.instant}
      onPress={() => {
        NavigationService.navigate("Home");
      }}
    >
      <Image
        style={styles.homeImage}
        source={require("~/assets/images/homeIcon.png")}
      />
    </TouchableOpacity>
    <TouchableOpacity
      style={styles.ovalCopy}
      onPress={() => NavigationService.navigate("Competitions")}
    >
      <LinearGradient
        start={{ x: 0, y: 1 }}
        end={{ x: 1, y: 0 }}
        colors={[buttonGradientBlueColor, buttonGradientGreenColor]}
        style={styles.linearGradient}
      >
        <Image
          style={styles.plusImage}
          source={require("~/assets/images/plus.png")}
        />
      </LinearGradient>
    </TouchableOpacity>
    <TouchableOpacity
      style={styles.instant}
      onPress={() => NavigationService.navigate("Competitions")}
    >
      <Image
        style={styles.instantImage}
        source={require("~/assets/images/competitions.png")}
      />
    </TouchableOpacity>
  </View>
);

const styles = StyleSheet.create({
  container: {
    width: windowWidth,
    height: windowHeight * 0.1020935961,
    backgroundColor: "white",
    flexDirection: "row",
    justifyContent: "space-around",
    borderTopLeftRadius: -50,
    borderTopRightRadius: -50
  },
  homeImage: {
    width: windowWidth * 0.05,
    height: windowWidth * 0.05
  },
  instant: {
    flexDirection: "column",
    // alignSelf: 'center',
    justifyContent: "center"
  },
  instantImage: {
    width: windowWidth * 0.05,
    height: windowWidth * 0.05
  },
  ovalCopy: {
    width: 64,
    height: 64,
  },
  linearGradient: {
    borderRadius: 50, //TODO: make sure this is correct
    width: 64,
    height: 64,
    shadowColor: "#0a0b12cc",
    shadowOffset: {
      width: 0,
      height: -10
    },
    shadowRadius: 60,
    shadowOpacity: 1,
    alignItems: 'center',
    justifyContent: 'center'
  },
  plusImage: {
    width: windowWidth*0.064,
    height: windowWidth*0.064
  }
});
like image 524
bzlight Avatar asked Feb 06 '26 10:02

bzlight


1 Answers

Hey I guess you could do it in a hard way like making a background picture for getting that curvy white background. Or you could superpose 2 "black-grey" views on top of a white view. The first "black-grey" could be one like with a incredible big borderRadius, and second one a 100% circle one slightly bigger than the + button. This is what I mean:

<View style={{ flex: 1, backgroundColor:"white",height: HEIGHT ,width:WIDTH, alignItems: 'center', justifyContent: 'flex-start' }}>
            <View style={{ backgroundColor:"black",borderBottomLeftRadius:WIDTH*10,borderBottomRightRadius:WIDTH*10,height: HEIGHT*.6 ,width:WIDTH*2, alignItems: 'center', justifyContent: 'center' }}>
</View>
            <View style={{ backgroundColor:"black",borderRadius:60,height: 120 ,width:120, marginTop:-60,alignItems: 'center', justifyContent: 'center' }}>
                <View style={{ backgroundColor:"white",borderRadius:40,height: 80 ,width:80 ,alignItems: 'center', justifyContent: 'center' }}>
                    <Icon name="chevron-left" size={30} />
                </View>
            </View>
            <View style={{ backgroundColor:"transparent",height: 120 ,width:WIDTH, marginTop:-60,flexDirection:"row",padding:20, justifyContent: 'space-between' }}>
                <Icon name="chevron-left" size={30} />
                <Icon name="chevron-left" size={30} />
            </View>
    </View>

Screenshoot of what you will get: Screenshoot

like image 133
Ignacio Urpi nachourpi Avatar answered Feb 07 '26 22:02

Ignacio Urpi nachourpi