起因
最近写了很多关于SVG
滤镜的内容,但大部分都是直接呈现了一个效果,并没有去详细的记录关于各个滤镜的详细用法,这次想换个写作风格也是给自己留个备忘录~
往期SVG
滤镜相关内容
feColorMatrix
<feColorMatrix>
是 SVG 滤镜中的一个元素,用于对图形的颜色值进行转换和调整。它通过 5x4 的矩阵操作,对每个像素的红色 (R)、绿色 (G)、蓝色 (B) 和透明度 (A) 进行重新计算,从而实现各种颜色效果,如色调旋转、灰度化、饱和度调整等。
python
| R' | | r1 r2 r3 r4 r5 | | R |
| G' | | g1 g2 g3 g4 g5 | | G |
| B' | = | b1 b2 b3 b4 b5 | * | B |
| A' | | a1 a2 a3 a4 a5 | | A |
计算公式可以展开为:
- R' = r1 * R + r2 * G + r3 * B + r4 * A + r5
- G' = g1 * R + g2 * G + g3 * B + g4 * A + g5
- B' = b1 * R + b2 * G + b3 * B + b4 * A + b5
- A' = a1 * R + a2 * G + a3 * B + a4 * A + a5
矩阵中的值决定了颜色的最终效果。
属性说明
-
type 属性
定义矩阵的类型,常见值包括:
- matrix:手动指定矩阵值。
- saturate:调整饱和度。
- hueRotate:旋转色相。
- luminanceToAlpha:将亮度值转换为透明度值。
-
values 属性
当 type="matrix" 时,用于指定 5x4 的矩阵值。值用空格或逗号分隔。
saturate
saturate
变换会影响图像中每个像素的颜色强度(从灰度到全彩)。feColorMatrix
的 saturate
功能通过指定 values
属性来设定饱和度的值。
- values="1" 表示图像保持原样,即饱和度没有变化。
- values="0" 会将图像变成完全灰度(无饱和度,所有颜色都转为灰色)。
- values > 1 会增加图像的饱和度,使颜色更加鲜艳。
- values < 0 会反向饱和(通常结果类似于反转色彩)。
可以拖拽
saturate
查看效果
hueRotate
色相旋转通过改变颜色在色轮上的位置来调整颜色。例如红色可能会变成蓝色或绿色 ,蓝色可能会变成绿色或红色
- values="0" 表示不旋转,图像保持原样。
- values="90" 将色相旋转 90°。
- values="180" 将色相旋转 180°,通常会反转颜色。
- values="360" 等价于不旋转(颜色循环一圈回到原点)。
可以拖拽
hueRotate
查看效果
luminanceToAlpha
feColorMatrix 中的 luminanceToAlpha 是一个特殊的类型,它将图像的亮度信息(即每个像素的光亮程度)转换为透明度信息(Alpha 通道)
这个属性可谓是最难理解的属性之一了,光看定义完全无法理解,还是看个例子先!
luminanceToAlpha
不接受value
,也不受R、G、B
影响只受亮度影响,其中亮度(Luminance)的算法是
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> L u m i n a n c e = 0.2126 × R + 0.7152 × G + 0.0722 × B Luminance=0.2126×R+0.7152×G+0.0722×B </math>Luminance=0.2126×R+0.7152×G+0.0722×B
- 亮度较高的区域会被映射的更接近不透明也可以理解成黑色
- 亮度较低的区域会映射为较低的 Alpha 值,即更加透明。
luminanceToAlpha
常常会配合其他滤镜一起使用,这里先不过多的展开🤖,知道这个属性的功能效果先~
matrix
matrix
是整个feColorMatrix
中最重要的属性,上述介绍的其他属性都可以通过matrix
来实现!
<feColorMatrix>
中的 type="matrix" 是一种通过矩阵操作来修改图像颜色和透明度的方式。这种方法可以直接对图像的颜色通道进行数学运算,改变每个像素的颜色值。与其他类型的 feColorMatrix(如 saturate 或 hueRotate)相比,matrix 提供了更大的灵活性,允许开发者自定义颜色转换的具体方式。
matrix
采用的是一个 4x5 的矩阵结构,矩阵的每一行与颜色的 R、G、B 和 A 分量相对应,最后一列是一个额外的偏移值,具体的公式如下
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> R ′ = ( R × m 11 ) + ( G × m 12 ) + ( B × m 13 ) + ( A × m 14 ) + m 15 G ′ = ( R × m 21 ) + ( G × m 22 ) + ( B × m 23 ) + ( A × m 24 ) + m 25 B ′ = ( R × m 31 ) + ( G × m 32 ) + ( B × m 33 ) + ( A × m 34 ) + m 35 A ′ = ( R × m 41 ) + ( G × m 42 ) + ( B × m 43 ) + ( A × m 44 ) + m 45 R' = (R \times m_{11}) + (G \times m_{12}) + (B \times m_{13}) + (A \times m_{14}) + m_{15} \\ G' = (R \times m_{21}) + (G \times m_{22}) + (B \times m_{23}) + (A \times m_{24}) + m_{25} \\ B' = (R \times m_{31}) + (G \times m_{32}) + (B \times m_{33}) + (A \times m_{34}) + m_{35} \\ A' = (R \times m_{41}) + (G \times m_{42}) + (B \times m_{43}) + (A \times m_{44}) + m_{45} </math>R′=(R×m11)+(G×m12)+(B×m13)+(A×m14)+m15G′=(R×m21)+(G×m22)+(B×m23)+(A×m24)+m25B′=(R×m31)+(G×m32)+(B×m33)+(A×m34)+m35A′=(R×m41)+(G×m42)+(B×m43)+(A×m44)+m45
这里,m_{ij}
代表矩阵中的元素,而 R, G, B, A 是图像的每个像素的颜色通道值,并且矩阵中的输入颜色值是归一化到 0~1 的浮点数范围内,而不是直接使用 0~255 的整数范围。这种归一化的方式适用于所有输入的 RGB 和 Alpha 通道值。
举一个例子!
html
.box {
width: 400px;
height: 400px;
background: rgba(255, 0, 0, 1);
filter: url(#matrix);
}
...
...
<svg>
<filter id="matrix">
<feColorMatrix type="matrix" values="
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0"/>
</filter>
</svg>
带入到公式中
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 1 = ( 1 × 1 ) + ( 0 × 0 ) + ( 0 × 0 ) + ( 1 × 0 ) + 0 0 = ( 1 × 0 ) + ( 0 × 1 ) + ( 0 × 0 ) + ( 1 × 0 ) + 0 0 = ( 1 × 0 ) + ( 0 × 0 ) + ( 0 × 1 ) + ( 1 × 0 ) + 0 1 = ( 1 × 0 ) + ( 0 × 0 ) + ( 0 × 0 ) + ( 1 × 1 ) + 0 1 = (1 \times 1) + (0 \times 0) + (0 \times 0) + (1 \times 0) + 0 \\ 0 = (1 \times 0) + (0 \times 1) + (0 \times 0) + (1 \times 0) + 0 \\ 0 = (1 \times 0) + (0 \times 0) + (0 \times 1) + (1 \times 0) + 0 \\ 1 = (1 \times 0) + (0 \times 0) + (0 \times 0) + (1 \times 1) + 0 \\ </math>1=(1×1)+(0×0)+(0×0)+(1×0)+00=(1×0)+(0×1)+(0×0)+(1×0)+00=(1×0)+(0×0)+(0×1)+(1×0)+01=(1×0)+(0×0)+(0×0)+(1×1)+0
最终输出结果会重新映射到 0 ~ 255 的整数范围
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> R = 1 = 255 , G = 0 = 0 , B = 0 = 0 , A = 1 = 255 R = 1 = 255, \quad G = 0 = 0, \quad B = 0 = 0, \quad A = 1 = 255 </math>R=1=255,G=0=0,B=0=0,A=1=255
这个矩阵保证了所有颜色通道依然保持原有的色值,所以上述例子中的红色矩形最终依然保持了红色!
如果我们想让红色的矩形变成绿色,只需要让红色通道最终结果为0,绿色通道最终结果为1
html
<feColorMatrix type="matrix" values="
0 0 0 0 0 👈红色通道最后结果全部为0
0 1 0 0 1 👈绿色通道最终偏移加上1也就是255
0 0 1 0 0
0 0 0 1 0"/>
效果展示
利用matrix
我们可以完成很多有意思的效果
灰度展示
ini
<feColorMatrix type="matrix" values="
0.2126 0.7152 0.0722 0 0
0.2126 0.7152 0.0722 0 0
0.2126 0.7152 0.0722 0 0
0 0 0 1 0"/>
灰度看腻了?我们把红色通道的权重修改一下再看看效果~
这也突显了matrix
的自由,可以任意配置数值改变原图~
去色(黑白)
html
values="
0.33 0.33 0.33 0 0
0.33 0.33 0.33 0 0
0.33 0.33 0.33 0 0
0 0 0 1 0"
降低亮度
html
values="
1 0 0 0 -0.2
0 1 0 0 -0.2
0 0 1 0 -0.2
0 0 0 1 0"
色相转换
html
values="
0 1 0 0 0
0 0 1 0 0
1 0 0 0 0
0 0 0 1 0"
将原来的 RGB 值重新排列:R → G,G → B,B → R,形成色相旋转。
粘滞效果
这个技巧在H5 实现超丝滑ChatGPT语音交互中有使用到过
html
<svg width="400" height="400">
<defs>
<filter id="goo">
<feGaussianBlur stdDeviation="15"></feGaussianBlur>
<feColorMatrix type="matrix" values="
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 26 -7">
</feColorMatrix>
</filter>
</defs>
<g filter="url(#goo)">
<circle cx="200" cy="200" r="20" fill="white"></circle>
<circle cx="300" cy="200" r="20" fill="white">
<animate
attributeName="cx"
from="300"
to="100"
dur="4s"
repeatCount="indefinite"/>
</circle>
</g>
</svg>
字体背景圆角效果
html
<svg style="visibility: hidden; position: absolute;" width="0" height="0" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="goo">
<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
</defs>
</svg>
效果来自Gooey text background with SVG filters
结束语
关于feColorMatrix
相关内容就先到这里啦,喜欢的朋友点点关注~