【问题标题】:Scale SVG image non-proportionally to fit in remaining space不按比例缩放 SVG 图像以适应剩余空间
【发布时间】:2020-12-20 19:32:57
【问题描述】:

下面的箭头由 3 个单个元素组成。中心部分应水平拉伸,以便箭头可以填充其周围的容器。但正如您在渲染代码中看到的那样,拉伸不起作用。如何启用拉伸并确保连接处没有间隙。由于antialiasing(这是强制性的),部分之间应该有少量重叠。

编辑:使用@Turnip 建议的preserveAspectRatio="none" 会拉伸图像,但它会在某些宽度上产生间隙和跳跃。看这个截图:

根本无法解释这种奇怪的行为!

.arrow {
  display: flex;
  max-width: 200px;
  padding-bottom: 2em;
}

.arrow svg {
  height: 25px;
  shape-rendering: auto;
}

#arrow-1 svg.stretched {}

#arrow-2 svg.stretched {
  width: 100%;
}
<div class="arrow" id="arrow-1">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 25">
  <path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M13 2.5h-1.31A5.21 5.21 0 006.5 7.69v14.62"/>
</svg>

  <svg xmlns="http://www.w3.org/2000/svg" class="mid" viewBox="0 0 3 25"><rect y="1" width="3" height="3"/></svg>

  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 25">
  <path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M5.5 15.84V7.69A5.21 5.21 0 00.31 2.5H0"/>
  <path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"/>
</svg>
</div>

<div class="arrow" id="arrow-2">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 25">
  <path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M13 2.5h-1.31A5.21 5.21 0 006.5 7.69v14.62"/>
</svg>

  <svg xmlns="http://www.w3.org/2000/svg" class="stretched" viewBox="0 0 3 25"><rect y="1" width="3" height="3"/></svg>

  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 25">
  <path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M5.5 15.84V7.69A5.21 5.21 0 00.31 2.5H0"/>
  <path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"/>
</svg>
</div>

【问题讨论】:

    标签: html css svg flexbox


    【解决方案1】:

    您可以使用 CSS 完成大部分工作,并且更容易处理:

    .box {
      width: 50%;
      margin: auto;
      height: 50px;
      border: 10px solid;
      border-bottom: 0;
      border-radius: 20px 20px 0 0;
      position: relative;
    }
    
    .box::after {
      content: "";
      position: absolute;
      bottom: 0;
      right: -5px;
      width: 45px;
      height: 58px;
      transform: translate(50%, 30%);
      background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 12 11 13"><path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"></path></svg>') bottom/contain no-repeat;
    }
    &lt;div class="box"&gt;&lt;/div&gt;

    也像下面这样:

    .box {
      width: 50%;
      margin: auto;
      height: 50px;
      border: 10px solid;
      border-bottom: 0;
      border-radius: 20px 20px 0 0;
      position: relative;
    }
    
    .box svg {
      position: absolute;
      bottom: 0;
      right: -5px;
      width: 45px;
      transform: translate(50%, 30%);
    }
    <div class="box">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 12 11 13"><path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"></path></svg>
    </div>

    【讨论】:

    • 在 CSS 中使用背景图片是一个好方法——但不幸的是我不能使用伪元素,因为我只能使用 CSS 内联样式!
    • 非常经济和智能!就这样。
    【解决方案2】:

    我只使用了一个,而不是使用 3 个 svg 元素。我将“箭头”的开头和结尾放在&lt;symbol&gt; 元素中,这样我就可以在需要的地方使用这些形状。请注意&lt;symbol&gt; 元素有一个紧凑的视图框(视图框将形状紧紧包裹起来,并且与形状的边界框大小相同 + 为 1/2 线宽留出一些额外空间)。

    现在我可以根据需要在需要的地方多次使用这些符号。

    为了连接 2 个使用元素,我使用了一条线。请注意,线(在第一组中)的 x1 属性为 18,其中 18 = 10(第一个 use 元素的 x 属性)+ 8(第一个 use 元素的 width 属性)。

    该行的 x2 属性取决于您需要多长时间,并且与第二个使用元素的属性 x 具有相同的值。

    <svg viewBox="0 0 130 70">
      <symbol id="start" xmlns="http://www.w3.org/2000/svg" viewBox="5 0 8 22">
        <path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M13 2.5h-1.31A5.21 5.21 0 006.5 7.69v14.62" />
      </symbol>
    
      <symbol id="end" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 25">
        <path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M5.5 15.84V7.69A5.21 5.21 0 00.31 2.5H0" />
        <path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z" />
      </symbol>
    
      <g id="g1">
        <use xlink:href="#start" x="10" width="8" height="22" />
        <use xlink:href="#end" x="100" width="11" height="25" />
        <line x1="18" y1="2.5" x2="100" y2="2.5" stroke="black" stroke-width="3" stroke-linecap="round" />
      </g>
      
      <g id="g2">
        <use xlink:href="#start" x="20" y="35" width="8" height="22" />
        <use xlink:href="#end" x="70" y="35" width="11" height="25" />
        <line x1="28" x2="70" y1="37.5" y2="37.5" stroke="black" stroke-width="3" stroke-linecap="round" />
      </g>
    </svg>

    【讨论】:

    • 非常优雅的解决方案,我真的很喜欢!但不幸的是,它按比例缩放,而不仅仅是水平缩放;笔画宽度应该是固定的。
    【解决方案3】:

    在要拉伸的 SVG 上使用 preserveAspectRatio="none"。这将允许内部 rect 与 SVG 元素一起拉伸。

    .arrow {
      display: flex;
      max-width: 200px;
      padding-bottom: 2em;
    }
    
    .arrow svg {
      height: 25px;
      shape-rendering: auto;
    }
    
    #arrow-1 svg.stretched {}
    
    #arrow-2 svg.stretched {
      width: 100%;
    }
    <div class="arrow" id="arrow-1">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 25">
      <path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M13 2.5h-1.31A5.21 5.21 0 006.5 7.69v14.62"/>
    </svg>
    
      <svg xmlns="http://www.w3.org/2000/svg" class="mid" viewBox="0 0 3 25"><rect y="1" width="3" height="3"/></svg>
    
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 25">
      <path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M5.5 15.84V7.69A5.21 5.21 0 00.31 2.5H0"/>
      <path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"/>
    </svg>
    </div>
    
    <div class="arrow" id="arrow-2">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 25">
      <path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M13 2.5h-1.31A5.21 5.21 0 006.5 7.69v14.62"/>
    </svg>
    
      <svg xmlns="http://www.w3.org/2000/svg" class="stretched" viewBox="0 0 3 25" preserveAspectRatio="none"><rect y="2" width="3" height="3"/></svg>
    
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 25">
      <path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M5.5 15.84V7.69A5.21 5.21 0 00.31 2.5H0"/>
      <path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"/>
    </svg>
    </div>

    【讨论】:

    • 是的,拉伸是有效的,但是如果中间部分变小或变大,外观就会变得一团糟。只需删除 max-width 并尝试使视口越来越小。我会在我的问题末尾放一张结果图片。
    猜你喜欢
    • 2018-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    相关资源
    最近更新 更多