2016-12-21 29 views
10

我有一个箭头作为SVG,它的长度是我想要改变以响应包装DIV(例如)的宽度。动态调整单个形状的大小,但不缩放整个SVG

我以前所有的尝试引入这种行为(缩放整个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>

+0

所以你只想让中间线伸展过来的空间? – Stewartside

+0

是的,正好...(但动态回应,让我们说一个div的宽度) – to7be

+0

好吧给我5分钟 – Stewartside

回答

8

作为一般规则,无法创建可伸缩的SVG,其中一部分不能缩放。如果一个SVG有一个viewBox,并且你缩放它,那么所有的内容都会缩放。没有办法将某些内容标记为不受缩放的影响。

最接近你可以得到的是限制缩放到X轴。但是箭头仍然会伸展。

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

如果你想要一个广义解,那么你必须调整监控的事件和动态更新SVG。

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

说了这么多,有一个聪明的技术,在一组有限的情况下工作。限制如下:

  1. SVG仅向一个方向延伸。
  2. “不缩放”部分位于延伸线的两端或两端
  3. 端部部分固定且没有任何孔。
  4. 您可以将SVG的背景设置为纯色,而不是透明。

下面是使用此技术实现的形状演示。如果水平调整窗口的大小,你会看到它绵延适当.:

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

+0

因为我可以忍受这些限制,所以这对我来说非常合适!谢谢! – to7be

+0

狡猾和聪明 –

+0

嗨保罗,还有一个更通用的解决方案。使用百分比和变换,您可以从左侧和底部定位符号,以便您可以在响应式svg中的任意位置定位任何形状...请参阅下面的我的回答... ;-) –

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>

+0

谢谢!由于这对我而言是一个全新的话题,我从未考虑过这种方法。我需要在这里阅读很多内容,下一步就是对所有职位和翻译进行调整,以实现预期的动态行为。 – to7be

+0

@ to7be如果它很好地为你工作,不要忘记接受:) – Stewartside

+1

这并没有真正回答OP的问题。 OP想知道如何在SVG的一部分不缩放的情况下制作响应式SVG。这基本上是不可能的。 –

0

** EDITED **

此行为是由上<svg>viewBox属性引起的喜欢进行定位。默认情况下,SVG的纵横比保持不变。您希望此行为在#Triangle#Rectangle-3上,但不在#Rectangle-2上(您希望height增加,但width保持不变)。

我想你会希望添加preserveAspectRatio=none<svg>内联CSS,然后做一些调整(因为弄乱了你的#Triangle#Rectangle-3的长宽比 - 或者替代那种,你可以尝试改变#triangle-2height到与你的包装div相同的高度(在我的JS小提琴中,我已经这样做了,设置#Triangle-2的高度为25vh)。播放窗口的高度 - #Rectangle-2的高度拉长但不改变宽度,虽然我还没有让你的#Rectangle-3动态地粘贴到#Rectangle-2的底部(#Rectangle-3卡在窗口的底部):https://jsfiddle.net/KyleVassella/dnagft6q/6/

我怀疑你会知道如何解决这个问题,但无论哪种方式,我会保持它,你可以在这里阅读了此期间的工作,其中有关于这个问题的更多信息:

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

+0

Thx为不错的链接!在SVG领域有许多基础知识,您必须先了解才能体验成功。 'preserveAspectRatio'非常有帮助。 对我而言,您的解决方案非常适合正确的方向。下一步是自动将#Triangle对齐到顶部,将#Rectangle-3自动对齐到包装DIV的底部。 这个定位的东西对我来说仍然是一个挑战:) thx! – to7be

+1

你的建议是错误的。 'preserveAspectRatio'不是''元素的有效属性。它将不起作用。 –

+0

@Paul LeBeau你是对的,谢谢你指出。我编辑了我的答案。 @ to7be,告诉我一下吧!下次我只是留下链接的评论,我认为在这种情况下会更有帮助(和适当的)。我希望有人过来并一路解决这个问题。睡觉后我会继续努力。 –

3

对于这个particlular用例,我想我会去一个CSS的方法,它可能会(对您的标记)添加一个html元素,如果你不能使用伪元素,但它不会需要JS或笔画宽度或转换元素的手动输入值。

这里是一个办法,使箭头使用段落标签:

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

+0

这也是一个绝对有效的伟大方法。很高兴看到这个问题可以通过伪元素来解决! – to7be

3

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

对于基本形状它很简单。你可以写你的主矩形作为

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

你的第二个矩形是更简单,因为它坐落在0,0所有的时间

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

但与箭头出现在pathes和多边形的问题你不能使用百分比。要解决此问题,有两步解决方案。

先放路径的符号元素:

<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。所以,仅仅翻译使用回20像素:使用这种方法

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

+0

我可以问下来的选民我的回答有什么问题吗?这将是一个乐趣,纠正它... –