3

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>
  );
}
MouseWarrior
  • 391
  • 4
  • 19
  • 1
    remove the viewBox perhaps. The viewBox attribute is what causes SVG to resize with the content size. – Robert Longson May 16 '23 at 04:41
  • That unfortunately made things worse – MouseWarrior May 16 '23 at 05:00
  • Strange, the snack throws an exception when running the project: Unable to resolve module 'react-native-web.js' – VonC May 18 '23 at 08:19
  • hmm make sure Expo version 47 is selected in the bottom right – MouseWarrior May 18 '23 at 13:32
  • @MouseWarrior And I run it using the "Web" device, but not resize is visible then. I only see exception when trying to run as Android or iOS. – VonC May 18 '23 at 13:51
  • You must hit the pop out arrow in the top right corner of the emulator to get the resizable option as described in my original post. 'If you run the snack, please hit the pop out arrow in the web emulator to change window sizes to see the issue.' – MouseWarrior May 18 '23 at 14:58

1 Answers1

1

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.

Rohit S K
  • 1,178
  • 3
  • 13
  • I need to update my post as I am realizing the answer I am looking for is more specific. I apologize, I would like the height to be static. You see how as you make the window larger/smaller, the height changes as well. I would like the height to remain the same regardless of window size – MouseWarrior May 18 '23 at 15:34
  • 1
    in that case add ```preserveAspectRatio="none"``` prop to Svg component like [this](https://snack.expo.dev/34H2X0Au6). Now it has fixed height and dynamic width. – Rohit S K May 19 '23 at 04:14