滤镜在摄影中非常流行。您几乎可以在每个照片编辑应用程序或网站上找到它们,并且一些相机具有内置的过滤器选项,因此您以后不必编辑照片。
CSS 有几个过滤器可以帮助改善网站的视觉效果。您可以使用该filter属性将它们直接应用于 Web 元素,也可以将它们应用于具有该属性的元素后面的区域backdrop-filter。
使用这些滤镜,您可以模糊图像、调整对比度和饱和度、更改色调、降低不透明度等等!
在这篇文章中,我们将专门学习一组独特而强大的工具:SVG 过滤器。但在我们继续之前,让我们对 SVG 做一些介绍。
-
什么是 SVG?
-
使用带有 SVG 的 CSS 过滤器
-
过滤基元
-
feGaussianBlur
-
feDropShadow
-
feMorphology
-
feTurbulence
-
feDisplacementMap
-
feColorMatrix
-
feConvolveMatrix
-
feComponentTransfer
-
feOffset
-
feMerge
-
feFlood
-
feComposite
-
feImage
-
feBlend
-
feDiffuseLighting
-
feSpecularLighting
-
feTile
-
-
浏览器支持
什么是 SVG?
SVG 或 Scalable Vector Graphics 是一种基于 XML 的矢量图像格式,用于显示二维图形。XML 是另一个花哨的首字母缩写词,代表可扩展标记语言。XML 用于存储和传输数据,并定义您的标签。
回到 SVG。SVG 兼作图像和文档格式。JPEG 和 PNG 等常规图像格式由放大时通常会丢失质量的像素组成。
SVG 的不同之处在于,无论您放大多少,它们都能保持质量。这是可能的,因为它们是由数学公式组成的。
让我们看看 SVG 的底层是什么。
首先,在代码编辑器中打开 SVG 图像。这是您可能会发现的屏幕截图:
超过 20 万开发人员使用 LogRocket 来创造更好的数字体验了解更多 →
这段代码构成了一个复杂的形状。我们可以在代码行中控制图像的颜色、大小和其他特征。让我们创建一个更简单的形状,一个圆形:
<正文> <svg width="400" height="400"> <circle cx="200" cy="200" r="100" fill="#553c9a"> </svg> </正文>
我们有一个紫色的圆圈!
stroke我们可以通过添加一个值将这个圆圈变成一个环。描边是边框,我们可以将fill颜色设置为transparent。
<正文> <svg width="400" height="400"> <circle cx="200" cy="200" r="100" fill="透明" stroke="#553c9a" stroke-width="20px"> </svg> </正文>
结果是这样的:
可以通过组合不同的 SVG 来创建复杂的图像。SVG 用于图标、徽标或作为背景图像。他们也可以动画!
使用带有 SVG 的 CSS 过滤器
CSS 过滤器主要限于图像,并且相当容易使用。另一方面,SVG 过滤器可以应用于图像(SVG 和其他格式)、文本和所有其他 HTML 元素。CSS 过滤器实际上是 SVG 过滤器的一个子集。
SVG 过滤器使用<filter>元素和一组称为过滤器原语的函数。这些函数是创建效果的子元素。
<filter>CSS属性将filter通过id.
过滤基元
首先,创建一个svg元素,其中filter嵌套了一个元素。然后,在图像之前添加基元(或您希望应用过滤器的任何元素)。
有 17 个过滤器原语,它们是:
-
feGaussianBlur
-
feDropShadow
-
feMorphology
-
feTurbulence
-
feDisplacementMap
-
feColorMatrix
-
feConvolveMatrix
-
feComponentTransfer
-
feOffset
-
feMerge
-
feFlood
-
feComposite
-
feImage
-
feBlend
-
feDiffuseLighting
-
feSpecularLighting
-
feTile
“fe”代表过滤效果。从名称中,我们可以了解它们会产生什么效果。让我们看一个基本的 SVG 过滤器语法:
<svg> <过滤器id=""> <!--Filter Primitives go in here--> </过滤器> </svg>
每个 SVG 原语都有自己独特的一组属性,用于创建效果。其中一些过滤器原语可以自己正常工作,但有些必须与其他原语结合使用。
有很多东西要讲,所以让我们开始吧。
来自 LogRocket 的更多精彩文章:
-
不要错过来自 LogRocket 的精选时事通讯The Replay
-
使用 React 的 useEffect优化应用程序的性能
-
在多个 Node 版本之间切换
-
了解如何使用 AnimXYZ 为您的 React 应用程序制作动画
-
探索 Tauri,一个用于构建二进制文件的新框架
-
比较NestJS 与 Express.js
-
发现TypeScript 领域中使用的流行 ORM
feGaussianBlur
SVG 是基于数学公式的,所以使用高斯模糊滤镜是正确的。该滤镜以已故数学家卡尔·弗里德里希·高斯的名字命名,并应用数学函数来模糊图像。
首先,您需要一张图片。这是来自freepik.com的一个:
接下来,我们将在 HTML 文件中创建 SVG 语法:
<svg> <filter id="模糊"> <feGaussianBlur stdDeviation="5" in="SourceGraphic" result="BLUR"></feGaussianBlur> </过滤器> <图片 xlink:href="2833.jpg" filter="url(#blur)"></image> </svg>
现在,我们将feGaussianBlur在filter元素中添加 SVG 过滤器原语。图元内部的一些属性会对产生的模糊产生影响。
第一个属性是stdDeviation,它调节模糊量。
接下来是in,对于输入,它定义了过滤器的应用位置。在这种情况下,它是SourceGraphic,这是我们的图像。SourceGraphic也可以是文本。
本例中的最后一个属性是result. 我们用它来命名过滤器。in在使用多个过滤器时,这可用作参考。
这是应用了过滤器的结果图像:
如前所述,SVG 过滤器可以使用filter属性和url指向外部应用id:
<svg> <filter id="模糊"> <feGaussianBlur stdDeviation="5"></feGaussianBlur> </过滤器> </svg>
最后,将它与filterCSS 属性一起应用:
图像{ 宽度:1000px; 高度:自动; 过滤器:网址(#blur); }
feDropShadow
这个过滤器非常简单,并在元素后面添加了阴影。
从语法开始:
<svg> <filter id="模糊"> <feDropShadow in="SourceGraphic" dx="10" dy="10"></feDropShadow> </过滤器> </svg>
和属性分别定义了阴影沿 x 和 y 轴的位置dx。dy结果是图像后面的阴影非常暗:
feMorphology
形态学是对形式、形状和结构的研究。原feMorphology语用于改变或变形元素的形式。
它适用于operator接受两个值中的任何一个的属性,dilate或者erode,以及radius定义膨胀或腐蚀量的 a。对于dilate, 的像素SourceGraphic向外扩展。erode相反。
让我们比较一下。首先是dilate:
<svg> <filter id="模糊"> <feMorphology in="SourceGraphic" operator="dilate" radius="5"> </fe形态> </过滤器> </svg>
结果:
现在让我们看看erode:
<svg> <filter id="模糊"> <feMorphology in="SourceGraphic" operator="erode" radius="5"> </fe形态> </过滤器> </svg>
结果:
所有的星星都去哪儿了?
从这些结果中,我们可以看到,dilate与来自erode. 亮度是由于图像的像素扩展,反之亦然。
feTurbulence
这个过滤器原语的效果唯一真正的解释就在它的名字里:湍流。它使用两个属性:baseFrequency和numOctaves。
<feTurbulence in="SourceGRaphic" baseFrequency="0.01 0.02" numOctaves="1" 结果="噪声"> </fe湍流>
结果是图像上的噪声效果:
让我们解释一下属性。
baseFrequency控制 x 和 y 方向上的失真或噪声量。较高的baseFrequency值会减小失真图案的大小。它可以包含两个值,如果使用一个值,它会同时覆盖 x 和 y 轴。
numOctaves也是一个噪声函数,控制滤波器效果中的八度音阶数。使用 a baseFrequencyof "0.01 0.02",我们得到以下结果:
最终,由您决定八度音阶的数量和频率的数量。玩转价值观,看看你想出了什么。请记住,他们不接受负值。
feDisplacementMap
置换贴图是用于更改另一个元素的内容的图像。一个元素的纹理可以应用于另一个元素。
对于这个 SVG 过滤器原语,我们需要两个输入:in和in2. 一个将保存原始图形,另一个将是用作置换贴图的图像。
<svg> <filter id="湍流"> <feTurbulence type="turbulence" baseFrequency="0.01 0.02" numOctaves="1" result="NOISE"></feTurbulence> <feDisplacementMap in="SourceGraphic" in2="NOISE" scale="50"> </feDisplacementMap> </过滤器> </svg>
现在来看看结果。图像遵循feTurbulence过滤器创建的失真模式:
我们可以更进一步,通过添加一些波浪动画来完成水汪汪的外观:
<svg> <filter id="波浪形"> <feTurbulence id="turbulence" type="turbulence" numOctaves="1" result="NOISE"></feTurbulence> <feDisplacementMap in="SourceGraphic" in2="NOISE" scale="50"> </feDisplacementMap> <animate xlink:href="#turbulence" attributeName="baseFrequency" dur="60s" keyTimes="0;0.5;1" values="0.01 0.02;0.02 0.04;0.01 0.02" repeatCount="indefinite"></animate> </过滤器> </svg>
请注意,第一个过滤器原语现在有一个id. 这就是我们正在制作的动画。
接下来,我们将使用<animate>元素来定义动画。该元素将包含xlink:href,指向将被动画化的过滤器。之后是attributeName,我们制作动画的原始属性是baseFrequency.
接下来,我们使用dur和设置持续时间keyTimes。这些本质上是@keyframes。
values``baseFrequency包含用设置的停止点的新值keyTimes。
最后,我们已repeatCount设置为indefinite使效果循环运行。
这是结果:
我们还可以使用常规animation和transitionCSS 属性或一些 JavaScript 来制作动画。
feColorMatrix
此 SVG 过滤器用于修改元素的色调和饱和度。它适用于一个type属性和四个可能的值:matrix、saturate、hueRotate和luminaceToAlpha。
对于matrix,使用 RGBA 颜色矩阵或网格来应用滤镜效果value。
<svg> <过滤器> <feColorMatrix in="SourceGraphic" type="matrix" 值=“1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"> </过滤器> </svg>
上面的语法不会改变图像的颜色。让我们看看每个颜色通道。
玩转这些值,看看你能想出什么色调、阴影和色调!
接下来,我们有saturate. 这使用values0 和 1 之间的值来控制图像中的黑白量。
<svg> <filter id="饱和"> <feColorMatrix in="SourceGraphic" type="saturate" values="0.5"/> </过滤器> </svg>
结果:
接下来是hueRotate. 此属性将图像的颜色围绕色轮旋转特定角度。让我们首先向您展示色轮:
现在让我们使用属性:
<feColorMatrix in="SourceGraphic" type="hueRotate" values="60"/>
浏览器检测图像中的每种颜色,并沿色轮将每种颜色旋转 60 度。这将是生成的图像:
决赛type是luminaceToAlpha。这基本上通过移除 Alpha 通道将图像变成半透明负片。
如果给定正确的matrix网格值,则可以实现与其他效果相同的效果。
feConvolveMatrix
从一个矩阵到下一个矩阵!此过滤器原语为图像添加卷积效果或内核。它用于使用像素组合进行模糊、边缘检测、锐化、浮雕和斜切。
我们可以使用网格中的一些随机值来演示微妙的故障效果:
<svg> <filter id="convolve"> <feConvolveMatrix kernelMatrix ="1 -4 1 1 0 -8 1 0 -4" /> </过滤器> </svg>
结果:
让我们和原作对比一下,看清楚效果:
feComponentTransfer
此原语类似于feColorMatrix,但代替网格,每个颜色通道 (RGBA) 是一个单独的函数。就像使用矩阵一样,我们可以通过操纵这些通道的颜色强度来调整图像的对比度。
这是它的样子:
以下是使用此示例中给出的值的工作原理:
例如,在红色通道中,颜色强度范围从 0 到 1。我们使用了四个值,因此 1 除以 4。现在我们有四个相等的红色范围:0-0.25、0.25-0.5、0.5 –0.75 和 0.75–1。
任何介于 0–0.25 之间的红色值都将被分配到第一个值,tableValues依此类推。相同的原理可用于多达 10 个值。
这个过滤器原语可以使用多种功能,我们要研究的第一个是discrete. 这会减少图像中的颜色数量。
<svg> <filter id="离散"> <fe组件传输> <feFuncR type="discrete" tableValues="0 0.5 0 1"/> <feFuncG type="discrete" tableValues="0 0.5 0 1"/> <feFuncB type="discrete" tableValues="0 0.5 0 1"/> <feFuncA type="discrete" tableValues="0 0.5 0 1"/> </feComponentTransfer> </过滤器> </svg>
结果:
接下来type是table,它对图像的对比度进行更细微的更改。因此,使用与tableValues上述相同的...
<svg> <filter id="convolve"> <fe组件传输> <feFuncR type="table" tableValues="0 0.5 0 1" /> <feFuncG type="table" tableValues="0 0.5 0 1" /> <feFuncB type="table" tableValues="0 0.5 0 1" /> <feFuncA type="table" tableValues="0 0.5 0 1" /> </feComponentTransfer> </过滤器> </svg>
......我们得到这个:
我们可以使用这个原语创建双色调效果。Duo 的意思是两个,所以我们为每个通道使用两个颜色值tableValues。
我们需要两种颜色,让我们使用#A91C93和#8EE3FF。现在,我们需要 RGB 颜色值 —#A91C93等价于(169,28,147)并且#8EE3FF等价于(255,142,227).
接下来,我们需要将红色、绿色和蓝色通道中的值除以 255,得到 0-1 范围内的值。这进入tableValues.
<svg> <filter id="双色调"> <fe组件传输> <feFuncR type="table" tableValues="0.662745098 1" /> <feFuncG type="table" tableValues="0.109803922 0.556862745" /> <feFuncB type="table" tableValues="0.576470588 0.890196078" /> </feComponentTransfer> </过滤器> </svg>
我们得到了这个:
还有第三种控制图像对比度的方法,那就是type, gamma。这带有其他三个属性:exponent、amplitude和offset。
增加exponent使图像的暗区更暗。与 相反amplitude,使图像中已经很亮的区域变亮。
offset为图像添加白色色调,其值介于 0 和 1 之间。
<svg> <filter id="放大"> <fe组件传输> <feFuncR type="gamma" exponent="1.9"amplitude="1.9" offset="0" /> <feFuncG type="gamma" exponent="1.9"amplitude="1.9" offset="0" /> <feFuncB type="gamma" exponent="1.9"amplitude="1.9" offset="0" /> </feComponentTransfer> </过滤器> </svg>
让我们与原始图像进行比较:
尝试其他值以找到更多为元素增添趣味的方法。使用这个 SVG 过滤器原语,您的指尖有很多可能性!
feOffset
这个原语非常简单。我们沿 x 和 y 方向偏移图像,类似于我们对投影所做的。
<svg> <filter id="convolve"> <feOffset in="SourceGraphic" dx="10" dy="10"></feOffset> </过滤器> </svg>
feMerge
这个 SVG 过滤器让我们可以对两个或更多元素进行分层。每一层都是feMergeNode主要feMerge原语中的一个。
现在是介绍SourceAlpha黑本的最佳时机SourceGraphic。因此,使用我们的图像,它SourceAlpha是一个与图像具有相同尺寸的黑色矩形。我们可以使用它来创建更好的阴影。
我们将首先抵消SourceAlpha:
<svg> <filter id="drop-shadow"> <feOffset in="SourceAlpha" dx="10" dy="10"></feOffset> </过滤器> </svg>
接下来,我们将应用模糊并使用以下方法降低不透明度feColorMatrix:
<svg> <filter id="drop-shadow"> <feOffset in="SourceAlpha" dx="10" dy="10"></feOffset> <feGaussianBlur stdDeviation="10" result="BLUR"></feGaussianBlur> <feColorMatrix 类型="矩阵" 在 =“模糊” 结果="DROPSHADOW" 值=“1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.5 0"></feColorMatrix> </过滤器> </svg>
此时,我们有一个模糊的半透明矩形:
现在,我们将使用feMerge. 第一个feMergeNode将是顶层,其他将按此顺序排列。
<feMerge> <feMergeNode in="FINALSHADOW"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> </feMerge>
现在,我们通过组合四个 SVG 滤镜获得了更好的投影效果!
feFlood
使用这个过滤器原语,我们只是用颜色填充过滤器区域。
<svg> <filter id="convolve"> <feflood flood-color="#00c2cb" flood-opacity="0.1" /> </过滤器> </svg>
结果:
feComposite
此滤镜将图像与其背景相结合。我们将切换到文本来演示这个过滤器原语的效果。
我们还将使用另外两个 SVG 过滤器,feFlood以及feMorphology创建一些剔除文本。
这是我们的h1文字:
这是 SVG 语法:
<正文> <svg> <filter id="淘汰赛"> <feMorphology operator="dilate" radius="2" in="sourceGraphic" 结果="扩张" /> <feFlood flood-color="#301934" flood-opacity="0.5" result="FLOOD" /> <feComposite operator="out" in="FLOOD" in2="DILATE" /> </过滤器> </svg> <h1>你好!我是一个淘汰赛...</h1> </正文>
这是结果:
首先,我们使用feMorphologyasoperator来dilate扩展文本。接下来,我们用颜色填充文本区域。最后,我们feComposite将文本与白色背景混合。
我们用作out复合材料的值operator。你能猜到我们使用时会发生什么in吗?
让我们来看看:
反其道而行之!这一次,泛色停留在文本的字母内。
feImage
该图元用图像填充过滤器区域。这正是我们所做的feFlood。我们坚持使用文本示例,所以让我们看看这个 SVG 过滤器是如何工作的。
<feImage xlink:href="2833.jpg" x="0" y="0" 宽度=“100%” 高度=“100%” preserveAspectRatio="none" 结果="IMAGE"> </feImage>
现在,结果如下:
现在,我们可以使用feComposite将此图像添加到文本中。
<svg> <filter id="淘汰赛"> <feImage xlink:href="2833.jpg" x="0" y="0" 宽度=“100%” 高度=“100%” preserveAspectRatio="none" result="IMAGE"></feImage> <feComposite operator="in" in="IMAGE" in2="SourceGraphic" /> </过滤器> </svg>
feBlend
顾名思义,这个原语将图像与其背景混合在一起。为了证明这一点,我们将创建一个噪波效果feTurbulence并将其与图像结合。
<svg> <filter id="混合"> <feTurbulence in="SourceGraphic" type="turbulence" baseFrequency="0.01 0.02" numOctaves="1" result="NOISE"> </fe湍流> <feBlend in="SourceGraphic" in2="NOISE" mode="multiply" result="BLEND"> </feBlend> </过滤器> </svg>
结果是一个多云的图像:
我们来看一个动画演示:
feDiffuseLighting
漫射照明是来自大型外部光源的光。它使用图像的 Alpha 通道作为凹凸贴图。凹凸贴图是一种向图像添加纹理的图形方法。
有三种光源可用于此原语:feDistantLight、fePointLight和feSpotLight。
feDistant定义来自远处的光源。
<svg> <filter id="淘汰赛"> <feDiffuseLighting in="SourceGraphic" lighting-color="#00c2cb" 扩散常数=“2”> <feDistantLight 方位角="100" 仰角="15" /> </feDiffuseLighting> <feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" /> </过滤器> </svg>
从这个片段中,光源是蓝色的。diffuseConstant定义了光的漫反射常数,这就是光从表面反射的方式。较低的值会使光线变暗。
对于feDistantLight属性,azimuth是光在 xy 平面上的顺时针方向,elevation是 z 轴上的角度方向。
这是使用上面的代码产生的效果:
接下来,fePointLight. 我们本质上是将光线指向图像中的特定点。从我们的图像来看,月亮似乎是最好的照明点。
为此,我们沿 x、y 和 z 轴移动灯光。
<svg> <filter id="point"> <feDiffuseLighting in="SourceGraphic" lighting-color="#00c2cb"diffuseConstant="2"> <fePointLight x="580" y="100" z="40"/> </feDiffuseLighting> <feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" /> </过滤器> </svg>
现在我们在繁星点点的夜空中有了一个漂亮的蓝月亮:
最后,对于这个 SVG 过滤器,我们有feSpotLight. 它就在名称中,有一个看不见的聚光灯将光束指向图像。至于我们,我们可以控制位置、角度和强度。
<svg> <filter id="point"> <feDiffuseLighting in="SourceGraphic" lighting-color="#00c2cb" 漫射常数="5"> <feSpotLight x="680" y="20" z="30" 限制锥角=“60” pointsAtX="100" pointsAtY="100" pointsAtZ="0" /> </feDiffuseLighting> <feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" /> </过滤器> </svg>
控制聚光灯的limitingConeAngle宽度。pointsAtX, pointsAtY, 并pointsAtZ控制聚光灯指向的方向。
结果:
Music Play(music.iztyy.com)世界音乐分享平台,歌曲支持在线播放下载本地!
feSpecularLighting
镜面光用于突出显示。此滤镜基元使用与 相同的光源feDiffuseLighting。
<svg> <filter id="point"> <feSpecularLighting specularExponent="5" lighting-color="#00c2cb" surfaceScale="1" in="SourceGraphic" specularConstant="1.5"> <fePointLight x="570" y="100" z="200" /> </feSpecularLighting> <feComposite in="SourceGraphic" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" /> </过滤器> </svg>
我们来看看属性。specularExponent控制高光的亮度,surfaceScale是图像表面的高度。specularConstant做同样的事情,diffuseConstant使灯光的颜色变亮或变暗。
结果:
我们使用过fePointLight,但请与其他人一起尝试,看看您能想出什么!
feTile
我们已经到了最后,最终的 SVG 过滤器是feTile. 此过滤器原语在元素上创建重复图案,就像地板上的瓷砖一样。
<svg> <filter id="tiles"> <feTile in="SourceGraphic" x="50" y="50" width="50" height="50" /> <feTile /> </过滤器> </svg>
在此代码段中,我们选择了 x 和 y 轴上将显示在每个图块上的图像部分。我们所要做的就是设置瓷砖的width和height。
瞧!
我们有它,所有 17 个 SVG 过滤器原语。当您可以随时随地编辑时,谁需要 Photoshop?您可以组合许多原语以获得更复杂的效果。
浏览器支持
SVG 过滤器在所有现代浏览器中都有很好的支持。这是来自caniuse的屏幕截图,显示了它们的兼容性范围。
结论
SVG 可以做很多不可思议的事情,我们刚刚讨论了如何使用 SVG 过滤器来增强图像以及其他图形元素。
我们还演示了 SVG 过滤器可用的 17 个原语。失真、颜色处理、模糊、颜色反转——只要你能想到的,只需几个按键即可实现这些效果!
现在,要记住几件事:
-
小心驼色字体
-
属性区分大小写,因此请注意任何拼写错误
-
result值应该全部大写以将它们与原始属性区分开来
去创造神奇的代码,一条线,一次一个像素!
您的前端是否占用了用户的 CPU?
随着 Web 前端变得越来越复杂,资源贪婪的功能对浏览器的要求也越来越高。如果您对监控和跟踪生产环境中所有用户的客户端 CPU 使用情况、内存使用情况等感兴趣,请尝试使用 LogRocket。
LogRocket就像一个用于 Web 和移动应用程序的 DVR,记录您的 Web 应用程序或网站中发生的一切。无需猜测问题发生的原因,您可以汇总和报告关键前端性能指标、重放用户会话以及应用程序状态、记录网络请求并自动显示所有错误。