如何在SVG中实现偏移路径效应,而不使用Javascript或扩展/删除过滤器?

前端之家收集整理的这篇文章主要介绍了如何在SVG中实现偏移路径效应,而不使用Javascript或扩展/删除过滤器?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个很长的时间项目:一个基本的矢量图形工具,在浏览器中运行,并使用SVG和 Javascript(也许你已经看到其他地方的某些).该工具只有非常有限的功能,因为观众受到限制,目的是非常具体的,实际上不允许有其他功能,而不是明确允许的(你知道).一个错过的功能是侵蚀(也称为插入或稀疏)和扩展(开始,加粗,加粗)多边形和其他图形元素.

我已经使用Adobe Illustrator的偏移路径效果多次,并且可以轻松地使图形对象的图像对象变薄或变厚,而不影响原始对象,因此几乎可以支持该程序.

我已经尝试获得与SVG相同的功能,但没有成功.

我已经尝试过以下内容
– 扩大和侵蚀过滤器,但不满足结果(please see the image here)
– 服务器端的Python的Shapely库,但是这个解决方法太慢了,只允许插入或者只开始基本的多边形(description here)
– 找到javascript库/代码/函数,这可能会改变图形元素的路径数据,但没有发现任何javascript

那么有什么有意义的方法来实现这一点,如偏移路径效应和如何?

解决方法

这是一个“回答你自己的问题 – share your knowledge,Q&A-style”的答案,但如果你有更好的答案,请自由使用你的键盘.

我只用了几天,所以请不要拒绝我的差距.这个问题基于可变宽度的笔画和掩码,我得到了一个有趣的workaround idea.

但是让我们开始你的(或我的)第一个想法.当我们要在SVG中腐蚀(薄)图形对象时,明显的第一个想法是使用erode过滤器:

但是因为erode过滤器(和扩大了)uses pixel data (the rasterized path)的结果并不好看在所有情况下.实际上,我从来没有看到过滤器用于过滤矢量对象的好看.看到帽子和嘴巴:

扩张过滤器有类似的问题(鼻子不好,棒球帽有些尴尬和其他一些不一致):

Adobe Illustrator的所有用户都知道很好的路径效果,可以用于将各种路径操作应用于形状(对象).这些效果不会改变原始路径数据,它们只能创建修改后的对象副本.最可用的是Offset Path Effect,它可以用于从所选对象放下指定的距离(或类似的东西). SVG:侵蚀和扩张过滤器与Illustrator的偏移路径效应具有相似性,但质量作为向量操作(对位图)高.

SVG格式处于当前状态,不支持像Illustrator一样的偏移路径,但是可以使用可变宽度的笔画和掩码获得相同的功能,如here所示.

让我们来看看SVG面具的世界.扩大(或开始路径或增厚)可以通过简单地增加行程宽度来实现,但侵蚀(或插入路径或变薄)需要更多的东西,例如掩模.在SVG中,任何图形对象或“g”元素都可以用作将当前对象合成到背景中的Alpha掩码(W3C SVG 1.1 Recommendation).

上述意味着不仅可以将对象的填充用作掩码,还可以用于描边.并且调整用作掩码的路径的行程宽度,我们可以控制当前对象(使用mask属性应用掩码的对象)被屏蔽了多少.

让我们举一个使用mask的例子.首先我们在SVG中定义一个路径:s defs元素:

<defs>
<path id="head_path" d="M133.833,139.777c1 ...clip... 139.777z"/>
</defs>

当我们在defs元素中定义一个路径时,它不需要在文档的其他部分重复相同的数据.路径的id属性用于引用文档某一点的路径.

现在我们可以在掩码中使用这个路径数据:

<defs>
...
<mask id="myMask" maskUnits="userSpaceOnUse">
<use xlink:href="#head_path" fill="#FFFFFF" stroke="#000000" 
stroke-width="18" stroke-linecap="round" stroke-linejoin="round"/>
</mask>
...
</defs>

‘use’元素引用’path’元素,其id为’head_path’,并指示在该掩码中包含’head_path’元素的图形内容(在这种情况下只有路径数据).在上述’use’元素上定义的笔画宽度将是偏移(侵蚀)效果的量.这个数量被蒙上了元素的情况,我们接下来要画出来.

好的,让我们先画’头’而不遮掩看看它是多么美丽:

...
</defs>
<use x="5" y="5" xlink:href="#head_path" fill="#4477FF" stroke="black"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>

这产生以下形状:

现在测试,我们可以实现使用mask:

...
</defs>
<use x="5" y="5" xlink:href="#head_path" fill="#22EE22" stroke="black"
stroke-width="21" stroke-linecap="round" stroke-linejoin="round"
mask="url(#myMask)"/>

指示上述’use’元素使用’myMask’作为掩码,’head_path’作为图形内容.掩码效果应用于’use’元素,并绘制以下形状:

如果我们堆叠在每个顶部,我们可以将原始的头部与掩蔽的头部进行比较:

一点也不差?我们比较使用SVG erode过滤版本到屏蔽版本的第一次尝试:

左边的一个被侵蚀过滤,右边的一个被屏蔽,以模仿像Illustrator一样的偏移路径效应.帽子和嘴里没有奇怪的文物!

那么怎么扩大呢?有没有办法消除棒球帽上的鼻子不平坦和刮擦的路径?当然.而且这个方法真的很简单,但是有点黑客.幸运的是没有必要使用面具.相反,我们可以调整笔画宽度来实现所需的效果.而且因为中风已经被大胆的使用,为了让黑色的笔触加上粗体(如果有的话),我们必须添加一个额外的元素,稍微更宽的一个元素,并将其放在粗体下面:

<!-- To get the black stroke -->
<use x="220" y="5" xlink:href="#head_path" fill="red" stroke="black"
stroke-width="24" stroke-linecap="round" stroke-linejoin="round"/>
<!-- To get the boldened shape -->
<use x="220" y="5" xlink:href="#head_path" fill="red" stroke="red"
stroke-width="21" stroke-linecap="round" stroke-linejoin="round"/>

这产生以下形状:

这里原始的形状和我们的自定义偏移路径效应应用:

我们的自定义加粗方式如何与扩展过滤器进行比较:

左侧(上))使用SVG扩展过滤器扩张,右侧使用我们的自定义偏移路径效应加粗.很好,我喜欢路径忠实地遵循在给定距离的原始路径,没有棒球帽上的刮擦迹象.

最后我们把所有的电线拉到一起:

左侧(上)使用SVG的扩展/侵蚀过滤器,右侧使用Illustrator模仿的偏移路径效果,这是使用SVG掩码和较厚笔画实现的.你会选哪一个?

结论:我们没有被迫使用Javascript或其他脚本来增加或缩小SVG中的图形元素. SVG的Erode和Dilate过滤器可能有一些用途,但它们不适合高质量的路径“修改”.面具有点复杂使用,但经过少量实验,你熟悉他们.我真的希望SVG在将来会支持本地的偏移路径效应,而不使用这样的黑客.

我在这些例子中使用的形状让你玩过滤器和面具:http://jsfiddle.net/7Y4am/
(至少测试改变行程宽度!)

(抱歉我的英文不好,让母语笑笑直到死,但请记住,我属于人类的94%,不会说英语,但幸运的是我们有Google翻译.)

猜你在找的JavaScript相关文章