【问题标题】:How can I preserve the aspect ratio of internal elements of an SVG while allowing the SVG itself to scale?如何在允许 SVG 本身缩放的同时保留 SVG 内部元素的纵横比?
【发布时间】:2018-06-27 00:10:51
【问题描述】:

我对 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>

这可能吗?我是不是走错了路?

【问题讨论】:

    标签: html svg


    【解决方案1】:

    使用纯 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】:

      可以使用 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>
      

      【讨论】:

        【解决方案3】:

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

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

        对不起,我也是 svgs 的新手,感谢您的更正。

        这并不能直接解决所提出的问题,但我发现我无法在不保留纵横比的视图框中保留视图框的纵横比。

        此解决方案的警告是,您必须为每个内部 svg 建立宽度和高度,除非不保留相对位置。

        如果您想同时保留相对位置和纵横比,请不要使用视图框。

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

        【讨论】:

        • 你能解释一下吗?
        • 我不明白这如何回答 OP 的问题。这里的viewBox 也是无效的。您不能在 viewBox 中使用百分比值。
        最近更新 更多