动态调整单个形状的大小而不缩放整个SVG

时间:2016-12-21 08:54:14

标签: css svg css-shapes

我有一个箭头作为SVG,我想根据包装DIV的宽度改变长度(例如)。

我以前的所有尝试都导致了这种行为(缩放整个SVG):

Scaling whole SVG

而不是这样,我想实现这种行为:

Scaling shapes only

是否可以通过简单地在代码中添加百分比值来改变SVG内部的单个形状?如果没有,我怎么能这样做?

SVG代码:



<svg width="35px" viewBox="0 0 35 985" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <g id="Group" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(0.000000, 0.000000)">
    <rect id="Rectangle-2" fill="#5FDCC7" x="12" y="19.7987928" width="11" height="100%"></rect>
    <polygon id="Triangle" fill="#5FDBC6" points="17.5 0 35 20.7887324 0 20.7887324"></polygon>
    <rect id="Rectangle-3" fill="#5FDBC6" x="0" y="973.110664" width="35" height="11"></rect>
  </g>
</svg>
&#13;
&#13;
&#13;

5 个答案:

答案 0 :(得分:9)

作为一般规则,没有办法创建可扩展的SVG,其中部分不会扩展。如果SVG具有viewBox,并且您对其进行缩放,则所有内容都将缩放。没有办法将某些内容标记为不受缩放影响。

最接近的是限制缩放到X轴。然而,箭头仍会伸展。

&#13;
&#13;
<svg width="35px" height="150px" viewBox="0 0 35 985" preserveAspectRatio="none">

        <g id="Group" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(0.000000, 0.000000)">
            <rect id="Rectangle-2" fill="#5FDCC7" x="12" y="19.7987928" width="11" height="100%"></rect>
            <polygon id="Triangle" fill="#5FDBC6" points="17.5 0 35 20.7887324 0 20.7887324"></polygon>
            <rect id="Rectangle-3" fill="#5FDBC6" x="0" y="973.110664" width="35" height="11"></rect>
        </g>
</svg>


<svg width="35px" height="300px" viewBox="0 0 35 985" preserveAspectRatio="none">

        <g id="Group" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(0.000000, 0.000000)">
            <rect id="Rectangle-2" fill="#5FDCC7" x="12" y="19.7987928" width="11" height="100%"></rect>
            <polygon id="Triangle" fill="#5FDBC6" points="17.5 0 35 20.7887324 0 20.7887324"></polygon>
            <rect id="Rectangle-3" fill="#5FDBC6" x="0" y="973.110664" width="35" height="11"></rect>
        </g>
</svg>
&#13;
&#13;
&#13;

如果您需要通用解决方案,则必须监控调整大小事件并动态更新SVG。

有限的偷偷摸摸的聪明解决方案......

说了这么多,有一种巧妙的技术可以在有限的情况下发挥作用。限制是:

  1. SVG只朝一个方向伸展。
  2. &#34;不缩放&#34;零件位于拉伸的任一端或两端
  3. 末端部分是实心的,没有任何孔。
  4. 你可以选择SVG是纯色的背景,而不是透明的。
  5. 以下是使用此技术实现的形状演示。如果你水平调整窗口的大小,你会看到它适当地伸展。:

    &#13;
    &#13;
    <svg width="100%" height="35px">
    
      <svg viewBox="0 0 1 1" preserveAspectRatio="none">
        <rect x="0" y="0" width="1" height="1" fill="white"/>
        <rect x="0" y="0.4" width="1" height="0.2" fill="#5FDBC6"/>
      </svg>
        
      <svg viewBox="0 0 0.2 1" preserveAspectRatio="xMinYMid">
        <rect x="0" y="0" width="0.2" height="1" fill="#5FDBC6"/>
      </svg>
    
      <svg viewBox="0 0 0.8 1" preserveAspectRatio="xMaxYMid">
        <rect x="0" y="0" width="0.8" height="1" fill="white"/>
        <polygon points="0,0 0.8,0.5 0,1" fill="#5FDBC6"/>
      </svg>
    
    </svg>
    &#13;
    &#13;
    &#13;

答案 1 :(得分:5)

是的,你可以在svg中使用百分比。

基本形状很简单。您可以将主矩形写为

<rect x="0" y="5" width="100%" height="10"/>

你的第二个矩形甚至更简单,因为它始终位于0,0

<rect x="0" y="0" width="10" height="20"/>

但是使用箭头时,在pathes和polygon中存在问题,您无法使用百分比。要解决此问题,需要采取两步解决方案。

首先将路径放在符号元素中:

<symbol id="arrow" viewBox="0 0 20 20" width="20" height="20">
  <path d="M0,0L20 10L0 20z" />
</symbol>

现在你可以定位这个符号,就像你定位一个矩形......简单......

<use xlink:href="#arrow" x="100%" y="0" width="20" height="20"/>

但现在你的箭头开始100%并完全在你的视口之外。你可以设置溢出:在你的svg上显示并完成它,但这不是我们想要的......我们希望箭头以100%结束。但这也很容易,我们知道箭头是20px宽。所以只需将使用率翻译成20px:

<use xlink:href="#arrow" x="100%" y="0" width="20" height="20" transform="translate(-20 0)"/>

使用这种方法,您可以根据百分比将任何形状定位在任何位置......

将它全部扭曲,你的完整svg现在看起来像这样:

<svg id="svg" height="20px" xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol id="arrow" viewBox="0 0 20 20" width="20" height="20">
    <path d="M0,0L20 10L0 20z" />
  </symbol>
  <g id="Group" fill="#5FDCC7">
    <rect x="0" y="5" width="100%" height="10" transform="translate(-20 0)" />
    <rect x="0" y="0" width="10" height="20" />
    <use xlink:href="#arrow" width="20" height="20" x="100%" y="0" transform="translate(-20 0)" />
  </g>
</svg>

这是一个使用这个svg的片段,有3种不同的宽度:

svg:nth-of-type(1) {
  width: 100px
}
svg:nth-of-type(2) {
  width: 200px
}
svg:nth-of-type(3) {
  width: 300px
}
<svg height="20px" xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol id="arrow" viewBox="0 0 20 20" width="20" height="20">
    <path d="M0,0L20 10L0 20z" />
  </symbol>
  <g id="Group" fill="#5FDCC7">
    <rect x="0" y="5" width="100%" height="10" transform="translate(-20 0)" />
    <rect x="0" y="0" width="10" height="20" />
    <use xlink:href="#arrow" width="20" height="20" x="100%" y="0" transform="translate(-20 0)" />
  </g>
</svg>
<br/>
<svg height="20px" xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol id="arrow" viewBox="0 0 20 20" width="20" height="20">
    <path d="M0,0L20 10L0 20z" />
  </symbol>
  <g id="Group" fill="#5FDCC7">
    <rect x="0" y="5" width="100%" height="10" transform="translate(-20 0)" />
    <rect x="0" y="0" width="10" height="20" />
    <use xlink:href="#arrow" width="20" height="20" x="100%" y="0" transform="translate(-20 0)" />
  </g>
</svg>
<br/>
<svg height="20px" xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol id="arrow" viewBox="0 0 20 20" width="20" height="20">
    <path d="M0,0L20 10L0 20z" />
  </symbol>
  <g id="Group" fill="#5FDCC7">
    <rect x="0" y="5" width="100%" height="10" transform="translate(-20 0)" />
    <rect x="0" y="0" width="10" height="20" />
    <use xlink:href="#arrow" width="20" height="20" x="100%" y="0" transform="translate(-20 0)" />
  </g>
</svg>

答案 2 :(得分:3)

对于这个特殊用例,我想我会采用CSS方法,它可能(取决于你的标记)添加一个html元素,如果你不能使用伪元素,但它不会需要JS或为manualy输入stroke-width或transform元素的值。

以下是使用段落标记制作此箭头的方法:

&#13;
&#13;
p {
  position: relative;
  max-width: 300px;
  border-bottom: 4px solid #5FDBC6;
  padding-bottom:6px;
}
p:nth-child(2) {max-width: 400px;}
p:nth-child(3) {max-width: 200px;}
p::before, p::after{
  content:'';
  position:absolute;
  bottom:-8px;
}
p::before {
  height: 12px;
  left:0;
  border-left: 4px solid #5FDBC6;
}
p::after{
  right:-4px;
  border-style:solid;
  border-width:6px 0 6px 8px;
  border-color:transparent transparent transparent #5FDBC6;
}
&#13;
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. a dapibus, tincidunt velit eget, rutrum urna.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras in purus risus. Ut id est suscipit, tincidunt sem a, fermentum magna. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut rutrum ac ligula</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras in purus risus. Ut id est suscipit, tincidunt sem a, fermentum magna.</p>
&#13;
&#13;
&#13;

答案 3 :(得分:1)

通过使用符号,您可以制作所需的形状并将其包含在内。然后,为了扩展中间部分,只需创建一条新路径并使线条更长。通过使用transform属性

,可以将它们放置在您喜欢的任何位置

<svg xmlns="http://www.w3.org/2000/svg">

  <symbol id="base">
    <g xmlns="http://www.w3.org/2000/svg">
      <path fill="#5FDBC6" d="M0,0 L0,20 L4,20 L4,0z"></path>
    </g>
  </symbol>
  <symbol id="triangle" >
    <g>
      <path fill="#5FDBC6" d="M0,0 L15,10 L0,20z"></path>
    </g>
  </symbol>

  <path stroke-width="4" stroke="#5FDBC6" d="M0,10 L100,10"></path>
  <g class="first" transform="translate(0,00)">
    <use xlink:href="#base" />
  </g>
  <g class="first" transform="translate(90,00)">
    <use xlink:href="#triangle" />
  </g>
  
  <path stroke-width="4" stroke="#5FDBC6" d="M0,50 L200,50"></path>
  <g class="first" transform="translate(0,40)">
    <use xlink:href="#base" />
  </g>
  <g class="first" transform="translate(200,40)">
    <use xlink:href="#triangle" />
  </g>


</svg>

答案 4 :(得分:0)

** 已编辑 **

此行为是由viewBox上的<svg>属性引起的。默认情况下,您的SVG宽高比将被保留。您希望#Triangle#Rectangle-3上出现此行为,但不希望#Rectangle-2上出现此行为(您希望height增加,但width保持不变)。

我认为您希望将preserveAspectRatio=none添加到<svg>内联CSS中,然后进行一些调整(因为这会影响#Triangle和{{的宽高比1}} - 或者更确切地说,你可以尝试将#Rectangle-3 height更改为与包装div相同的高度(在我的JS小提琴中我已经这样做了,设置{ {1}}高度为25vh)。玩窗户的高度 - #triangle-2的高度伸长但不会改变宽度,虽然我还没有你的{{1动态地粘贴到#Triangle-2的底部(#Rectangle-2卡在窗口底部):https://jsfiddle.net/KyleVassella/dnagft6q/6/

我怀疑你会知道如何解决这个问题,但无论哪种方式我都会继续努力,同时你可以在这里阅读有关这个​​主题的更多信息:

How can I make an svg scale with its parent container?