SVG元素详解(3) -- 渐变元素和滤镜元素


系列文章:

经过前两篇文章的学习,我们已经学习完了比较基础的元素类型,从本文开始我们正式来学习进阶内容,首先是渐变元素和滤镜元素。

渐变元素

渐变是一种图形效果,用于实现平滑的颜色过渡。同时也用于填充图形元素,例如矩形、圆形、文本等,或者描边。

在SVG中,有两种渐变方式 -- 线性渐变和径向渐变,相对应的元素也有两个 -- <linearGradient><radialGradient>

渐变定义好之后并不会直接显示出来,而是应用在其他SVG元素上时才会显示,通常是定义在<defs>元素中,等待其他SVG元素调用。

<linearGradient>

<linearGradient>用于定义线性渐变。线性渐变是从某个点沿着一个方向到另一个点的变化。

属性

属性名 简介
x1 长度/百分比/number 渐变起始的X坐标。
y1 长度/百分比/number 渐变起始的Y坐标。
x2 长度/百分比/number 渐变终点的X坐标。
y2 长度/百分比/number 渐变终点的Y坐标。
gradientUnits userSpaceOnUse/y1objectBoundingBox(默认值) 定义属性x1y1x2y2的坐标系.
gradientTransform 转换列表 定义从渐变坐标系到目标坐标系的可选附加变换。
href urlstring 对模板渐变元素的URL引用。
spreadMethod pad/reflect/repeat 定义渐变在目标矩形的边界内开始或结束时会发生的情况。

如果x1 = x2y1 = y2,那么将使用最后一个渐变停止的颜色和不透明度进行绘制。

🌰:

html 复制代码
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500">
  <!-- 定义 -->
  <defs>
    <linearGradient id="MyGradient">
      <stop offset="5%" stop-color="lightblue" />
      <stop offset="95%" stop-color="lightpink" />
    </linearGradient>
  </defs>

  <!-- 使用 -->
  <rect fill="url(#MyGradient)" x="25" y="25" width="250" height="150"/>
</svg>

<radialGradient>

<radialGradient>用于定义径向渐变。径向渐变是一种从中心到边缘逐渐变化的颜色或亮度过渡效果

属性

属性名 简介
fr 长度/百分比/number 定义渐变的起始圆的半径。
fx 长度/百分比/number 定义渐变的起始圆的x坐标。
fy 长度/百分比/number 定义渐变的起始圆的y坐标。
r 长度/百分比/number 定义渐变结束时圆的半径。
cx 长度/百分比/number 定义渐变结束时圆的x坐标。
cy 长度/百分比/number 定义渐变结束时圆的y坐标。
gradientUnits userSpaceOnUse/y1objectBoundingBox(默认值) 定义属性cxcyrfrfxfy的坐标系.
gradientTransform 转换列表 定义从渐变坐标系到目标坐标系的可选附加变换。
href urlstring 对模板渐变元素的URL引用。
spreadMethod pad/reflect/repeat 定义渐变在目标矩形的边界内开始或结束时会发生的情况。

径向渐变要比线性渐变复杂一点,如果不使用fxfyfrcxcycr的话,那么渐变就以元素中心向四周扩散;如果使用了的话,fxfyfr定义起始圆,cxcycr定义结束圆。这时会有几种情况:

  1. 如果起始圆在结束圆之外,那么会创建一个类圆锥图形,椎体区域外的区域没有渐变:

    两个圆越靠近,锥体角度就越大,反之越小。

  2. 如果起始圆在结束圆内,渐变会以起始圆为中心向四周扩散,最多扩散到结束圆。

  3. 如果起始圆和结束圆大小位置相同,则不会出现渐变效果。

🌰:

html 复制代码
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500">
  <defs>
    <!-- 起始圆在结束圆内 -->
    <radialGradient id="gradient" fx="30%" fy="50%" fr="10%" cx="40%" cy="50%" r="40%" >
      <stop offset="0" stop-color="pink"></stop>
      <stop offset="1" stop-color="lightblue"></stop> 
    </radialGradient>
  </defs>
  
  <circle cx="150" cy="150" r="100" fill="url(#gradient)" />
</svg>

<stop>

<stop>元素定义渐变的颜色向量和位置<stop>元素只能作为<linearGradient><radialGradient>的子元素使用。

属性

属性名 简介
offset number/百分比 定义渐变停止点。
stop-color currentcolor 定义在渐变停止点使用的颜色。
stop-opacity 百分比/number(0 - 1) 定义渐变停止点的不透明度。
  • 如果offset属性的值小于0,则会向上舍入为00%);大于1,则会向下舍入为1100%)。

  • 下一个<stop>offset属性值必须大于上一个<sto>offset属性值,否则offset属性值将等于之前所有偏移值中的最大值。

  • 如果两个相邻的<stop>stop-color属性的颜色值不同,但是offset属性值一样,则以后一个<stop>stop-color属性的颜色值为主。

颜色相关属性

color

color属性用于为fillstrokestop-colorflood-colorlighting-color属性提供一个潜在的间接值,它不会直接影响元素,当这些属性的值为currentcolor时,其颜色值就是color属性的值。

color-interpolation

color-interpolation属性用于指定在渐变或插值过程中如何处理颜色的插值。它决定了在哪个颜色空间中进行颜色操作。

当一个子元素与背景混合时,子元素上的color-interpolation属性的值决定了混合的方式,而不是父元素上的color-interpolation属性的值。对于使用href属性引用另一个渐变的渐变,渐变会使用直接由fillstroke属性引用的渐变元素上的属性值。在对颜色进行动画处理时,会根据正在进行动画处理的元素上的color-interpolation属性的值来执行颜色的过渡。

取值

关键字 简介
auto 由用户代理选择sRGBlinearRGB空间不要求在特定颜色空间中进行颜色插值。
sRGB 指示颜色插值应在sRGB颜色空间中进行。
linearRGB 指示颜色插值应发生在线性化的RGB颜色空间中。

🌰:

html 复制代码
<svg 
  width="800" 
  height="800"
  xmlns="http://www.w3.org/2000/svg"
  >
  <defs>
    <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" stop-color="lightpink" />
      <stop offset="100%" stop-color="lightblue" />
    </linearGradient>
  </defs>
  
  <rect width="100" height="100" fill="url(#gradient)" color-interpolation='sRGB' />
  <rect y="120" width="100" height="100" fill="url(#gradient)" color-interpolation='linearRGB' />
</svg>

color-interpolation-filters

color-interpolation-filters属性与color-interpolation类似,用于指定通过滤镜效果执行的成像操作的颜色空间。它可以控制滤镜操作期间颜色的平滑过渡。该属性接受与color-interpolation属性同类型的值。

滤镜元素

滤镜元素允许我们为SVG元素添加各种滤镜效果。每种滤镜都有一个相应的元素表示,这些元素我们称之为原子滤镜 或者滤镜基元 。有点类似CSSfilter属性,但是滤镜元素比filter更强更复杂。一个滤镜通常由多个滤镜基元构成一个完整的滤镜效果。

在学习滤镜元素前,请自备两张图片(两张图片最好要有不重叠部分):

inin2属性

这两个属性可以和很多个滤镜元素一起使用,并且是比较复杂的属性,因此这里先介绍一下他们。

inin2属性分别用于指定滤镜效果的第一和第二输入源。输入源(input source)是指滤镜效果将被应用到的元素或图像的特定部分。输入源确定了滤镜操作的基础,决定了滤镜如何影响元素或图像的可视外观。不同的输入源可以用来实现不同的图形处理效果。

这两个属性接受的值一致:

关键字 简介
SourceGraphic 将以元素自身的图形为基础进行处理。
SourceAlpha 将以要应用滤镜的元素的图形内容的不透明度(alpha通道)作为输入源。
BackgroundImage 将以元素的背景图像的不透明度作为输入源。如果元素没有背景图像,则这个值与SourceAlpha相同。
FillPaint 将以元素的填充颜色(或填充图案)作为输入源。
StrokePaint 将以元素的描边颜色(或描边图案)作为输入源。
filter-primitive-reference 一种自定义的名称,用于标识滤镜中的滤镜基元。

filter-primitive-reference类型的值有两种情况:

  • 如果给一个滤镜基元起了一个名字(例如result="xxx"),那么可以在同一个滤镜元素中的其他滤镜基元中使用这个名字来处理前一个滤镜生成的图形。这种方式可以在滤镜链中重复使用相同的图形结果,而不必每次都重新生成。
  • 如果没有提供名称,那么前一个滤镜基元的输出仍然可以作为隐式的输入传递给下一个滤镜基元,但只有在下一个滤镜基元没有为其in属性提供值时才有效。在MDN中也有这么说明:在现代浏览器中不支持BackgroundImage作为过滤器源(请参阅feComposite兼容性表)。因此,我们需要使用<feImage>元素导入其中一个图像,以便在过滤器本身中混合:
html 复制代码
<defs>
  <filter id="imageMultiply">
    <!-- <feImage>作为隐式输入传递给下一个滤镜基元 -->
    <feImage
      href="mdn_logo_only_color.png"
      x="10%"
      y="10%"
     width="80%"
     height="80%" />
    <feBlend in2="SourceGraphic" mode="multiply" />
  </filter>
</defs>

可用于元素

  • <feBlend>
  • <feColorMatrix>
  • <feComponentTransfer>
  • <feComposite>
  • <feConvolveMatrix>
  • <feDiffuseLighting>
  • <feDisplacementMap>
  • <feDropShadow>
  • <feGaussianBlur>
  • <feMergeNode>
  • <feMorphology>
  • <feOffset>
  • <feSpecularLighting>
  • <feTile>

下文对应的元素属性当中就不再过多说明inin2属性。

<filter>

<filter>元素是滤镜基元的容器 ,通过对滤镜基元进行分组来自定义滤镜效果。<filter>元素及其内容不会直接呈现,需要被引用时才会显示,通常定义在<defs>元素中。使用时通过fliter="url(id)"或者style="filter: url(id)"的形式引用。

属性

属性 简介
x 长度/百分比 滤镜区域的X坐标。
y 长度/百分比 滤镜区域的y坐标。
width 长度/百分比 滤镜
height 长度/百分比 滤镜
filterUnits userSpaceOnUse/objectBoundingBox(默认值) 定义x, y, width, height的坐标系统。
primitiveUnits userSpaceOnUse(默认值)/objectBoundingBox <filter>中的各种长度值和定义原子滤镜区域的属性指定坐标系统。

<feImage>

<feImage>元素用于从外部源获取图像数据,并提供像素数据作为输出,以便对其进行处理和操作

属性

属性名 简介
href urlstring 图像资源或元素的URL。
preserveAspectRatio none/xMinYMinxMidYMin/xMaxYMin/xMinYMid/xMidYMid/xMaxYMid/xMinYMax/xMidYMax/xMaxYMax/[(meetslice)] 如果SVG片段嵌入到具有不同纵横比的容器中,则必须如何变形。
crossorigin anonymous/use-credentials 是否允许跨域访问,并与<feDisplacementMap>元素一起使用

🌰:

html 复制代码
<svg width="500" height="500" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="img">
      <feImage href="xxx.jpg" />
    </filter>
  </defs>

  <rect x="50" y="50" width="200" height="100" filter="url(#img);" />
</svg>

注意:如果目标图像资源是SVG图像,会被栅格化。

<feBlend>

<feBlend>元素用于在图像或图形之间应用混合效果。它通过将两个图像或图形的像素进行混合来创建新的视觉效果。类似CSS的mix-blend-mode属性。

属性

属性 简介
mode 与CSSmix-blend-mode属性的取值一致。blend-mode 定义混合模式。

🌰:

html 复制代码
<!-- 原图 -->
<img src="./images/water.png" width="200px" height="200px">

<svg width="200px" height="200px">
  <defs>
    <filter id="blendFilter">
      <feImage href="./images/water.png" y="10" height="180" result="p1" />
      <feImage href="./images/fire.png" y="10" height="180" result="p2" />
      
      <!-- 相乘 -->
      <feBlend mode="multiply" in="p1" in2="p2" />
    </filter>
  </defs>
  
  <rect width="200" height="200" filter="url(#blendFilter)"" />
</svg>

<feTile>

<feTile>元素用输入图像的重复平铺模式填充目标矩形

🌰:

html 复制代码
<svg
  width="300"
  height="300"
  xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="tile">
      <feImage href="./images/fire.png" width="100" height="100" result="fire" />
      <!-- 情况一:正常使用 -->
      <feTile in="fire" x="10" y="10" />

      <!-- 情况二:第一个<feTile>元素将图像平铺到100x100的区域,然后第二个<feTile>元素将这个100x100的区域再次平铺到整个<rect>元素的大小 -->
      <feTile in="fire" width="100" height="100" />
      <feTile x="10" y="10" />
    </filter>
  </defs>

  <rect
    width="300"
    height="300"
    filter="url(#tile)" />
</svg>

<feOffset>

<feOffset>将输入图像相对于其在图像空间中的当前位置通过指定向量进行偏移。

属性

属性名 简介
dx number 输入图形沿x轴偏移的量。
dy number 输入图形沿y轴偏移的量。

🌰:

html 复制代码
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
  <defs>
    <filter id="offset">
      <feOffset dx="50" dy="50" />
    </filter>
  </defs>

  <!-- 原图 -->
  <image href="./images/fire.png" />

  <!-- 偏移之后 -->
  <image href="./images/fire.png" filter="url(#offset)" />
</svg>

<feFlood>

<feFlood>元素用于在图像上创建一个填充效果。它通过flood-colorflood-opacity来填充整个图像或特定区域,以改变图像的外观。

属性

属性名 简介
flood-color color 指示使用什么颜色来填充当前滤镜区域。
flood-opacity 不透明度 定义在整个过滤器原语子区域中使用的不透明度值。

🌰:

html 复制代码
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="floodFilter">
      <feFlood 
        flood-color="lightpink" 
        flood-opacity="0.5" 
        width="150"
        height="150"
        result="flood"
      />
      <feComposite in="SourceGraphic" in2="flood" operator="arithmetic" k1="0" k2="1" k3="1" k4="0"/>
    </filter>
  </defs>
  
  <image href="./images/water.png" width="150" height="150" filter="url(#floodFilter)"/>
</svg>

<feDropShadow>

<feDropShadow>创建输入图像的投影。类似于CSS filter: drop-shadow(xxx)

属性

属性名 简介
dx number 输入图形沿x轴偏移的量。
dy number 输入图形沿y轴偏移的量。
stdDeviation number 定义投影中模糊操作的标准偏差。
flood-color color 指定阴影的颜色
flood-opacity [0, 1]/百分比 指定阴影的不透明度。

🌰:

html 复制代码
<svg width="500" height="500" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="shadow">
      <feDropShadow
        dx="5"
        dy="5"
        stdDeviation="5"
        flood-color="lightblue"
        flood-opacity="0.8" />
    </filter>
  </defs>

  <image href="./images/water.png" filter="url(#shadow)" />
</svg>

<feDisplacementMap>

<feDisplacementMap>元素使用来自in2的图像的像素值来对来自in的图像进行空间位移,从而在图像或图形上创建一种扭曲或变形的效果。

属性

属性名 简介
scale number 定义要在<feDisplacementMap>过滤器基元上使用的置换比例因子
xChannelSelector R/G/B/A 指示从in2中使用哪个颜色通道沿x轴替换in中的像素。
yChannelSelector R/G/B/A 指示从in2中使用哪个颜色通道沿y轴替换in中的像素。

转换公式:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> P ′ ( x , y ) = P ( x + s c a l e ∗ ( X C ( x , y ) − 0.5 ) , y + s c a l e ∗ ( Y C ( x , y ) − 0.5 ) ) P'(x,y) = P(x + scale * (XC(x, y) - 0.5), y + scale * (YC(x, y) - 0.5)) </math>P′(x,y)=P(x+scale∗(XC(x,y)−0.5),y+scale∗(YC(x,y)−0.5))

其中:其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> P ( x , y ) P(x,y) </math>P(x,y)为输入图像, <math xmlns="http://www.w3.org/1998/Math/MathML"> P ′ ( x , y ) P'(x,y) </math>P′(x,y)为目标图像。 <math xmlns="http://www.w3.org/1998/Math/MathML"> X C ( x , y ) XC(x,y) </math>XC(x,y)和 <math xmlns="http://www.w3.org/1998/Math/MathML"> Y C ( x , y ) YC(x,y) </math>YC(x,y)是xChannelSelectoryChannelSelector指定的通道的组件值。

公式的计算过程如下:

  1. 首先,计算位图中对应像素的亮度值的差异,即 <math xmlns="http://www.w3.org/1998/Math/MathML"> X C ( x , y ) − 0.5 和 Y C ( x , y ) − 0.5 XC(x,y) - 0.5和YC(x,y) - 0.5 </math>XC(x,y)−0.5和YC(x,y)−0.5。这个差异值表示位图像素的亮度相对于中间值0.5的偏移量。
  2. 将这个差异值乘以缩放比例 <math xmlns="http://www.w3.org/1998/Math/MathML"> s c a l e scale </math>scale。这样可以控制位图像素的偏移量的大小。
  3. 最后,将源图像中的像素位置 <math xmlns="http://www.w3.org/1998/Math/MathML"> P ( x , y ) P(x,y) </math>P(x,y)分别加上缩放后的位图像素的偏移量,即 <math xmlns="http://www.w3.org/1998/Math/MathML"> x + s c a l e ∗ ( X C ( x , y ) − 0.5 ) 和 y + s c a l e ∗ ( Y C ( x , y ) − 0.5 ) x + scale * (XC(x,y) - 0.5)和y + scale * (YC(x,y) - 0.5) </math>x+scale∗(XC(x,y)−0.5)和y+scale∗(YC(x,y)−0.5)。这样就得到了源图像像素的最终位置 <math xmlns="http://www.w3.org/1998/Math/MathML"> P ′ ( x , y ) P'(x,y) </math>P′(x,y)。

MDN🌰:

html 复制代码
<svg
  width="200"
  height="200"
  viewBox="0 0 220 220"
  xmlns="http://www.w3.org/2000/svg">
  <filter id="displacementFilter">
    <feTurbulence
      type="turbulence"
      baseFrequency="0.05"
      numOctaves="2"
      result="turbulence" />
    <feDisplacementMap
      in2="turbulence"
      in="SourceGraphic"
      scale="50"
      xChannelSelector="R"
      yChannelSelector="G" />
  </filter>

  <circle cx="100" cy="100" r="100" style="filter: url(#displacementFilter)" />
</svg>

<feTurbulence>

<feTurbulence>元素使用Perlin湍流函数创建图像。生成的图像将填充该滤镜的整个滤镜子区域。可以用来实现如说云纹、大理石纹、水波、有机形状等等效果。

Perlin湍流函数是一种用于生成连续、自然的随机数值的算法。其主要思想是通过插值和梯度向量来生成平滑的随机数值。可以用于生成连续的二维或三维噪声图像,这些图像可以用于模拟自然界中的各种效果,如云彩、水波纹、山脉等。

具体来说,Perlin湍流函数通过将输入坐标映射到一个网格中的控制点,并计算控制点周围的梯度向量来生成随机数值。然后,通过插值算法将这些随机数值平滑地连接起来,形成一个连续的函数。这个函数可以根据输入坐标的变化而变化,从而实现平滑的随机数值生成。

Perlin湍流函数在计算机图形学中被广泛应用,特别是在生成逼真的纹理和动画效果方面。它可以用于创建自然景观、水面效果、火焰效果等。此外,Perlin湍流函数还被用于生成随机地形、模拟流体动力学等领域。

属性

属性名 简介
type fractalNoise/turbulence 指示滤波器基元是否应执行噪声或湍流函数。
seed number 伪随机数生成器的起始数。
stitchTiles stitch/noStitch(默认值) 定义了噪声函数在边界处的行为。
baseFrequency number-optional-number; 噪声函数的基频参数。
numOctaves 正整数 控制噪声的复杂程度。它定义了生成噪声的频率数量,每个频率都会产生不同的纹理效果。较低的值会生成较简单的纹理,而较高的值会生成更复杂的纹理。

注意:如果stitchTiles="noStitch",则不会在包含湍流函数的tiles边界上实现平滑过渡。可能会显示明显的不连续的边界。

🌰:

html 复制代码
<svg xmlns="http://www.w3.org/2000/svg">
  <filter id="noise1">
    <feTurbulence baseFrequency="0.03" numOctaves="2" />
  </filter>

  <rect x="0" y="0" width="300" height="300" filter="url(#noise1)" />
</svg>

<feComposite>

<feComposite>用于在图像空间中以像素为单位对两个输入图像进行组合,使用了Porter-Duff合成操作在图像空间中按像素执行两个输入图像的组合。

Porter-Duff合成操作是一组用于图像合成的算法,它定义了如何将两个图像的像素进行组合以生成最终的合成图像。这些操作通常用于图形处理和计算机图形学中,用于实现图像的混合、遮罩、透明度等效果。

Porter-Duff合成操作基于两个输入图像的像素值和Alpha通道值,通过不同的算法来计算输出图像的像素值。这些算法可以根据像素的位置关系和Alpha通道的值来决定像素的合成方式。

属性

属性名 简介
operator over/in/out/atop/xor/lighter/arithmetic 指定合成操作的类型。
K1~K4 number operator="arithmetic"时用于计算结果像素的值。
  • 对于operator属性有:
    • over:将源图像放在目标图像上方。
    • in:如果源图形(in属性定义)与目标图形(in2定义)有重叠部分,那么会用源图形将这些重叠部分替换掉目标图形。也就是说,源图形会覆盖在目标图形上,取代目标图形的显示,其他部分透明。
    • out:与in相反。会用源图形将不重叠部分替换掉目标图形。
    • atop:与in类似,但是不重叠部分保持不变。
    • xor:指示in属性中定义的源图形的非重叠区域与in2属性中定义的目标图形合并。也就是只显示非重叠区域。
    • lighter:将源图像和目标图像的颜色值相加,产生更亮的颜色。
    • arithmetic
  • 对于K1~K4属性,它们用于调整每个输入图像的贡献程度。在MDN中对这个四个属性有这样一个像素合成公式:

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> r e s u l t = k 1 ∗ i 1 ∗ i 2 + k 2 ∗ i 1 + k 3 ∗ i 2 + k 4 ; result = k1 * i1 * i2 + k2 * i1 + k3 * i2 + k4; </math>result=k1∗i1∗i2+k2∗i1+k3∗i2+k4;

其中:

  • <math xmlns="http://www.w3.org/1998/Math/MathML"> k 1 ∗ i 1 ∗ i 2 k1 * i1 * i2 </math>k1∗i1∗i2表示两个输入图像的像素值相乘后再乘以权重系数 <math xmlns="http://www.w3.org/1998/Math/MathML"> k 1 k1 </math>k1,用于调整两个输入图像的互相影响程度。
  • <math xmlns="http://www.w3.org/1998/Math/MathML"> k 2 ∗ i 1 k2 * i1 </math>k2∗i1表示输入图像 <math xmlns="http://www.w3.org/1998/Math/MathML"> i 1 i1 </math>i1乘以权重系数 <math xmlns="http://www.w3.org/1998/Math/MathML"> k 2 k2 </math>k2,用于调整输入图像 <math xmlns="http://www.w3.org/1998/Math/MathML"> i 1 i1 </math>i1的整体贡献程度。 <math xmlns="http://www.w3.org/1998/Math/MathML"> k 3 ∗ i 2 k3 * i2 </math>k3∗i2同理。
  • <math xmlns="http://www.w3.org/1998/Math/MathML"> k 4 k4 </math>k4是一个常数项,用于调整整体亮度或对比度。

注意:

  • K1K2有任意一方的值为正数,另一方为负数时,只会呈现为正数那一方的图像的非重叠部分,
  • K4的值范围是[-1, 1],1完全白色,-1完全黑色,当值小于-1时,效果与正值一样。

operator="arithmetic"K1~K4属性配合使用是可以达到operator等于其他值的效果的。

🌰:

html 复制代码
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="floodFilter">
      <feimage href="./images/water.png" result="water" />
      <feimage href="./images/fire.png" result="fire" />
      <feComposite in="water" in2="fire" operator="xor" k1="0" k2="1" k3="1" k4="0" />
    </filter>
  </defs>
  
  <image href="./images/water.png" width="150" height="150" filter="url(#floodFilter)"/>
</svg>

<feColorMatrix>

<feColorMatrix>元素根据一个转换矩阵来改变颜色。对于每个像素的颜色值[R,G,B,A],它会将其与一个5x5的颜色矩阵相乘,从而创建出新的颜色值[R',G',B',A']。这个颜色矩阵可以通过一系列的矩阵操作来实现不同的颜色转换效果。

转换矩阵是一个数学工具,用于描述线性变换的方式。转换矩阵是一个5x5的矩阵,其中包含了一系列的数字。这些数字可以是正数、负数或零。矩阵的每一行代表了输出颜色的一个分量(红、绿、蓝、透明度和偏移量),而每一列代表了输入颜色的一个分量。

转换矩阵的计算方式是通过矩阵乘法来实现的。对于每个像素的颜色值(表示为一个包含红、绿、蓝和透明度分量的矢量),将其与转换矩阵进行乘法运算,得到一个新的颜色值。

通过调整转换矩阵中的数字,可以实现不同的颜色变换效果。例如,可以通过改变矩阵中的数字来调整亮度、对比度、饱和度等。具体的变换效果取决于矩阵中的数字的值和顺序。

转换矩阵的每个元素的含义如下:

  • 第一行的前三个元素表示红色分量的输出,第四个元素表示透明度的输出,第五个元素表示偏移量的输出。
  • 第二行的前三个元素表示绿色分量的输出,第四个元素表示透明度的输出,第五个元素表示偏移量的输出。
  • 第三行的前三个元素表示蓝色分量的输出,第四个元素表示透明度的输出,第五个元素表示偏移量的输出。
  • 第四行的前三个元素表示透明度的输出,第四个元素表示透明度的输出,第五个元素表示偏移量的输出。
  • 第五行均表示偏移量的输出。

通过调整转换矩阵中的数字,可以实现各种不同的颜色变换效果,从而实现对图像的颜色进行调整和变换。

属性

属性名 简介
type matrix/saturate/hueRotate/luminanceToAlpha 定义光源在坐标系中Y轴的位置。
values number 指定颜色矩阵的值
  • 对于type
    • matrix:使用一个5x4的矩阵来转换颜色。矩阵中的每个元素都会与输入图像的颜色值进行乘法运算,并将结果相加得到输出颜色值。
    • saturate:通过调整颜色的饱和度来转换颜色。此时values属性的值为一个浮点数,表示饱和度的倍数。值为0时,输出图像将完全灰度化;值为1时,输出图像与输入图像相同;值大于1时,输出图像的饱和度增加。
    • hueRotate:通过旋转颜色空间来转换颜色。此时values属性的值为一个角度值,表示颜色空间的旋转角度。正值表示顺时针旋转,负值表示逆时针旋转。
    • luminanceToAlpha:将亮度转换为透明度。此时values属性将输入图像的亮度值转换为透明度值,亮度越高的像素将越透明。
  • values的值是一个数字列表,具体的值对应type属性:

🌰:

html 复制代码
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="colorMeMatrix">
    <feColorMatrix in="SourceGraphic"
      type="matrix"
      values="0 0 0 0 0
             1 1 1 1 0
             0 0 0 0 0 
             0 0 0 1 0" />
  </filter>
  </defs>
  
  <!-- 浅蓝色变绿色 -->
  <rect width="100" height="100" fill="lightblue" filter="url(#colorMeMatrix)" />
</svg>

<feConvolveMatrix>

<feConvolveMatrix>元素用于通过卷积运算来改变图像的特性。

卷积运算是一种数学运算,它通过将一个矩阵(卷积核矩阵)应用于另一个矩阵(图像矩阵)来计算新的矩阵(输出矩阵)。

卷积核矩阵是一个二维矩阵,它的大小通常是奇数×奇数,例如3×3、5×5等。每个元素表示卷积核的一个权重值,用于计算图像中每个像素的新值。

通过调整卷积核矩阵的权重值,可以实现不同的图像处理效果。详细请查阅feConvolveMatrix

属性

属性名 简介
order [+number +number] 确定被用作<feConvolveMatrix>元素的矩阵的大小。
kernelMatrix 数字列表 定义卷积核矩阵。
divisor number 指定卷积运算的除数。用于对卷积运算的结果进行缩放。
bias number 用于调整滤镜的范围。在应用<feConvolveMatrix>元素的kernelMatrix到输入图像并应用divisor属性后,bias属性会被添加到每个分量上。这样可以表示本来会被限制在01的值。
targetX 0 ≤ targetX < order X(卷积矩阵在水平方向上的大小) 指定卷积矩阵的中心点在水平方向上的偏移量。
targetY 0 ≤ targetY < order Y(卷积矩阵在垂直方向上的大小) 指定卷积矩阵的中心点在垂直方向上的偏移量。
edgeMode duplicate/wrap/none 指定卷积滤镜的边缘处理模式。它决定当卷积核应用到图像边缘时如何处理边缘像素。
preserveAlpha Boolean 指定卷积操作后是(true)否(false)保留原始图像的透明度信息。
  • 对于order属性的值:第一个整数表示卷积核的宽度,第二个整数表示卷积核的高度。例如,order="3 3"表示卷积核的尺寸为3x3。

    order属性的值越大,卷积核的尺寸就越大,从而可以实现更复杂的图像处理效果。然而,较大的卷积核也会增加计算量,可能导致性能下降。需要注意的是,order属性的值必须是非负整数。如果指定的值不是整数,或者包含负数,则会被忽略。另外,如果只指定了一个整数,则会将其作为宽度和高度的值,即创建一个正方形的卷积核。

  • 对于edgeMode属性值:

    • duplicate:当卷积核应用到图像边缘时,边缘像素将被复制并用于计算。这意味着边缘像素的值将被重复使用,从而扩展了图像的边缘。这种模式适用于需要扩展边缘的情况。
    • wrap:当卷积核应用到图像边缘时,边缘像素将通过"包裹"的方式来获取。也就是说,如果卷积核超出了图像边界,它将从相对的另一侧获取像素值。这种模式适用于需要无限循环的纹理效果。
    • none:当卷积核应用到图像边缘时,边缘像素将被忽略,不参与计算。这意味着边缘像素的值将被视为0。这种模式适用于需要保留图像边缘的情况。

🌰:

html 复制代码
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
  <filter id="convolve-filter">
    <!-- 突出显示图像中的边缘和细节。 -->
    <feConvolveMatrix 
      in="SourceGraphic" 
      order="3" 
      kernelMatrix="1 1 1 
                  1 -8 1 
                  1 1 1" />
  </filter>
  <image href="./images/water.png" width="200" height="200" filter="url(#convolve-filter)" />
</svg>

<feFuncR><feFuncG><feFuncB><feFuncA>

<feFuncR><feFuncG><feFuncB><feFuncA>四个元素用于定义其父元素<feComponentTransfer>元素的输入图形的红色、绿色、蓝色个透明分量的Transfer函数。

Transfer 函数

属性

属性名 简介
type identity/table/discrete/linear/gamma 指示组件Transfer函数的类型。
intercept number type="linear"时,指定颜色组件传输的linear函数的截距。
amplitude number type="gamma"时,控制gamma函数的振幅。
exponent number type="gamma"时,定义gamma函数的指数。
tableValues 数字列表 一个数字列表,用于定义颜色组件传递函数的值查找表。

type属性值解释:

  • identity:用于保持颜色通道的原始值不变,不进行任何修改。
  • table:用于通过一个表格来映射输入颜色通道值到输出颜色通道值。需要再指定一个tableValues属性,该属性包含了一个数组,其中每个元素代表输入颜色通道值与输出颜色通道值的对应关系。
  • discrete:用于将输入颜色通道值映射到一组离散的输出颜色通道值。同样需要指定一个tableValues属性,但是这里的映射是分段的,每段映射都有一个不同的输出颜色值。
  • linear:用于执行线性插值,将输入颜色通道值映射到输出颜色通道值。需要指定slope(弃用)和intercept属性来定义线性函数。
  • gamma:用于应用伽马校正,以改变颜色通道值的亮度。需要指定amplitudeexponent属性,分别控制伽马函数的振幅和指数。

<feComponentTransfer>

<feComponentTransfer>元素用于对每个像素执行颜色分量的数据重映射。其计算使用非预乘色值进行执行,通过应用不同的Transfer函数来调整图像的亮度、对比度、饱和度和色调等等。

非预乘数据是指在计算机图形学中用于表示颜色的一种编码方式。在计算机中,颜色通常由红、绿、蓝三个分量来表示,每个分量的取值范围是0到255之间。而非预乘数据则是指在表示颜色时,每个分量没有被除以255以及乘以透明度0.8而转化为0~1范围的值。

属性

属性名 简介
in SourceGraphic/SourceAlpha/BackgroundImage/BackgroundAlpha/FillPaint/StrokePaint/filter-primitive-reference 标识给定过滤的输入。

🌰:

html 复制代码
<!-- 原图 -->
<img src="./images/water.png" width="200" height='200'>

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="colorAdjust">
      <feComponentTransfer in="SourceGraphic">
        <feFuncR type="linear" intercept="0.1" />
        <feFuncG type="linear" intercept="0.5" />
        <feFuncB type="linear" intercept="0.3" />
      </feComponentTransfer>
    </filter>
  </defs>
  
  <image href="./images/water.png" width="200" height="200" filter="url(#colorAdjust)"  />
</svg>

<feGaussianBlur>

<feGaussianBlur>元素用于在图像上应用高斯模糊效果。

高斯模糊是一种图像处理技术,用于使图像变得模糊并创建出柔和的视觉效果。它是基于高斯函数的数学原理,通过对图像中的像素进行加权平均来实现模糊效果。

高斯函数是一种钟形曲线,具有一个中心点和一个标准差。在高斯模糊中,标准差决定了模糊的强度。标准差越大,模糊效果越明显。

高斯模糊的原理是将每个像素的值与其周围像素的值进行加权平均。加权平均的权重由高斯函数计算得出,距离中心像素越远的像素权重越小。这样,中心像素的值会受到周围像素的影响,从而使图像变得模糊。

在图像处理中,高斯模糊常用于去除图像中的噪点、减少图像的细节和平滑图像的过渡。它也可以用于创建艺术效果,如柔和的光晕或模糊的背景。

属性

属性名 简介
stdDeviation number 模糊操作的标准差。
edgeMode duplicate/wrap/none 决定如何根据需要使用颜色值扩展输入图像,以便当内核位于输入图像的边缘或附近时可以应用矩阵操作。

🌰:

html 复制代码
<!-- 原图 -->
<img src="./images/water.png" width="200" height='200'>

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="blurFilter">
      <feGaussianBlur stdDeviation="5" />
    </filter>
  </defs>
  
  <image href="./images/water.png" width="200" height="200" filter="url(#blurFilter)"  />
</svg>

<feMerge><feMergeNode>

<feMerge>元素用于合并多个图像效果的SVG滤镜元素。它允许我们将多个滤镜效果同时(而不是按顺序)应用于一个元素,并将它们合并成一个最终的效果。

<feMergeNode>元素是<feMerge>元素的子元素,用于拿另一个滤镜的结果,让<feMerge>元素处理。

🌰:

html 复制代码
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <filter id="feOffset">
    <feOffset in="SourceGraphic" dx="50" dy="50" result="offset" />

    <feGaussianBlur stdDeviation="5" result="blur" />
    
    <!-- 同时应用偏移和高斯模糊滤镜 -->
    <feMerge>
      <feMergeNode in="offset" />
      <feMergeNode in="blur" />
    </feMerge>
  </filter>

  <rect
    width="100"
    height="100"
    fill="lightblue"
    filter="url(#feOffset)" />
</svg>

<feMorphology>

<feMorphology>元素用于对图像进行形态学处理。

形态学处理是一种基于图像形状的操作,用于改变图像的形态和结构。它主要通过改变图像中的像素值来实现,可以用于图像的边缘检测、膨胀、腐蚀等。

形态学处理的基本操作包括膨胀(dilate)和腐蚀(erode)。

膨胀操作可以使图像中的边缘变得更加粗细。它通过将每个像素的值替换为其周围像素中的最大值来实现。这样可以使边缘变得更加明显,同时也会使图像中的噪点变得更加明显。

腐蚀操作可以使边缘变得更加细小。它通过将每个像素的值替换为其周围像素中的最小值来实现。这样可以使边缘变得更加平滑,同时也会使图像中的细节变得模糊。

形态学处理还可以通过改变操作的半径或大小来控制操作的效果。较大的半径会使操作的影响范围更广,较小的半径会使操作的影响范围更小。

形态学处理在图像处理中有很多应用。例如,可以用膨胀操作来增强图像中的边缘,使其更加明显;可以用腐蚀操作来去除图像中的噪点,使其更加清晰;还可以用形态学处理来进行图像的分割和特征提取等。

属性

属性名 简介
operator erode/dilate 定义是膨胀(dilate)还是腐蚀(erode)源图形。
radius number(x-radius) number(y-radius) 定义形态学操作的半径或大小。它决定了操作的影响范围。

🌰:

html 复制代码
<!-- 原图 -->
<img src="./images/water.png" width="200" height="200">

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
  <defs>
    <filter id="edge-detection">
      <feMorphology operator="dilate" radius="3" />
    </filter>
  </defs>
  <image xlink:href="./images/water.png" width="200" height="200" filter="url(#edge-detection)" />
</svg>

光源(或者光照)元素

光源元素用于模拟光照效果,使图形看起来更加真实和立体。在SVG中,光源元素有三种种类型:平行光点光源聚光灯光。平行光是指光线是平行的,类似于太阳光;点光源是指光线是从一个点向四面八方发射的,类似于灯泡;而聚光灯光模拟了现实世界中的聚光灯效果。聚光灯光源可以用于在场景中创建具有特定方向和范围的聚焦光束。

<feDiffuseLighting><feSpecularLighting>

<feDiffuseLighting>元素用来对图像进行光照处理。它使用Alpha通道作为凹凸贴图,通过改变凹凸贴图的亮度来模拟光照效果。凹凸贴图中的亮度值越高,对应位置的像素就会被照亮得越明亮。产生的结果图像是一个RGBA不透明图像。结果图像的每个像素的颜色取决于光源的颜色、光源的位置以及输入凹凸贴图的表面几何。

通过使用<feComposite>滤镜的arithmetic运算符的乘积项,可以将这个滤镜基元产生的光照贴图与纹理图像相结合。从而实现光照效果与纹理的叠加。这样可以在纹理图像上添加光照效果,使得图像看起来更加真实。


<feSpecularLighting>元素使用Alpha通道作为凹凸贴图来照亮源图形。结果图像是基于浅色的RGBA图像。光照计算遵循Phong光照模型的标准镜面成分。结果图像取决于光颜色、光位置和输入凹凸贴图的表面几何。光照计算的结果被添加到图像中。滤镜基元假设观察者在z方向上处于无限远处。

这个滤镜基元产生的图像包含光照计算的镜面反射部分。这样的贴图意在与纹理结合使用,使用算术<feComposite>方法的add项。可以通过添加多个这些光照贴图来模拟多个光源,然后将其应用于纹理图像。

这两者的区别在于<feSpecularLighting>元素主要用于模拟镜面反射 效果;而<feDiffuseLighting>元素主要用于模拟漫反射效果。镜面反射效果更加明显,可以产生明亮的高光,而漫反射效果更加柔和,可以产生均匀的光照效果。

另外,这两者通常是作为其他光源的容器使用。

属性(共有)

属性名 简介
in SourceGraphic/SourceAlpha/BackgroundImage/BackgroundAlpha/FillPaint/StrokePaint/filter-primitive-reference 标识给定过滤的输入。
surfaceScale number 控制光照效果的扩散程度(即光照效果的半径大小)。
diffuseConstant number 调整光照效果的强度。它定义了光照效果的强度与输入图像的亮度之间的关系

点光源(PointLight)

<fePointLight>用于模拟一个点光源。

属性

属性名 简介
x number 定义光源在坐标系中X轴的位置。
y number 定义光源在坐标系中Y轴的位置。
z number 定义光源在坐标系中Z轴的位置。

平行光(DistantLight)

<feDistantLight>元素用于模拟远平行(距离)光源的效果。

属性

属性名 简介
azimuth number 控制光源在XY平面上的方位角,即光源相对于目标的水平角度。默认值为0,位于正北方向。
elevation number 指定光源从XY平面朝向Z轴的方向角。

聚光灯(SpotLight)

<feSpotLight>元素用于模拟一个点光源。

属性

属性名 简介
x number 定义光源在坐标系中X轴的位置。
y number 定义光源在坐标系中Y轴的位置。
z number 定义光源在坐标系中Z轴的位置。
pointsAtX number 定义光源在坐标系中X轴的位置。
pointsAtY number 定义光源在坐标系中Y轴的位置。
pointsAtZ number 定义光源在坐标系中Z轴的位置。
specularExponent number 定义光源的高光指数,决定高光的大小和亮度。
limitingConeAngle number 定义光源的光锥角度,决定光线的散射范围
  • xyzpointsAtXpointsAtXpointsAtX都是相对于<filter>元素的原始单位属性所定义的坐标系统来描述光源和光源指向的点的位置。它们的区别在于:前三者定义了光源在<filter>元素上的primitiveUnits属性所定义的坐标系统中对应轴的位置。也就是说,前三者确定了光源在<filter>元素上的对应位置。

    后三者表示光源指向的点在<filter>元素上的primitiveUnits属性所建立的坐标系统中对应轴的位置。也就是说,后三者确定了光源指向的点在<filter>元素上的对应位置。

使用示例

注意:<feSpecularLighting>通常需要与其他滤镜元素配合使用,在下面的🌰中<feDiffuseLighting><feDiffuseLighting>都会与<feComposite>一起使用,方便区分。

  • <feDiffuseLighting>与点光源、平行光源和聚光灯光源🌰:

    html 复制代码
    <svg width="500" height="100" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <filter id="lighting1" result="light1">
          <feDiffuseLighting>
            <fePointLight x="50" y="50" z="50" />
          </feDiffuseLighting>
    
          <feComposite
          in="SourceGraphic"
          in2="light1"
          operator="arithmetic"
          k1="0"
          k2="1"
          k3="1"
          k4="0" />
        </filter>
    
        <filter id="lighting2" result="light2">
          <feDiffuseLighting >
            <feDistantLight azimuth="45" elevation="30"/>
          </feDiffuseLighting>
    
          <feComposite
          in="SourceGraphic"
          in2="light2"
          operator="arithmetic"
          k1="0"
          k2="1"
          k3="1"
          k4="0" />
        </filter>
    
        <filter id="lighting3" result="light3">
          <feDiffuseLighting >
            <feSpotLight x="350" y="50" z="50" specularExponent="3" limitingConeAngle="50" pointsAtX="350" pointsAtY="50" />
          </feDiffuseLighting>
    
          <feComposite
          in="SourceGraphic"
          in2="light3"
          operator="arithmetic"
          k1="0"
          k2="1"
          k3="1"
          k4="0" />
        </filter>
      </defs>
    
      <image href="./images/water.png" width="100" height="100"  filter="url(#lighting1)"/>
      <image href="./images/water.png" x="150" width="100" height="100"  filter="url(#lighting2)"/>
      <image href="./images/water.png" x="300" width="100" height="100"  filter="url(#lighting3)"/>
    </svg>
  • <feSpecularLighting>与点光源、平行光源和聚光灯光源🌰:

    html 复制代码
    <svg width="500" height="100" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <filter id="lighting1" result="light1">
          <feSpecularLighting>
            <fePointLight x="50" y="50" z="50" />
          </feSpecularLighting>
    
          <feComposite
          in="SourceGraphic"
          in2="light1"
          operator="arithmetic"
          k1="0"
          k2="1"
          k3="1"
          k4="0" />
        </filter>
    
        <filter id="lighting2" result="light2">
          <feSpecularLighting light-color="white">
            <feDistantLight azimuth="45" elevation="30"/>
          </feSpecularLighting>
    
          <feComposite
          in="SourceGraphic"
          in2="light2"
          operator="arithmetic"
          k1="0"
          k2="1"
          k3="1"
          k4="0" />
        </filter>
    
        <filter id="lighting3" result="light3">
          <feSpecularLighting light-color="white">
            <feSpotLight x="350" y="50" z="50" specularExponent="3" limitingConeAngle="50" pointsAtX="350" pointsAtY="50" />
          </feSpecularLighting>
    
          <feComposite
          in="SourceGraphic"
          in2="light3"
          operator="arithmetic"
          k1="0"
          k2="1"
          k3="1"
          k4="0" />
        </filter>
      </defs>
    
      <image href="./images/water.png" width="100" height="100"  filter="url(#lighting1)"/>
      <image href="./images/water.png" x="150" width="100" height="100"  filter="url(#lighting2)"/>
      <image href="./images/water.png" x="300" width="100" height="100"  filter="url(#lighting3)"/>
    </svg>

参考资料

SVG 元素参考

相关推荐
阿奇__15 分钟前
element 跨页选中,回显el-table选中数据
前端·vue.js·elementui
谢尔登16 分钟前
【React】SWR 和 React Query(TanStack Query)
前端·react.js·前端框架
断竿散人16 分钟前
专题一、HTML5基础教程-Viewport属性深入理解:移动端网页的魔法钥匙
前端
3Katrina17 分钟前
理解Promise:让异步编程更优雅
前端·javascript
星之金币18 分钟前
关于我用Cursor优化了一篇文章:30 分钟学会定制属于你的编程语言
前端·javascript
天外来物20 分钟前
实战分享:用CI/CD实现持续部署
前端·nginx·docker
moxiaoran575321 分钟前
Spring Cloud Gateway 动态路由实现方案
运维·服务器·前端
市民中心的蟋蟀21 分钟前
第十一章 这三个全局状态管理库之间的共性与差异 【上】
前端·javascript·react.js
vvilkim35 分钟前
Flutter 常用组件详解:Text、Button、Image、ListView 和 GridView
前端·flutter
vvilkim41 分钟前
Flutter 命名路由与参数传递完全指南
前端·flutter