Search code examples
react-nativesvgexporeact-native-web

How can I render an svg to look the same dynamically across different window sizes?


Using react-native, expo, and react-native-svg I have rendered an svg in my web application. Unfortunately I am struggling to get the svg to remain the same look throughout changing the web applications window size.

The goal was to create a 'wavy' header. I have included a snack here that reproduces my exact issue as well as some code below. If you run the snack, please hit the pop out arrow in the web emulator to change window sizes to see the issue.

How can I render an svg to look the same dynamically across different window sizes?

EDIT 1:: I realized that the answer I am looking for requires the height to be static. I would like the width to always be the width of the window while the height is a constant and does not change regardless of screen size.

Thank you for any insight at all! I appreciate it more than you know.

SvgComponent.js

const SvgComponent = (props) => (
  <View  style={[styles.header,
    {
      transform: [{rotate: '180deg'}],
    },
  ]}>
  <Svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320" {...props}>
    <Path
      fill="#09f"
      d="m0 128 80-10.7C160 107 320 85 480 96c160 11 320 53 480 64s320-11 400-21.3l80-10.7v192H0Z"
    />
  </Svg>
  </View>
)

App.js

export default function App() {
  return (
    <View style={styles.container}>
        <Home/>
        <TopHeader/>
    </View>
  );
}

Home.js

export default function Home() {
  return (
    <View style={styles.container}>
        <Text style={styles.title}>Home</Text>
    </View>
  );
}
const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    height: height,
    width: width
  },
  title: {
    fontSize: 175, 
    color: 'white'
  }
});

TopHeader.js

export default function TopHeader(props) {
  const {menuActivated, switchTabs, setMenuActivated, headerTriggerd, setHeaderTriggered} = props;
  const [FS, setFS] = useState({ "width": Math.min(window.innerWidth), "height": Math.min(window.innerHeight)})
    useEffect(() => {
      window.addEventListener('resize', changeTitleSize);
      return () => {
          window.removeEventListener('resize', changeTitleSize);
      }
    }, []);
    function changeTitleSize(){
      setFS({ "width": Math.min(window.innerWidth), "height": Math.min(window.innerHeight)})
    }
  return (
    <View style={styles.container}>
      <SvgComponent width={FS.width} height={FS.width / 4} />
      <WebsiteHeader />
    </View>
  );
}

Solution

  • Your logic to resize svg is correct but there is issue with your layout, I have updated it in this snack.

    I have moved TabHeader above the Home and removed absolute styling from TabHeader.