如何在允许SVG自适应缩放的同时保持SVG内部元素的纵横比?

8

我对SVG非常陌生,如果这是一个显而易见的问题,我很抱歉。我已经尝试了几个小时,似乎已经遇到了障碍。

我正试图在HTML文档中创建一个SVG元素,它具有以下特点:

  • 在外部视口上有一个固定的边界
  • 保留内部元素的长宽比
  • 不保留外部SVG元素的纵横比
  • 可以任意调整大小,同时保持这些约束条件

这个JSFiddle演示了我的意思和我的尝试:

http://jsfiddle.net/a8q6S/

这里是相同的代码,因为我无法发布它:

<div>
     <h2>correct placement and aspect ratio, but cannot be resized without losing relative placement</h2>

    <svg viewBox="0 0 100 100" style="width: 100px; height: 100px; border: 1px solid red;">
        <circle cx="0" cy="0" r="10"></circle>
        <circle cx="50" cy="50" r="10"></circle>
        <circle cx="100" cy="100" r="10"></circle>
    </svg>
</div>
<div>
     <h2>correct aspect ratio of circle, incorrect relative placement</h2>

    <svg viewBox="0 0 100 100" preserveAspectRatio="xMinYMin" style="width: 200px; height: 100px; border: 1px solid red;">
        <circle cx="0" cy="0" r="10"></circle>
        <circle cx="50%" cy="50%" r="10"></circle>
        <circle cx="100%" cy="100%" r="10"></circle>
    </svg>
</div>
<div>
     <h2>correct relative placement, can be resized, but loses internal aspect ratio</h2>

    <svg viewBox="0 0 100 100" preserveAspectRatio="none" style="width: 200px; height: 100px; border: 1px solid red;">
        <circle cx="0" cy="0" r="10"></circle>
        <circle cx="50" cy="50" r="10"></circle>
        <circle cx="100" cy="100" r="10"></circle>
    </svg>
</div>

这可行吗?我走错路了吗?

3个回答

0

可以使用2个svg,一个带有preserveAspectRatio="none",另一个没有。最后一个将是上层的。

在我的示例中,我绘制了一个高度为100%的箭头,然后在其上绘制圆圈。

<body style="height: 100%; width: 100%; margin: 0; background-color: grey">
<svg style="height: 100%; width: 10%; left: 10%; position: absolute; overflow: hidden;"
    viewBox="0 0 100 100" preserveAspectRatio="none">
    <rect x="40" y="0" r="40"  width="20" height="95%" style="fill:blue;"/>
    <polygon points="40,95 50,100 60,95" style="fill:blue;" />
</svg>
<svg style="height: 100%; width: 10%; left: 10%; position: absolute; overflow: hidden;">
    <circle cx="50%" cy="16.6%" r="25" style="fill:white;" />
    <circle cx="50%" cy="50%" r="50" style="fill:white;" />
    <circle cx="50%" cy="83.3%" r="25" style="fill:white;" />
</svg>
</body>

0

使用纯SVG无法实现您想要的效果。您需要在加载和调整大小时使用一些JavaScript来微调SVG。

如果您使用类似第二个示例的东西,您只需要微调viewBox、宽度和高度即可。内容可以保持不变。

例如,

<svg viewBox="0 0 100 100" style="width: 100px; height: 100px; border: 1px solid red;">
    <circle cx="0" cy="0" r="10"></circle>
    <circle cx="50%" cy="50%" r="10"></circle>
    <circle cx="100%" cy="100%" r="10"></circle>
</svg>

会变成

<svg viewBox="0 0 200 100" style="width: 200px; height: 100px; border: 1px solid red;">
    <circle cx="0" cy="0" r="10"></circle>
    <circle cx="50%" cy="50%" r="10"></circle>
    <circle cx="100%" cy="100%" r="10"></circle>
</svg>

当宽度加倍时。

http://jsfiddle.net/a8q6S/3/


-2

谢谢。我也遇到了类似的问题。这是我的解决方案。

<svg viewBox="0 0 100% 100%" preserveAspectRatio="xMinYMin" style="width: 200px; height: 100px; border: 1px solid red;">
    <circle cx="0%" cy="0%" r="10"></circle>
    <circle cx="50%" cy="50%" r="10"></circle>
    <circle cx="100%" cy="100%" r="10"></circle>
</svg>

抱歉,我对SVG也很新,感谢您的纠正。

这并没有直接解决所提出的问题,但我发现在不保持宽高比的viewbox内无法保留viewbox的宽高比。

这个解决方案的注意事项是,除非不保持相对位置,否则必须为每个内部SVG建立宽度和高度。

如果要同时保持相对位置和宽高比,请不要使用viewbox。

<svg viewbox="0 0 100 100" preserveAspectRatio="xMinYMin" width=200 height=100 style="border: 1px solid red;">
   <svg>
     <circle cx="0" cy="0" r="10"></circle>
     <circle cx="50" cy="50" r="10"></circle>
     <circle cx="100" cy="100" r="10"></circle>
   </svg>
   <svg viewbox="0 0 100 100" preserveAspectRatio="none" fill=blue width=200 height=100>
     <circle cx="0" cy="0" r="7"></circle>
     <circle cx="50" cy="50" r="7"></circle>
     <circle cx="100" cy="100" r="7"></circle>
   </svg>
   <svg  fill=red width=200 height=100>
     <circle cx="0%" cy="0%" r="4"></circle>
     <circle cx="50%" cy="50%" r="4"></circle>
     <circle cx="100%" cy="100%" r="4"></circle>
   </svg>
 </svg>

1
你能解释一下吗? - Sylvain Martin
1
我不明白这如何回答问题。此外,此处的“viewBox”是无效的。你不能在“viewBox”中使用百分比值。 - Paul LeBeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接