在有关SVG过滤器的系列的下一篇文章中,Sara Soueidan将展示如何使用feDisplacementMap原语使文本与表面纹理匹配。

拟议的系列文章“ SVG过滤效果”,作者:Sara Soueidan,是自由UI / UX界面开发人员,并且是黎巴嫩的许多技术文章的作者,重点关注SVG过滤器的工作,并包括以下文章:
SVG过滤效果
- SVG过滤效果。 第1部分。SVG过滤器101
- SVG过滤效果。 第2部分。 用词形学概述文本
- SVG过滤效果。 第3部分。使用feComponentTransfer的图像后代化效果
- SVG过滤效果。 第4部分 。 带feComponentTransfer的两色图像 。
- SVG过滤效果。 第5部分。使用feDisplacementMap将文本与表面纹理匹配
在文本上应用纹理是图形设计中最受欢迎的文本效果之一。 由于大多数印刷和图形设计已渗透到Web平台,因此,这些效果也已在Internet上使用CSS以及模板,遮罩和裁切路径等SVG功能在Internet上重新创建。 我在Codrops上有一篇文章 ,向您全面概述了您今天可能会对使用CSS和SVG在Web上创建纹理文本的各种方式。 约瑟(Yoksel)谈到了这个话题的另一个领域,并写了一篇关于动画填充文本的文章 。
但是,未修饰的效果之一是与表面纹理匹配的文本。 当文本与表面匹配时,它将采用该表面的形式。 根据所使用的表面和纹理,您可能会得到一些非常吸引人的结果。 这就是我将在本文中介绍的内容。 最有趣的是,所有这些效果都将应用于真实,可搜索和可选择的文本。
使文本与表面纹理匹配:Photoshop的路径
与双色调效果一样,我学习了如何使Photoshop中的文本与表面纹理匹配,并尝试使用SVG滤镜重现该效果。 我在YouTube上找到了此分步教程 。
在Photoshop教程中,设计人员使用所谓的置换图创建了这种效果。 偏移图是一种图像,其颜色信息用于使另一个元素的内容失真。 要创建文本效果,图像纹理将用于使文本变形,使其与纹理的形状匹配。
在Photoshop中,为了匹配表面文字,设计人员执行了以下操作:
- 使图像变色。
- 减少图像中的细节量,将其模糊效果应用1px。
- 将图像另存为置换图。
- 我创建了文本,并使用图像作为位移贴图对其应用了变形滤镜。
- 重新使用原始图像作为文本的背景。
- 然后,他通过在文本中添加一些不透明度并将其与背景图像混合来改善效果。
位移贴图的图像在用于偏移文本之前,在第二步中变得模糊,因为如果图像包含过多或过少的细节,所产生的效果将看起来不太真实。 通常,2px的图像模糊足以获得平均的细节量,这绝对足够。
如果阅读了本系列的前几篇文章,您就会知道分步思考对于使用SVG过滤基元创建或重新创建效果很重要。 您可能已经找到了如何使用SVG过滤原语重现其中一些步骤的方法,其中一些是我们在先前文章中介绍的。
但是,实现此效果的最重要步骤是创建并应用位移贴图。 我们如何在SVG中创建它?
使文本与SVG中的表面纹理匹配
为了从上面的Photoshop教程中重新创建效果,我们首先需要创建一个置换图。 在SVG中, feDisplacementMap原语用于使用置换图来偏移内容。
feDisplacementMap需要两个输入才能得到一个结果。 您要用来偏移内容的图像在in2属性中指定。 in属性保留给您要向其应用偏移效果的输入。
与所有其他原语一样, feDisplacementMap的输入可以是任何东西,从您自己的图形源( SourceGraphic )到另一个过滤操作的结果。 由于我们要将位移图应用于文本源,因此这意味着in属性将具有SourceGraphic作为值。
因此,让我们使用SVG过滤器原语重新创建Photoshop的手动步骤。 在SVG中将文本匹配到纹理的过程与我们在Photoshop中看到的过程非常相似。 我将详细介绍每个步骤。
- 我们使用feImage获得了将用作纹理的图像 。
- 使用feColorMatrix对图像进行去饱和。
- 使用feGaussianBlur将0.5px高斯模糊应用于图像。
- 使用图像通过feDisplacementMap扭曲文本。
- 使用feBlend将文本与背景图像混合,并对其应用透明效果(我们将使用feComponentTransfer降低不透明度)。
- 使用feMerge将两层结合起来,显示其后面的文本和图像。
过滤原语feImage是image元素的过滤器版本,并具有与其相同的属性。 因此,要在滤镜区域渲染图像,我们将使用feImage 。 收到图像后,我们可以将其用作其他过滤操作的输入。 它将用于加载到feColorMatrix操作中使其褪色。
前面我们已经描述了feColorMatrix原语,但是没有提到它带有几个关键字,它们是预定义矩阵的快捷方式。 您可以使用可能的键之一来更改type属性,而不是始终提供矩阵作为输入:
matrix | saturate | hueRotate | luminanceToAlpha
当您要提供自己的矩阵作为矩阵运算的值时,将使用矩阵类型。 其他键添加功能。
要漂白图像,请使用饱和类型。 values属性指示图像变色的大小。 由于我们要使图像完全变色,因此将其设置为0。请注意,这些值以分数表示,其中1(默认值)表示完全饱和,而0表示完全变色(灰色阴影)。
因此,让我们开始将步骤转换为代码:
<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.--> <filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> <!-- Get the image. --> <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage> <!-- Desaturate the image. --> <feColorMatrix type="saturate" values="0" result="IMAGE"/> <!-- ... -->
目前,我们的过滤区域如下:

图_1。 变色后的原始图像。
现在,我们将稍微模糊图像以略微减少细节数量,而不会损失整体质量。 对于这种特殊效果,我决定仅将其模糊0.25px。 您可能需要尝试使用这些值来获得所需的内容,具体取决于所使用的图像和所需的效果。
<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.--> <filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> <!-- Get the image. --> <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage> <!-- Desaturate the image. --> <feColorMatrix type="saturate" values="0" result="IMAGE"/> <!-- decrease level of details so the effect on text is more realistic --> <feGaussianBlur in="IMAGE" stdDeviation="0.25" result="MAP"></feGaussianBlur> <!-- ... -->
现在我们的置换图如下所示:

图_2。 位移图的视图。
使用feDisplacementMap ,我们现在可以使用置换图使文本变形:
<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.--> <filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> <!-- Get the image. --> <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage> <!-- Desaturate the image. --> <feColorMatrix type="saturate" values="0" result="IMAGE"/> <!-- decrease level of details so the effect on text is more realistic --> <feGaussianBlur in="IMAGE" stdDeviation="0.25" result="MAP"></feGaussianBlur> <!-- Use the displacement map to distort the source text --> <feDisplacementMap in="SourceGraphic" in2="MAP" scale="15" xChannelSelector="R" yChannelSelector="R" result="TEXTURED_TEXT"></feDisplacementMap> <!-- ... -->
此时,我们用来扭曲文本的图像不再显示,因为它用于创建扭曲的文本。 因此,目前的过滤区域仅包含与置换贴图的织物的形状和纹理匹配的文本:

图_3。 显示变形的文本。
您已经可以看到织物纹理如何在文本边缘周围成形。 太好了
像在Photoshop手册中一样,我们将再次使用feImage通过文字重新显示图像:
<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.--> <filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> <!-- Get the image. --> <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage> <!-- Desaturate the image. --> <feColorMatrix type="saturate" values="0" result="IMAGE"/> <!-- decrease level of details so the effect on text is more realistic --> <feGaussianBlur in="IMAGE" stdDeviation="0.25" result="MAP"></feGaussianBlur> <!-- Use the displacement map to distort the source text --> <feDisplacementMap in="SourceGraphic" in2="MAP" scale="15" xChannelSelector="R" yChannelSelector="R" result="TEXTURED_TEXT"></feDisplacementMap> <!-- Re-display the image as a background image --> <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" result="BG"></feImage> <!-- ... -->
最后,我们想将文本与背景混合以提高效果。 我们将使用feColorMatrix将文本的不透明度降低到0.9,然后将feBlend原语应用于文本以与背景混合。
像CSS混合模式一样 ,我们有16种混合模式可供选择。 乘法模式适合我们的效果。 在Photoshop手册中,设计人员使用了SVG / CSS中没有的线性记录。
feBlend将接受两个输入进行混合:文本和背景图像:
<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.--> <filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> <!-- Get the image. --> <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage> <!-- Desaturate the image. --> <feColorMatrix type="saturate" values="0" result="IMAGE"/> <feGaussianBlur in="IMAGE" stdDeviation="0.25" result="MAP"></feGaussianBlur> <!-- Use the displacement map to distort the source text --> <feDisplacementMap in="SourceGraphic" in2="MAP" scale="15" xChannelSelector="R" yChannelSelector="R" result="TEXTURED_TEXT"></feDisplacementMap> <!----> <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" result="BG"></feImage> <!-- Reduce the opacity of the text --> <feColorMatrix in="Textured_Text" result="Textured_Text_2" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 .9 0" /> <!-- Blend the text with the background --> <feBlend in="BG" in2="Textured_Text_2" mode="multiply" result="BLENDED_TEXT"></feBlend> <!-- ... -->
最后,但不是按值,我们将使用feMerge在背景图像层的顶部覆盖一个新的混合文本层:
<!-- I'm extending the filter region just to increase its area for visual purposes. This is not required or needed for the effect to work.--> <filter id="conform" x="-50%" y="-50%" width="200%" height="200%"> <!-- Get the image. --> <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none"></feImage> <!-- Desaturate the image. --> <feColorMatrix type="saturate" values="0" result="IMAGE"/> <!-- decrease level of details so the effect on text is more realistic --> <feGaussianBlur in="IMAGE" stdDeviation="0.25" result="MAP"></feGaussianBlur> <!-- Use the displacement map to distort the source text --> <feDisplacementMap in="SourceGraphic" in2="MAP" scale="15" xChannelSelector="R" yChannelSelector="R" result="TEXTURED_TEXT"></feDisplacementMap> <!----> <feImage xlink:href="..." x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" result="BG"></feImage> <!-- Reduce the opacity of the text --> <feColorMatrix in="Textured_Text" result="Textured_Text_2" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 .9 0" /> <!-- Blend the text with the background --> <feBlend in="BG" in2="Textured_Text_2" mode="multiply" result="BLENDED_TEXT"></feBlend> <!-- Layer the text on top of the background image --> <feMerge> <feMergeNode in="BG"></feMergeNode> <feMergeNode in="BLENDED_TEXT"></feMergeNode> </feMerge> </filter> <text dx="60" dy="200" font-size="10em" font-weight="bold" filter="url(#conform)" fill="#00826C"> organic </text>
这是我们的最终结果:

图_4。 最终结果。
在SVG中使用偏移贴图的注意事项
feDisplacementMap元素具有三个属性,这些属性确定置换图如何影响原始图形:
- xChannelSelector :指示从in2使用哪个颜色通道(R / G / B / A)进行水平偏移;
- yChannelSelector :指示从in2使用哪个颜色通道(R / G / B / A)进行垂直偏移;
- 标度 :确定图像失真量。 比例越高,失真效果越强。 您可能会尝试使用该值以获得所需的结果。
使用图像偏移SVG过滤器中的内容时,要记住的最重要的事情是图像和内容要遵守CORS规则。 确保从同一来源提供图像和内容,以使浏览器不会跳过偏移操作。
您也可以将图像嵌入过滤器中(在feImage中 ),并将其用作置换贴图。 来自Gabi的这支笔是一个很好的例子,它使用内置的SVG模式使原始图像变形。 我最喜欢这种圆形图案,形成像涟漪一样的效果。
将转换应用于来源
在用于此效果的Photoshop教程中,设计人员将旋转变换应用于文本,这为整体效果添加了良好的触感。
如果将旋转变换应用于要应用滤镜的<text>,则整个滤镜区域将被旋转,包括背景图像:

图_5。 旋转后,背景旋转时的图像视图。
如果将其他样式应用于源文本,也会发生这种情况。 例如,如果将不透明度参数<text>设置为0.5,这也会影响文本和背景图像。
为了旋转文本,而不是旋转过滤区域的其余部分,我们可以将文本包装在一个组( <g> )中,然后对该组应用过滤器,然后对文本应用旋转变换。 这样可以确保仅旋转文本,而现在由包装组定义的其余过滤区域仍不受转换的影响。 该方法由Amelia Bellamy-Royds提供 。
<g filter="url(#conform)"> <text dx="60" dy="200" font-size="10em" transform="translate(-20 30) rotate(-7)" fill="#00826C">organic</text> </g>
我通过添加重新计数来稍微改变了转换,以确保文本保持在过滤区域的中心。 现在,此转换的结果如下所示:

图_6。 与重新计数一起转换以使文本居中。
请注意,我使用SVG变换属性(而不是CSS)将旋转变换应用于文本,因为在撰写本文时,Internet Explorer和MSEdge不支持SVG元素中的CSS变换。
真实演示
目前,这种文本偏向效果在所有主流浏览器(包括MSEdge)中均有效。 下面是MSEdge中效果的屏幕截图:

图_7。 MSEdge中的文本处理是什么样的。
但是,Chrome最近停止了对文本应用变形效果。 此线程包含有关此问题的其他信息。 但是,其他过滤操作也可以正常使用,因此可以很好地应用,因此在Chrome解决此问题之前,您可以看到文本与背景混合在一起,并且边缘没有失真。 以下是该演示在Chrome中的屏幕截图:

图_8。 当前的文本失真效果在Chrome中是什么样的。
您可以在此处观看演示。
结论
我希望您已经开始享受SVG滤镜的强大功能,并正在考虑可以使用它们创建的许多功能和效果。
如果您喜欢将文本与表面纹理匹配的想法,那么您当然想学习如何在SVG中创建自己的纹理。 是的,您没看错。 SVG可以创建纹理 。
在下一篇文章中,我们将学习如何结合使用SVG生成的噪声和光效果来创建简单的纹理。 和我们在一起。