gpt4 book ai didi

javascript - 如何在不使用 Javascript 或膨胀/腐 eclipse 过滤器的情况下在 SVG 中实现偏移路径效果?

转载 作者:可可西里 更新时间:2023-11-01 02:00:38 32 4
gpt4 key购买 nike

我有一个很长的项目:一个在浏览器中运行并使用 SVG 和 Javascript 的基本矢量图形工具(也许你已经在其他地方看到过这些)。该工具只有非常有限的一组功能,因为受众受到限制并且目的非常具体,实际上除了明确允许的功能(你知道)之外,不允许有其他功能。一个遗漏的特征是侵 eclipse (也称为插入或细化)和扩张(开始、加厚、加粗)多边形和其他图形元素。

我已经多次使用 Adob​​e Illustrator 的 Offset Path Effect,有了它,我可以轻松制作变薄或变厚的图形对象的副本,而不会影响原始对象,因此几乎可以是程序支持的任何对象。

我试图获得相同的功能以在 SVG 中运行,但没有成功。

我尝试了以下方法:
- 扩张和侵 eclipse 过滤器,但结果不令人满意(please see the image here)
- 服务器端 Python 的 Shapely 库,但这种解决方法太慢并且只允许插入或开始基本多边形(description here)
- 找到javascript库/代码/函数,可以改变图形元素的路径数据,但没有找到javascript

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

最佳答案

这是一个“回答你自己的问题——share your knowledge, Q&A-style”式的答案,但如果你有更好的答案,请随意使用你的键盘。
我只使用了几天,所以请不要低估我的差距。我得到了一个有趣的 workaround idea这个问题是基于可变宽度的笔触和蒙版。
但让我们从你(或我)的第一个想法开始。当我们要在 SVG 中侵 eclipse (细化)图形对象时,显而易见的第一个想法是使用侵 eclipse 过滤器:
但是因为侵 eclipse 过滤器(以及扩张)uses pixel data (the rasterized path)结果在所有情况下都不好看。事实上,我从来没有见过一个漂亮的腐 eclipse 用于过滤矢量对象。看帽子和嘴巴:
Eroded image
dilate 过滤器也有类似的问题( Nose 不好看,棒球帽很乱,还有一些其他的不一致):
Dilated image
Adobe Illustrator 的所有用户都知道漂亮的路径效果,可用于将各种路径操作应用于形状(对象)。这些效果不会更改原始路径数据,它们只会创建对象的修改副本。最有用的方法之一是 Offset Path Effect ,可用于从选定对象开始指定距离(或类似距离)。 SVG:s erode 和 dilate 过滤器与 Illustrator 的 Offset Path Effect 有相似之处,但质量作为矢量操作(相对于位图)高。
当前状态下的 SVG 格式缺乏对类似 Illustrator 的偏移路径的支持,但可以使用可变宽度的笔触和 mask 获得相同的功能,如 here .
让我们深入了解 SVG 蒙版的世界。扩张(或起始路径或加厚)可以通过简单地增加笔画宽度来实现,但侵 eclipse (或插入路径或细化)需要更多的东西,例如 mask 。在 SVG 中,任何图形对象或 'g' 元素都可以用作将当前对象合成到背景中的 alpha 掩码 ( W3C SVG 1.1 Recommendation )。
以上意味着不仅对象的填充可以用作蒙版,还可以用作笔触。 并调整用作 mask 的路径的笔触宽度,我们可以控制当前对象(使用 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' 元素上定义的笔画宽度将是偏移(侵 eclipse )效果的量 .这个数量被屏蔽在元素之外,以防万一,我们接下来要绘制。
好的,让我们先画出没有 mask 的“头部”,看看它有多漂亮:
...
</defs>
<use x="5" y="5" xlink:href="#head_path" fill="#4477FF" stroke="black"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
这会产生以下形状:
Original shape
现在测试,我们可以使用掩码实现什么:
...
</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' 作为图形内容。 mask 效果应用于 'use' 元素并绘制以下形状:
Masked shape
如果我们将它们堆叠在每个顶部,我们可以将原始头部与蒙面头部进行比较:
Original and masked shape
一点也不差?让我们将使用 SVG 侵 eclipse 过滤版本的第一次尝试与屏蔽版本进行比较:
Eroded vs masked
左边一个经过侵 eclipse 过滤,右边一个被屏蔽以模仿类似 Illustrator 的偏移路径效果。帽子和嘴巴里没有奇怪的文物!
那怎么扩容呢?有没有办法消除棒球帽 Nose 上的路径不忠和斗志?当然。这个方法真的很简单,但有点黑客。幸运的是,不需要使用口罩。相反,我们可以调整笔划宽度以达到所需的效果。并且因为笔划已经用于加粗,为了在加粗形状周围获得黑色笔划(如果需要的话),我们必须添加一个具有更宽笔划的元素的额外副本,并将其放置在加粗形状下方:
<!-- 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"/>
这会产生以下形状:
Offset Path Effect applied
这里既有原始形状,也有应用了我们自定义偏移路径效果的形状:
Original and Offset Path Effect applied
我们的自定义粗体与 dilate 过滤器相比如何:
Dilated vs Boldened
左边的(上图)使用 SVG:s dilate 过滤器进行了扩张,右边的使用我们自定义的 Offset Path Effect 加粗。挺好看的,喜欢路径忠实地遵循给定距离的原始路径,棒球帽上没有任何斗志。
最后让我们把所有的电线拉在一起:
Dilate/Origina/Erode vs Offset Path Combined
左边(上图)使用了SVG的dilate/erode filter,右边使用了Illustrator模仿的Offset Path Effect,通过SVG蒙版和粗笔画来实现。你会选择哪一个?
结论 :我们不会被迫使用 Javascript 或其他脚本来加厚或减薄 SVG 中的图形元素。 SVG 的 Erode 和 Dilate 过滤器可能有一些使用目的,但它们不太适合高质量的路径“修改”。面具使用起来有点复杂,但经过几次实验后,您就会熟悉它们。我真的希望 future 的 SVG 能够原生支持 Offset Path Effect,而不是像 hacks 那样使用它。
我对这些示例中使用的形状进行了 jsfiddle 处理,以便您使用过滤器和蒙版: http://jsfiddle.net/7Y4am/
(至少测试以更改笔画宽度!)
(对不起,我的英语不好,让母语者笑到死,但请记住,我属于 94% 的人类,母语不是英语。但幸运的是我们有谷歌翻译。)

关于javascript - 如何在不使用 Javascript 或膨胀/腐 eclipse 过滤器的情况下在 SVG 中实现偏移路径效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12723832/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com