Css 如何使用本机svg查找宽度、高度和viewBox的正确值

Css 如何使用本机svg查找宽度、高度和viewBox的正确值,css,react-native,svg,aspect-ratio,Css,React Native,Svg,Aspect Ratio,我一直在尝试做一些看似简单的事情,但我已经尝试了几个小时,却找不到解决办法 我有一个SVG,需要放在屏幕上。它来自设计师,尺寸如下: <Svg width="354px" height="190px" viewBox="0 0 354 190">...</Svg> 我的问题是,我还没有找到一种方法来缩放SVG以获得100%的屏幕宽度,找到正确的高度(或自动设置的方法),并保留纵横比。我已经尝试了很多事情,包括摆弄容器的aspectRatio样式和高度(或者根本不设置高度

我一直在尝试做一些看似简单的事情,但我已经尝试了几个小时,却找不到解决办法

我有一个SVG,需要放在屏幕上。它来自设计师,尺寸如下:

<Svg width="354px" height="190px" viewBox="0 0 354 190">...</Svg>
我的问题是,我还没有找到一种方法来缩放SVG以获得100%的屏幕宽度,找到正确的高度(或自动设置的方法),并保留纵横比。我已经尝试了很多事情,包括摆弄容器的aspectRatio样式和高度(或者根本不设置高度)。每当我发现一些“比例”起作用时,我就尝试在不同的设备上使用不同的屏幕宽度,但它看起来一点都不好(裁剪、小于屏幕宽度等)

我觉得SVG(react native SVG)中的PreserveSpectRatio属性在某种程度上与aspectRatio样式相冲突。我完全迷上了PreserveSpectRatio,我还没有找到一种不被裁剪就可以缩放的方法

有人知道如何做到这一点吗

这是我的最后一段代码,它返回了一个显示SVG的热图组件,但尽管它的高度正确,但SVG的一部分从右侧不在屏幕上(看起来被裁剪了,因为它太宽了):

const windowWidth=Dimensions.get(“窗口”).width;
const getSVGRootProps=({width,height})=>({
宽度:“100%”,
高度:“100%”,
视图框:`0${width}${height}`,
PreserveSpectratio:“xMinYMin会议”,
});
常量字段形状=()=>{
常量宽度=354;//原始宽度
常数高度=190;//原始高度
const aspectRatio=宽度/高度;
//调整后的高度=*原始高度/原始宽度
常量计算高度=(窗宽*高度)/宽度;
常量字段样式={
宽度:窗宽,
高度:计算高度,
aspectRatio,
};
返回(
...
);
};
常数热图=()=>{
返回;
};
结果是:


我找到了解决方案,我将它发布在这里,以防任何人在react native和SVG中遇到同样的问题。基本上,如果您试图获取一个SVG文件并将其转换为具有“动态”部分的组件(如基于数据以编程方式将颜色设置为路径,或显示SVG文本),则可能会遇到此问题

我所做的是将原始SVG转换为react本机组件(使用)。然后,我只是根据需要用变量(来自props)替换硬编码数据。它看起来不错,但我有一个问题的组成部分的大小。我找不到一种一致的方式来跨不同的设备大小和分辨率显示它。看起来很简单,但我试了几个小时,结果在每个屏幕大小上都不一样。在这里提问并在react-native svg repo上打开一个问题之后,我没有得到任何答案和线索(没有责怪任何人,只是说这可能不是很多人遇到的事情)。所以我挖了又挖,终于找到了,她谈到了绝对和相对SVG路径。这让我想到,也许我在寻找完美的调整公式时遇到了很多问题,因为我的路径不是相对的,而是绝对的。所以我尝试了这个方法,粘贴我的(原始)SVG代码,然后复制结果。我将结果粘贴到这张便利纸上,然后我更改了一些内容以实现我的目标:

  • 我想让我的SVG获得全屏幕的宽度,宽度和高度相应地缩放
这就是我所改变的:

// SVG's original size is 519 width, 260 height
// <Svg width="519" height="260" viewBox="0 0 519 260">...</Svg>
// I also added a container, which enforces the aspect ratio
const originalWidth = 519;
const originalHeight = 260;
const aspectRatio = originalWidth / originalHeight;
const windowWidth = Dimensions.get("window").width;
return (
    <View style={{ width: windowWidth, aspectRatio }}>
        <Svg 
            width="100%" 
            height="100%" 
            viewBox={`0 0 ${originalWidth} ${originalHeight}`}>
        ...
        </Svg>
    </View>
)
用于将绝对路径转换为相关路径的脚本是这个名为()的库的一部分,但您只需要它的1%。我正在考虑使用一个小工具,它将获取svg文件中的所有路径,并应用此转换。老实说,我已经处理SVG文件很多年了,但我从来没有真正了解过它的内部工作原理、路径格式、坐标等,所以这非常有启发性:)


如果你发现自己处于同样的处境,我希望这对你有所帮助

使用getBBox()方法。在这里阅读更多内容:我不确定我是否可以在react native svg中使用它,我还没有看到在这里实现的方法……只是遇到了这个问题,您的解决方案工作得很好。谢谢你花时间在这上面!我也有同样的问题,你帮了我很多。谢谢:)
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 />;
};
// SVG's original size is 519 width, 260 height
// <Svg width="519" height="260" viewBox="0 0 519 260">...</Svg>
// I also added a container, which enforces the aspect ratio
const originalWidth = 519;
const originalHeight = 260;
const aspectRatio = originalWidth / originalHeight;
const windowWidth = Dimensions.get("window").width;
return (
    <View style={{ width: windowWidth, aspectRatio }}>
        <Svg 
            width="100%" 
            height="100%" 
            viewBox={`0 0 ${originalWidth} ${originalHeight}`}>
        ...
        </Svg>
    </View>
)
npx @svgr/cli [-d out-dir] [--ignore-existing] [src-dir]