我一直在尝试做一些看起来很容易的事情,但是我已经尝试了几个小时了,也找不到解决的办法。
我有一个SVG需要在屏幕上。它来自设计师,具有这些维度:
<Svg width="354px" height="190px" viewBox="0 0 354 190">...</Svg>
在React Native中,这将位于容器内部,SVG需要获取屏幕的全宽度,我从以下内容获取:
Dimensions.get("window").width
我的问题是,我还没有找到一种方法来缩放SVG以获得100%的屏幕宽度,找出正确的高度(或者自动设置高度的方法),并保留纵横比。我已经尝试了很多事情,包括玩容器的aspectRatio样式和它的高度(或者根本不设置高度)。每当我发现一些“比例”的工作,我尝试在不同的设备与不同的屏幕宽度,它看起来一点也不好看(裁剪,比屏幕宽度小,等等)。
我觉得SVG(react-native-svg)中的preserveAspectRatio属性与aspectRatio样式有些冲突。我完全失去了保留的aspectratio,我没有找到一种方法使它缩放而不被裁剪。
有没有人知道如何做到这一点?
这是我的最后一段代码,它返回了一个显示SVG的热图组件,但是尽管它有正确的高度,但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 />;
};
这就是结果:
我已经找到了解决方案,我将它发布在这里,以防有人在react native和SVG中遇到同样的问题。基本上,如果您试图获取一个SVG文件,并将其转化为一个包含“动态”部分的组件(例如基于数据以编程方式为路径设置颜色,或显示SVG文本),那么您可能会遇到这个问题。
我所做的是使用SVGR将原始SVG转换为react原生组件(带有react-native-svg)。然后我只是根据需要用变量(来自道具)替换硬编码数据。它看起来不错,但我有一个问题的组件的大小。我找不到一个一致的方法来显示它在不同的设备大小和分辨率。这看起来很容易,但我试了几个小时,结果在每个屏幕尺寸上都不一样。在问了这个问题并开了一个关于react-native-svg repo的问题之后,我没有得到任何答案,也没有任何线索(没有责备任何人,只是说这可能不是很多人遇到的事情)。所以我挖了又挖,终于找到了Lea Verou的这篇文章,她在里面谈到了绝对和相对SVG路径。这让我想,也许我有这么多问题试图找到完美的大小公式,因为我的路径不是相对的,而是绝对的。所以我尝试了heyzeuss的这个jsfiddle,粘贴我的(原始)SVG代码,然后复制结果。我将结果粘贴到这个方便的SVGR playground(SVG到JS)工具中,然后我更改了一些位来实现我的目标:
所以这就是我改变的:
// 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>
)
在此过程中我学到了一些东西,例如,create-react-app中包含了一个@svgr/cli,并且在我的react-native项目中也可用,而不需要安装任何额外的东西,因此它也必须与原始依赖项捆绑在一起。您可以运行此命令,它将把文件夹中的单个文件或所有文件从.svg转到React组件:
npx @svgr/cli [-d out-dir] [--ignore-existing] [src-dir]
用于将绝对路径转换为亲属路径的脚本是这个名为snap.svg的库的一部分,但您只需要它的1%(snap.path.toRelative)。我正在考虑有一个小工具,它可以处理svg文件中的所有路径,并应用这种转换。老实说,我已经处理SVG文件很多年了,但我从未真正了解过它在内部的工作方式、路径的格式、坐标等等,所以这是很有启发意义的:)
我希望这对你有帮助,如果你发现自己在同样的情况!
我试图构造带有viewBox属性的内联SVG,但没有显式的width或height属性。我正在使用CSS将SVG的宽度设置为100%。这将允许SVG缩放到其包装容器中,保持由ViewBox设置的纵横比。在Chrome和Firefox中,这是完美的! 下面是我所讲内容的一个最小代码示例:http://codepen.io/pcorey/pen/amkgl HTML: CSS: viewBox是100
如何不是用 width 和 height 控制 svg 的渲染大小? 下面的网站 https://nicegui.io/ 首页左上角的的 「NiceGUI」的尺寸不大不小刚刚好,对应的 svg 是:https://github.com/zauberzeug/nicegui/blob/main/website/static/nicegui_word.svg https://nicegui.io/ 这
SVG VIEWBOX viewport 首先来了解下SVG中的viewport这个概念,简单来说viewbox就是值指SVG图片本身可视区域的大小,除了SVG本身,其它一些元素也有可视区域的限制,比如symbol、image、pattern等。 在SVG中viewport主要是通过width和height属性来定义的。比如,我们定义一个width="600"和height="600"就表示我们定
描述 (Description) 调整大小操作会将width, height, data-width and data-height属性设置为“img”/“video”或“a”标记。 这样,您的图像将以请求的大小显示。 例子 (Example) ![](video.mp4?resize = 400, 220) 输出 (Output) 上面的代码将生成以下输出&
描述 (Description) cropZoom用于根据请求zoom和crop图像。 宽高比将相同,但图像将被裁剪,生成的图像将设置在center 。 例子 (Example) ![My new image](example-1.jpg?cropZoom = 600, 200) 输出 (Output) 上面的代码给出了以下结果 -
描述 (Description) 使用CropResize ,您可以根据图像的宽度和高度将图像调整为更小或更大的尺寸。 在背景区域中裁剪常规resize 。 例子 (Example) ![My new image](example-1.jpg?cropResize = 300, 300) 输出 (Output) 上面的代码将获取以下输出 -