使用 SVG 中 vector-effect 属性来解决边框(stroke)缩放问题

这是我的一个关于SVG的应用的技术分享网站svgtrick.com,会同步一些文章到这里来,更多关于SVG技术应用可以去网站看看。

这篇文章来看看在SVG中SVGTiny12vector-effect这个属性以及使用它来解决SVG在缩放过程中会产生边框不定宽的问题,比如随着SVG增大,边框也会按比例增大,如下图所示:

使用 SVG 中 vector-effect 属性来解决边框(stroke)缩放问题

从上图中就可以看到中间icon的边框明显比旁边的两个icon的边框要粗一点。

在前一段时间的一个项目中,使用SVG缩放的时候遇到这个边框问题。

具体问题是,在一个项目中我把一个icon定义在SVG中的symbol元素中,这样就可以方便在不同的地方引用这个icon。根据不同的场景,它的宽高不一样,这个时候就可以任意放大缩小SVG的尺寸而不失真。众所周知,SVG是矢量图形,所以可以任意放大缩小它的尺寸而保持不失真,这也是它大受欢迎的一个原因。

在实际使用的过程中,有一些icon是由边框组成的,无论在什么情况下边框的宽度都应该为1px。而当你对一个SVG进行缩放的时候,它会把边框也进行缩放,比如当你把一个SVG的icon放大两倍的时候,它会把对应的边框也会放大两倍。而我们的需求是,无论怎么样缩放SVG,边框都应保持不变。

Vector Effect 属性

程序员就是一个不断的挖坑填坑并以此为乐的一类人。在解决这个问题的过程中,我在W3C标准的网站上发现了一个很不起眼的SVG属性vertor-effect,并且它有一个non-scaling-stroke。正如这个属性表示的那样,它就是用来阻止SVG对边框进行缩放的。

下面来具体看看代码:

<!-- reusable symbols -->
<svg>
  <symbol id="Icon-plus" viewBox="0 0 50 50">
    <circle cx="25" cy="25" r="20" fill="none" stroke="#fff" stroke-width="2"/>
    <path d="M25 15 L 25 35" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round"/>
    <path d="M15 25 L 35 25" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round"/>
  </symbol>
</svg>

<!-- actually using the symbol -->
<svg width="50" height="50">
  <use xlink:href="Icon-plus"/>
</svg>

可以看到下面SVG的宽和高和symbol的viewBox的值是一样的,icon的边框都是2px。这样是没问题的,当我对它进行缩放的时候,问题就出现了。比如我指定icon的宽和高为200px:

<svg width="200" height="200">
  <use xlink:href="Icon-plus"/>
</svg>

可以看到icon的尺寸变成200px了,同时它的边框也加粗了。相对于原来的尺寸增加了4倍,边框也增加到了8px。有了vector-effect这个属性,解决这个问题就很简单了。在不需要放大的SVG元素上添加vector-effect属性并且设置它的值为non-scaling-stroke就可以了。

<circle vector-effect="non-scaling-stroke"/>
<path vector-effect="non-scaling-stroke"/>
<path vector-effect="non-scaling-stroke"/>

现在,无论你怎么对它进行缩放,它的边框永远是2px。

使用 SVG 中 vector-effect 属性来解决边框(stroke)缩放问题

中间的icon是没有设置vector-effect属性的。

源码

原文地址,基于自己的理解翻译而成。

相关推荐