I am trying to put a react-native-svg
element inside of a View
such that it\'s rendered with a certain, fixed aspect ratio, but then scaled to be as la
For my SVG, I was using those provided at https://material.io/resources/icons
What fixed it for me, was to make sure you don't mess with the viewBox
or given values in the Paths
(like I did) but only change the height
and width
to fill and then use the containers like the other answers:
<View style={{
height: 100, display: 'flex',
}}>
<TouchableOpacity style={{
display: 'flex', justifyContent: 'center',
alignItems: 'center', aspectRatio: 1,
}}>
<Svg fill="white" height="100%"
width="100%" viewBox="0 0 24 24">
<Path d="M0 0h24v24H0z" fill="none"/>
<Path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>
</Svg>
</TouchableOpacity>
</View>
You have to play with the width and height together with the viewBox. Usually the viewBox you have to place the original dimensions of your desired shape. And by defining the width/height based on your needs your shape will be down/up scaled properly.
Please have a look to this tutorial where this concepts have been explained pretty clear.
https://www.sarasoueidan.com/blog/svg-coordinate-systems/
the trick in
preserveAspectRatio="xMinYMin slice"
you should do that
<Svg
height="100%"
preserveAspectRatio="xMinYMin slice"
width="100%"
viewBox="0 0 100 100"
>
Here is a component that behaves like your images:
import React from 'react';
import { View } from 'react-native';
import Svg, { Circle } from 'react-native-svg';
const WrappedSvg = () =>
(
<View style={{ aspectRatio: 1, backgroundColor: 'blue' }}>
<Svg height="100%" width="100%" viewBox="0 0 100 100">
<Circle r="50" cx="50" cy="50" fill="red" />
</Svg>
</View>
);
In context:
const WrappedSvgTest = () => (
<View>
<View style={{
width: '100%',
height: 140,
alignItems: 'center',
backgroundColor: '#eeeeee'
}}
>
<WrappedSvg />
</View>
{/* spacer */}
<View style={{ height: 100 }} />
<View style={{
width: 120,
height: 280,
justifyContent: 'space-around',
backgroundColor: '#eeeeee'
}}
>
<WrappedSvg />
</View>
</View>
);
The trick is to wrap the SVG element in a view that preserves its aspect ratio, then set the SVG sizing to 100% width and height.
I believe there is some complex interaction between the SVG element size and the viewbox size that makes the SVG render smaller than you would expect, or in some cases not render at all. You can avoid this by keeping your <View>
tags at a fixed aspect ratio and setting the <Svg>
tags to 100% width and height, so the viewbox aspect ratio always matches the element ratio.
Be sure to set aspectRatio
to viewbox.width / viewbox.height
.