Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/468.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SVG中实现偏移路径效果而不使用Javascript或扩展/腐蚀过滤器?_Javascript_Vector_Svg_Effect - Fatal编程技术网

如何在SVG中实现偏移路径效果而不使用Javascript或扩展/腐蚀过滤器?

如何在SVG中实现偏移路径效果而不使用Javascript或扩展/腐蚀过滤器?,javascript,vector,svg,effect,Javascript,Vector,Svg,Effect,我有一个很长时间的项目:一个基本的矢量图形工具,在浏览器中运行,使用SVG和Javascript(也许你们在别处见过类似的东西)。该工具只有非常有限的功能集,因为受众受到限制,目的非常具体,事实上,除了明确允许的功能外,不允许有其他功能(您知道)。缺少的一个特征是多边形和其他图形元素的侵蚀(也称为插入或细化)和膨胀(开始、加厚、加粗) 我已经多次使用Adobe Illustrator的偏移路径效果,使用它,我可以轻松地复制缩小或加厚的图形对象,而不会影响原始对象,因此几乎可以是程序支持的任何对象

我有一个很长时间的项目:一个基本的矢量图形工具,在浏览器中运行,使用SVG和Javascript(也许你们在别处见过类似的东西)。该工具只有非常有限的功能集,因为受众受到限制,目的非常具体,事实上,除了明确允许的功能外,不允许有其他功能(您知道)。缺少的一个特征是多边形和其他图形元素的侵蚀(也称为插入或细化)和膨胀(开始、加厚、加粗)

我已经多次使用Adobe Illustrator的偏移路径效果,使用它,我可以轻松地复制缩小或加厚的图形对象,而不会影响原始对象,因此几乎可以是程序支持的任何对象

我曾尝试在SVG中使用相同的功能,但没有成功

我尝试了以下方法:
-膨胀和腐蚀过滤器,但结果不令人满意()
-服务器端Python的Shapely库,但此解决方案速度太慢,只允许插入或开始基本多边形()
-查找javascript库/代码/函数,它可以更改图形元素的路径数据,但找不到javascript的任何内容

那么,有没有什么有意义的方法来实现这种类似偏移路径的效果以及如何实现呢?

这是一个“回答你自己的问题–”式的回答,但如果你有更好的答案,请自由使用键盘

我只用了几天,所以请不要把我的票投给差距。我对这个问题很感兴趣,它基于可变宽度笔划和遮罩

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

但由于腐蚀过滤器(以及扩张),结果并非在所有情况下都好看。事实上,我从来没有见过一个好看的侵蚀当用来过滤向量对象。见帽子和嘴:

扩张过滤器也有类似的问题(鼻子不好,棒球帽有点乱,还有其他一些不一致):

Adobe Illustrator的所有用户都知道漂亮的路径效果,可用于将各种路径操作应用于形状(对象)。这些效果不会更改原始路径数据,它们只创建对象的修改副本。最有用的方法之一是,它可用于从选定对象偏移指定距离(或类似距离)。SVG:s侵蚀和扩张过滤器与Illustrator的偏移路径效果相似,但其质量作为向量操作(相对于位图)很高

SVG格式在其当前状态下,缺乏对Illustrator类偏移路径的支持,但可以使用可变宽度笔划和遮罩获得相同的功能

让我们深入SVG面具的世界。扩张(或起始路径或加厚)可以通过简单地增加笔划宽度来实现,但侵蚀(或插入路径或变薄)需要更多的东西,例如遮罩。在SVG中,任何图形对象或“g”元素都可以用作将当前对象合成到背景中的alpha掩码()

这意味着不仅对象的填充可以用作遮罩,还可以用作笔划通过调整用作遮罩的路径笔划的宽度,我们可以控制遮罩当前对象(使用遮罩属性将遮罩应用到其中)的数量

我们来举一个使用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”元素的图形内容(在本例中仅为路径数据)包含在此掩码中在上述“使用”元素上定义的笔划宽度将是偏移(侵蚀)效应的量。这个数量在元素中被屏蔽掉了,我们将在下一步提取

好的,让我们先画一个没有遮罩的“头”,看看它有多美:

...
</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”作为图形内容。遮罩效果应用于“使用”元素,并绘制以下形状:

如果我们将两者叠加在每个顶部,我们可以将原始头部与遮罩头部进行比较:

还不错吧?让我们将第一次尝试使用SVG腐蚀过滤版本与屏蔽版本进行比较:

左边的是腐蚀过滤,右边的是遮罩以模仿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:sdi展开