I have been trying to do something that seemed easy, but I have been trying for a few hours and I can't find the solution.
I have an SVG that needs to be on top of a screen. It came from the designer with these dimensions:
<Svg width="354px" height="190px" viewBox="0 0 354 190">...</Svg>
In React Native, that would go inside of a container, and the SVG needs to take the full width of the screen, which I am taking from:
Dimensions.get("window").width
My problem is, I haven't found a way to scale the SVG to take 100% of the screen width, finding out the correct height (or a way for it to be set automatically), and preserve the aspect ratio. I've tried like a million things, including playing around with the container's aspectRatio style and its height (or not setting the height at all). Whenever I've found some "proportions" that worked, I tried in a different device with different screen width and it didn't look good at all (cropped, smaller than the screen's width, etc).
I feel like the preserveAspectRatio property in the SVG (react-native-svg) is somehow conflicting with the aspectRatio style. And I am totally lost with the preserveAspectRatio, I haven't found a way to make it scale without being cropped.
Does anyone have any idea how to achieve this?
This is my final code, which returns a HeatMap component showing an SVG, but although it has the correct height, part of the SVG is out of the screen from the right (looks cropped because it's too wide):
const windowWidth = Dimensions.get("window").width;
const getSVGRootProps = ({ width, height }) => ({
width: "100%",
height: "100%",
viewBox: `0 0 ${width} ${height}`,
preserveAspectRatio: "xMinYMin meet",
});
const FieldShape = () => {
const width = 354; // Original width
const height = 190; // Original height
const aspectRatio = width / height;
// adjusted height = <screen width> * original height / original width
const calculatedHeight = (windowWidth * height) / width;
const fieldStyles = {
width: windowWidth,
height: calculatedHeight,
aspectRatio,
};
return (
<View style={fieldStyles}>
<Svg {...getSVGRootProps({ windowWidth, calculatedHeight })}>
...
</Svg>
</View>
);
};
const HeatMap = () => {
return <FieldShape />;
};
This is the result: