How can I automatically scale an SVG element within a React Native View?

后端 未结 4 975
隐瞒了意图╮
隐瞒了意图╮ 2021-02-07 01:10

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

相关标签:
4条回答
  • 2021-02-07 01:39

    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>
    
    0 讨论(0)
  • 2021-02-07 01:43

    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/

    0 讨论(0)
  • 2021-02-07 01:49

    the trick in

      preserveAspectRatio="xMinYMin slice"
    
    

    you should do that

    <Svg 
     height="100%" 
     preserveAspectRatio="xMinYMin slice" 
     width="100%" 
     viewBox="0 0 100 100"
    >
    
    
    
    0 讨论(0)
  • 2021-02-07 01:50

    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.

    0 讨论(0)
提交回复
热议问题