拟议的系列文章“ SVG过滤效果 ”,作者:Sara Soueidan,是自由UI / UX界面开发人员,并且是黎巴嫩的许多技术文章的作者,重点关注SVG过滤器的工作,并包括以下文章:
SVG过滤效果
- SVG过滤效果。 第1部分。SVG过滤器101 。
- SVG过滤效果。 第2部分。用词形学概述文本
- SVG过滤效果。 第3部分。使用feComponentTransfer进行图像后代化的效果 。
- SVG过滤效果。 第4部分 。 带feComponentTransfer的两色图像 。
- SVG过滤效果。 第5部分。使用feDisplacementMap将文本与表面纹理匹配
在SVG滤镜系列的第二部分中, Sara Soueidan向我们介绍了feMorphology滤镜,并举例说明了如何使用它来创建有趣的效果。

在有关SVG滤镜效果的系列文章的第一部分中 ,我们介绍了SVG滤镜的基础知识-如何创建它们以及如何使用它们。 我们还检查了一些最常用的过滤操作,即 过滤原语。 因为 由于我们将重用此信息,因此我建议在继续阅读本文章之前,先停止阅读该文章。
<feMorphology>是我最喜欢的SVG过滤器操作之一。 它也是最简单的操作之一,将其应用于各种元素的结果始终是可预测的。
什么是变形?
变形是指更改或更改对象的形状或外观。
形态过滤器对物体的形状起作用。 它提供了两个预定义的形状转换:腐蚀(即变薄或缩小)和扩展(即A.增厚或扩展)。 换句话说, feMorphology原语可用于压缩或扩展元素。
从技术上讲,这两个操作都在像素级别上进行,将像素扩展到相邻像素( 膨胀 )或破坏受控像素边缘处的相邻像素( 侵蚀 ),同时将轮廓保持在该像素的边界处。 像素扩展的值或用于“拉伸”或“扩展”像素的相邻像素的数量由radius参数确定。
<feMorphology in=".." result=".." operator="dilate || erode" radius=""> </feMorphology>
变形半径可以表示为圆形或椭圆形的半径。 从输入像素开始,包围在此半径的圆中的所有相邻像素都被视为单个像素社区,并将用于扩展或腐蚀效果。
但是,实际上,半径实际上代表了称为结构元素的核的大小,它更像矩阵。 现在,足以将其表示为一个小矩形,其宽度和高度由radius属性中指定的像素指定。

要使用滤镜,我们不需要研究像素级变形所带来的繁琐小事情。 只需知道您可以在feMorphology中提供一个或两个半径值, 即可确定元素的压缩或扩展量。 如果在radius属性中指定了两个数字,则第一个将对应于x半径,第二个将对应于y半径。
图像变形
如果将feMorphology操作应用于图像,那么通常会有两个可预测的结果:
- 如果使用侵蚀运算符,则图像大小减小;如果使用 膨胀运算符,则图像大小增大。
- 对于任何操作员,图像看起来都好像是用大画笔刷出的,带有少量小细节。
因此,为了将变形效果应用于图像,我们的代码应如下所示:
<svg width="450" height="300" viewBox="0 0 450 300"> <filter id="erode"> <feMorphology operator="erode" radius="3"></feMorphology> </filter> <image xlink:href="..." width="90%" height="90%" x="10" y="10" filter="url(#erode)"></image> </svg>
在此片段中,我们将图像(以像素为单位)模糊(压缩)3个像素。 下图显示了此代码的结果。 请注意,右侧的图像尺寸略小:

图_2。 右边是将变形的模糊效果应用于左边图像的结果。
现在,如果我们保持相同的变形半径并将运算符从腐蚀变为扩张 ,效果将相似,但也将明显不同:

图_3。 在右边,对左边的图像应用了dilate morph操作的结果。
在这两种情况下,图像看起来都像是其自身的抽象绘画版本,并且其整体大小会随着像素的扩展或收缩而变化。
但是除了这些结果之外,您可能首先注意到的是这两种效果中的每一种所引起的色差: 侵蚀会创建具有很多暗像素的图像,而膨胀则会使结果变亮。 这是由于以下事实:
- 侵蚀 (默认使用此值)为每个像素分别为通道R,G,B和A设置其社区的最低亮度或最高不透明度;
- 扩大每个像素的每个通道的值,使其值与其社区的最亮或最不透明值相对应。
抛开技术细节,将feMorphology应用于图像几乎总是具有相同的结果:压缩或拉伸图像的一小部分,作为具有深色或浅色主轮廓的图像的副本。
但是,将feMorphology应用于单色元素(例如文本)只会压缩或拉伸它,而不会引起任何明显的像素颜色变化,因为我们仍然只能使用一种颜色...
使用特征形态向文本添加颜色轮廓
现在,我们可以使用该文本的stroke属性在SVG中的文本上添加轮廓。
<!-- Adding an outline to SVG text using strokes --> <text font-size="80px" dx="100" dy="200" font-weight="700" stroke="deepPink" stroke-width="3px">Stroked Text</text>
添加一条通常以文本边缘为中心的路径,以使其一半的厚度被文本本身覆盖,从而使文本变薄,即使这不是故意的。 相反,我们可以使用feMorphology将文本扩展到轮廓或笔触的粗细 。
除非另有说明,否则文本通常只有一种颜色。 因此, feMorphology可应用于文本,以减少或增加文本的粗细。 一旦使用feMorphology扩展了文本 ,就可以将其用作其他过滤器基元的输入,以创建文本轮廓,这正是我们所需要的。
在研究如何执行此操作之前,请看一下该图,该图显示带圆圈轮廓的文本与使用feMorphology添加的轮廓之间的区别。

图_4。 比较源文本,带有笔触的文本和使用feMorphology创建的轮廓。
请注意,与添加了feMorphology的第三行文本相比,添加平滑轮廓后第二行的源文本变得更细。
因此,让我们逐步创建带有轮廓的彩色文本片段。 这是我们将努力争取的结果:

图_5。 最终结果。
因此,我们将创建一个包含文本和一个用于启动简单扩展操作的过滤器的SVG。 文本扩展名的大小取决于我们要获得的轮廓的粗细。
<svg width="900" height="200" viewBox="100 0 900 200"> <filter id="outline"> <feMorphology in="SourceAlpha" result="DILATED" operator="dilate" radius="4"></feMorphology> </filter> <!-- DILATED TEXT --> <text font-size="85px" dx="125" dy="130" font-weight="700" filter="url(#outline)">upgrade yourself</text> </svg>
上面的代码将获取文本的Alpha通道,它只是文本的黑色版本,并将字体粗细增加了4px。 此阶段的代码结果如下:

图_6。 加粗后的文字。
...与源文本相比,源文本具有深蓝色的填充颜色:

图_7。 源文本。
为了创建轮廓效果,我们将源文本覆盖在扩展文本的顶部,仅使扩展文本的边缘(我们的附加4px)在源文本周围可见,使它们看起来像一条路径。 文本覆盖其轮廓(扩展文本)将使用feMerge完成。 我们如何在上一篇文章中研究了如何做到这一点。
在将轮廓放置在文本周围之前,我们需要做的其他事情就是为轮廓本身上色。 就像我们在上一篇文章中所做的一样,用所需的颜色填充滤镜区域,然后在颜色层中添加已经扩展的文本层,即 我们的电路使用in运算符。 结果,将仅显示与扩展文本相交的那些颜色填充部分,从而对其进行着色。 然后,我们将所得的颜色轮廓与源文本结合在一起,以获得所需的结果。
现在我们的代码如下:
<svg width="900" height="200" viewBox="100 0 900 200"> <filter id="outline"> <feMorphology in="SourceAlpha" result="DILATED" operator="dilate" radius="4"></feMorphology> <feFlood flood-color="#32DFEC" flood-opacity="1" result="PINK"></feFlood> <feComposite in="PINK" in2="DILATED" operator="in" result="OUTLINE"></feComposite> <feMerge> <feMergeNode in="OUTLINE" /> <feMergeNode in="SourceGraphic" /> </feMerge> </filter> <!-- DILATED TEXT --> <text font-size="85px" dx="125" dy="130" font-weight="700" filter="url(#outline)">upgrade yourself</text> </svg>
在SVG中创建过滤效果的过程包括以小顺序操作的形式表示最终结果,将一个操作的结果用作另一操作的输入,并最终组合由它们创建的所有层以获得最终结果。
这是上面代码的演示:
文本的填充颜色可以在CSS中或使用fill属性在text元素中指定。 可以在feFlood图元的Flood-Color属性中设置轮廓颜色。
太好了! 如果要更改轮廓的颜色? 您将不得不再次使用feFlood原语,并将颜色填充与轮廓结合起来。 每次您想要更改轮廓的颜色时,都必须一次又一次地执行相同的操作。 诚然,这太累了。 幸运的是,有一种更简单的方法。
敲出文字
除了为文本添加轮廓外,我们还可以创建轮廓,即 浮雕文字,这意味着文字的内部将被“切除”,因此您可以通过轮廓看到其背后的背景。 这种效果的一个示例可能看起来像下一个GIF上的文本,该文本显示了背景颜色的变化以及如何在我们的文本内看到此背景。 这是我们将在本节中创建的演示:

图_8。 浮雕文字的示例。
这种效果更易于创建,并且执行该效果所需的代码明显更短。 此处的主要区别在于,我们不会在扩展文本的顶部分层,而是使用相同的源文本来剪切扩展文本的内部。 这意味着将仅保留扩展文本的增加的粗细,而将删除内部部分,从而仅留下轮廓。
如果您不是捕获和扩展文本的Alpha通道(默认情况下为黑色),而是捕获源文本本身(可以具有任何填充颜色!),将其展开,然后再次使用该文本切出扩展文本的内部,则会得到一个轮廓,它来自源代码本身。 这意味着该路径的颜色将始终与源文本的颜色匹配。 并且由于我们可以确定CSS中源文本的填充颜色,因此这意味着您拥有与其样式分开的文本轮廓。 (不用担心!)然后,您可以随时将此过滤器应用于任何文本,并可以在CSS中随时更改此文本的颜色,而无需配置过滤器代码。 现在,我们改进的代码如下所示:
<svg width="900" height="450" viewBox="0 0 900 450"> <filter id="outliner"> <!-- Start by grabbing the alpha channel of the text and dilating it--> <feMorphology operator="dilate" radius="8" in="SourceAlpha" result="THICKNESS" /> <!-- Next, grab the original text (SourceGraphic) and use it to cut out the inside of the dilated text --> <feComposite operator="out" in="THICKNESS" in2="SourceGraphic"></feComposite> </filter> <text dx="100" dy="300" filter="url(#outliner)" letter-spacing="10px">SVG Rocks</text> </svg>
使用好的字体,我们的演示现在看起来像这样:

图_9。 我们工作的结果。
在样式表中,我们可以选择SVG的轮廓色和背景色。 您还可以通过SVG内部的文本选择图像。 在下面的代码中,我无缘无故地使用CSS动画来更改背景颜色,只是它很漂亮。
svg text { font-family: 'Bangers', cursive; font-size: 150px; letter-spacing: 13px; fill: #000; /* This fill color determines the color of the outline */ } svg { background-color: gold; animation: colorsssss 2s linear infinite; animation-delay: 3s; } @keyframes colorsssss { 50% { background-color: deepPink; } }
上面的SVG过滤器可以像HTML一样通过SVG重用。 如果要将其应用于HTML元素,可以使用filter属性来完成; 只需将过滤器放入HTML并在CSS中“调用”即可:
h2 { filter: url(#outliner); /* You can change the color of the outline here by changing the color of the heading */ color: deepPink; }
我们完成的演示包含一个HTML头,其中应用了过滤器:
关于此过滤器配方,我最喜欢的事情是它可以用作视觉增强。 如果浏览器不支持SVG过滤器,或者不支持CSS过滤器,或者不支持将SVG过滤器应用于HTML元素,则用户将收到不带大纲的半透明源文本。 哦,还有蛋糕上的樱桃吗? SVG和HTML文本都将完全可搜索和可编辑。 万岁进步! SVG万岁!
结论
在SVG中仅使用两次过滤操作,就可以将所选文本的效果应用于SVG或HTML的文本内容。 将此过滤器放入HTML中,并在需要时使用它。
在本系列的下一篇文章中,我们将研究feComponentTransfer ,这是我最喜欢的过滤器原语之一,并了解它是如何工作的以及可以使用它产生什么效果。 和我们在一起。