动态调整单个形状的大小而无需扩展整个SVG [英] Resizing single shapes dynamically without scaling the whole SVG

查看:81
本文介绍了动态调整单个形状的大小而无需扩展整个SVG的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个箭头作为SVG,例如,我想根据包裹DIV的宽度更改其长度.

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

除此以外,我想实现以下行为:

是否可以通过简单地在代码中添加百分比值来更改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> 

解决方案

作为一般规则,无法创建其中部分内容无法扩展的可伸缩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> 

I have an arrow as a SVG which's length I want to alter in response to the width of a wrapping DIV (for example).

All my previous attempts have led into this behavior (scaling the whole SVG):

Rather than this, I want to achieve this behavior:

Is it possible to just alter single shapes inside of a SVG by simply adding percentual values to the code? If not, how could I perform this?

SVG as code:

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

解决方案

As a general rule, there is no way to create a scalable SVG where parts of it don't scale. If an SVG has a viewBox, and you scale it, then all the contents will scale. There is no way to mark some of the contents as immune to the scaling.

The nearest you can get is to restrict scaling to the X axis. However the arrowhead will still stretch.

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

If you want a generalised solution, then you have to monitor resize events and update the SVG dynamically.

The limited sneaky clever solution...

Having said all that, there is a clever technique that works in a limited set of circumstances. The limitations are:

  1. The SVG stretches in only one direction.
  2. The "non-scaling" parts are at either or both ends of the stretch
  3. The end parts are solid and don't have any holes.
  4. You are okay with the background of the SVG being a solid color, rather than transparent.

Here is a demo of your shape implemented using this technique. If you resize the window horizontally, you'll see it stretches appropriately.:

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

这篇关于动态调整单个形状的大小而无需扩展整个SVG的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆