如何在 React Native View 中自动缩放 SVG 元素? [英] How can I automatically scale an SVG element within a React Native View?

查看:52
本文介绍了如何在 React Native View 中自动缩放 SVG 元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 react-native-svg 元素放在 View 内,以便它以特定的固定纵横比呈现,但随后缩放为在包含视图的范围内尽可能大.

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 large as possible, within the confines of the containing view.

Svg 元素(来自 react-native-svg)似乎只接受绝对的 widthheight属性(我试过使用百分比,但没有任何渲染,调试确认百分比值在它们到达本机视图时是 NSNull).我不确定如何达到预期的效果.这是我迄今为止尝试过的:

The Svg element (from react-native-svg) seems to only accept absolute width and height attributes (I've tried using percentages, but nothing renders, and debugging confirms that percent values are NSNull by the time they get to the native view). I'm not sure how to achieve the desired effect. Here's what I've tried so far:

// I have a component defined like this:
export default class MySvgCircle extends React.Component {
    render() {
        return (
            <View style={[this.props.style, {alignItems: 'center', justifyContent: 'center'}]} ref="containingView">
                <View style={{flex: 1, justifyContent: 'center', alignItems: 'center', aspectRatio: 1.0}}>
                    <Svg.Svg width="100" height="100">
                        <Svg.Circle cx="50" cy="50" r="40" stroke="blue" strokeWidth="1.0" fill="transparent" />
                        <Svg.Circle cx="50" cy="50" r="37" stroke="red" strokeWidth="6.0" fill="transparent" />
                    </Svg.Svg>
                </View>
            </View>
        );
    }
}

// And then consumed like this:
<MySvgCircle style={{height: 200, width: 200, backgroundColor: "powderblue"}}/>

这就是我在渲染时看到的.

And this is what I see when it renders.

我希望放大红色和蓝色圆圈以填充 200x200 区域(如果包含视图是矩形而不是正方形,则保持圆形),而无需预先知道组件的使用者/用户所需的大小.

I want the red and blue circles to be scaled up to fill the 200x200 area (staying circular if the containing view is rectangular and not square), without having foreknowledge of the size desired by the consumer/user of the component.

如前所述,我尝试使用百分比,如下所示(其余相同):

As mentioned, I tried using percentages, like this (the rest is the same):

<Svg.Svg width="100%" height="100%">

但是 SVG 部分根本不绘制.像这样:

But then the SVG part doesn't draw at all. Like this:

控制台日志中没有错误消息或其他说明为什么这不起作用.

There are no error messages, or other indications of why this doesn't work, in the console logs.

在 RN 中布局后测量 UI 元素的方法似乎是异步的,这似乎与我想要做的不太匹配.我可以使用某种缩放或变换魔法吗?

The methods for measuring UI elements after layout in RN appears to be asynchronous, which seems like a poor match to what I'm trying to do. Is there some sort of scaling or transform magic that I could use?

所需的输出看起来像这样(通过硬编码值获得):

The desired output would look like this (obtained by hardcoding values):

当包含视图不是一个完美的正方形时,我希望它像这样工作:

And when the containing view isn't a perfect square I'd like it to work like this:

推荐答案

这是一个行为类似于您的图像的组件:

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>
  );

上下文:

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>
);

诀窍是将 SVG 元素包装在保留其纵横比的视图中,然后将 SVG 大小设置为 100% 宽度和高度.

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.

我相信 SVG 元素大小和 viewbox 大小之间存在一些复杂的交互作用,这使得 SVG 渲染得比您预期的要小,或者在某些情况下根本不渲染.您可以通过将 标签保持在固定纵横比并将 标签设置为 100% 宽度和高度来避免这种情况,因此视图框方面ratio 始终与元素比率匹配.

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.

务必将aspectRatio设置为viewbox.width/viewbox.height.

这篇关于如何在 React Native View 中自动缩放 SVG 元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆