#SVG 滤镜原语(filter primitive)
- feBlend
- feColorMatrix
- feComponentTransfer
- feComposite
- feConvolveMatrix
- feDiffuseLighting
- feDisplacementMap
- feFlood
- feGaussianBlur
- feImage
- feMerge
- feMorphology
- feOffset
- feSpecularLighting
- feTile
- feTurbulence
- feDistantLight
- fePointLight
- feSpotLight
<filter>标签用来定义滤镜,滤镜必须含有id属性来标识滤镜。图形元素通过filter=url(#id)来引用滤镜。
以前<filter>标签要包含在<defs>标签中,现在也可以直接定义而不用<defs>标签
#feblend(混合)
参考MDN https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feBlend
The <feBlend> SVG filter primitive composes two objects together ruled by a certain blending mode. This is similar to what is known from image editing software when blending two layers. The mode is defined by the mode attribute.
SVG滤镜原语<feBlend>通过一个确定的混合模式将两个对象组合到一起。它有点像我们平常使用的图片编辑器中的合并两个图层。混合模式由mode属性定义。
- in、in2 标识为给定的滤镜原始输入:SourceGraphic | SourceAlpha | BackgroundImage | BackgroundAlpha | FillPaint | StrokePaint | <filter-primitive-reference>(注意:in在上层,in2在下层)
- mode 混合模式:normal | multiply | screen | darken | lighten
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="feBlend1">
<feFlood result="floodFill" x="0" y="0" width="100%" height="100%" flood-color="green" flood-opacity="0.9"/>
<feBlend in="SourceGraphic" in2="floodFill" mode="normal"/>
</filter>
<filter id="feBlend2">
<feFlood result="floodFill" x="0" y="0" width="100%" height="100%" flood-color="green" flood-opacity="0.9"/>
<feBlend in="floodFill" in2="SourceGraphic" mode="normal"/>
</filter>
<circle cx="50" cy="50" r="40" fill="red" filter="url(#feBlend1)" />
<circle cx="150" cy="50" r="40" fill="red" filter="url(#feBlend2)"/>
</svg>
#feColorMatrix(RGBA颜色矩阵)
参考 http://www.w3cplus.com/svg/finessing-fecolormatrix.html
<svg xmlns="http://www.w3.org/2000/svg" >
<filter id="linear">
<feColorMatrix
type="matrix"
values="R 0 0 0 0
0 G 0 0 0
0 0 B 0 0
0 0 0 A 0 "/>
</feColorMatrix>
</filter>
</svg>
矩阵计算RGBA自已每行的最终值,每个RGBA通道有自身的RGBA通道。最后一个值是一个乘数。最后RGBA的值从上向下读,像下面这个列表:
/* R G B A 1 */
1 0 0 0 0 // R = 1*R + 0*G + 0*B + 0*A + 0
0 1 0 0 0 // G = 0*R + 1*G + 0*B + 0*A + 0
0 0 1 0 0 // B = 0*R + 0*G + 1*B + 0*A + 0
0 0 0 1 0 // A = 0*R + 0*G + 0*B + 1*A + 0
测试图像为
##清空通道(Blowing out channels)
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
<filter id="raw">
<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>
<filter id="red">
<feColorMatrix
type="matrix"
values="
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0 "/>
</filter>
<filter id="green">
<feColorMatrix
type="matrix"
values="
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 1 0 "/>
</filter>
<filter id="blue">
<feColorMatrix
type="matrix"
values="
0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 1 0 "/>
</filter>
<image xlink:href="rgb_colors.jpg" x="0" y="0" width="300" height="185" filter="url(#raw)"/>
<image xlink:href="rgb_colors.jpg" x="300" y="0" width="300" height="185" filter="url(#red)"/>
<image xlink:href="rgb_colors.jpg" x="600" y="0" width="300" height="185" filter="url(#green)"/>
<image xlink:href="rgb_colors.jpg" x="900" y="0" width="300" height="185" filter="url(#blue)"/>
</svg>
##明与暗(Lighten & darken)
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
<filter id="lighten">
<feColorMatrix
type="matrix"
values="1.5 0 0 0 0
0 1.5 0 0 0
0 0 1.5 0 0
0 0 0 1 0 "/>
</filter>
<filter id="darken">
<feColorMatrix
type="matrix"
values=".5 0 0 0 0
0 .5 0 0 0
0 0 .5 0 0
0 0 0 1 0 "/>
</filter>
<image xlink:href="rgb_colors.jpg" x="0" y="0" width="600" height="370" filter="url(#lighten)"/>
<image xlink:href="rgb_colors.jpg" x="600" y="0" width="600" height="370" filter="url(#darken)"/>
</svg>
##灰度级(GRAYSCALE)
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
<filter id="gray">
<feColorMatrix
type="matrix"
values="
.5 .5 .5 0 0
.5 .5 .5 0 0
.5 .5 .5 0 0
0 0 0 1 0 "/>
</filter>
<image xlink:href="rgb_colors.jpg" x="0" y="0" width="600" height="370" filter="url(#gray)"/>
</svg>
##<feColorMatrix>标签中type的取值
参考 https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feColorMatrix
- matrix
feColorMatrix的matrix是一个4*5的矩阵。前面4列是颜色通道的比例系数,最后一列是常量偏移。
上面公式中的rr表示red to red系数,以此类推。c1~c4表示常量偏移。
第一个4*5矩阵为变换矩阵,第二个单列矩阵为待变换对象的像素值。右侧单列矩阵为矩阵1和2的点积结果。
这个变换矩阵看起来比较复杂,在实践上常使用一个简化的对角矩阵,即除了rr/gg/bb/aa取值非零外,其余行列取值为0,这就退化成了简单的各颜色通道的独立调整。
- saturate
- hueRotate
- luminanceToAlpha
<svg width="100%" height="100%" viewBox="0 0 150 360"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<text x="70" y="50">Reference</text>
<g>
<circle cx="30" cy="30" r="20" fill="blue" fill-opacity="0.5" />
<circle cx="20" cy="50" r="20" fill="green" fill-opacity="0.5" />
<circle cx="40" cy="50" r="20" fill="red" fill-opacity="0.5" />
</g>
<text x="70" y="120">matrix</text>
<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>
<g filter="url(#colorMeMatrix)">
<circle cx="30" cy="100" r="20" fill="blue" fill-opacity="0.5" />
<circle cx="20" cy="120" r="20" fill="green" fill-opacity="0.5" />
<circle cx="40" cy="120" r="20" fill="red" fill-opacity="0.5" />
</g>
<text x="70" y="190">saturate</text>
<filter id="colorMeSaturate">
<feColorMatrix in="SourceGraphic"
type="saturate"
values="0.2" />
</filter>
<g filter="url(#colorMeSaturate)">
<circle cx="30" cy="170" r="20" fill="blue" fill-opacity="0.5" />
<circle cx="20" cy="190" r="20" fill="green" fill-opacity="0.5" />
<circle cx="40" cy="190" r="20" fill="red" fill-opacity="0.5" />
</g>
<text x="70" y="260">hueRotate</text>
<filter id="colorMeHueRotate">
<feColorMatrix in="SourceGraphic"
type="hueRotate"
values="180" />
</filter>
<g filter="url(#colorMeHueRotate)">
<circle cx="30" cy="240" r="20" fill="blue" fill-opacity="0.5" />
<circle cx="20" cy="260" r="20" fill="green" fill-opacity="0.5" />
<circle cx="40" cy="260" r="20" fill="red" fill-opacity="0.5" />
</g>
<text x="70" y="320">luminanceToAlpha</text>
<filter id="colorMeLTA">
<feColorMatrix in="SourceGraphic"
type="luminanceToAlpha" />
</filter>
<g filter="url(#colorMeLTA)">
<circle cx="30" cy="310" r="20" fill="blue" fill-opacity="0.5" />
<circle cx="20" cy="330" r="20" fill="green" fill-opacity="0.5" />
<circle cx="40" cy="330" r="20" fill="red" fill-opacity="0.5" />
</g>
</svg>
#feComposite
该滤镜执行两个输入图像的智能像素组合,在图像空间中使用以下Porter-Duff合成操作之一:
- over
- in
- atop
- xor
另外,还可以应用一个智能组件arithmetic操作(结果被压到[0,1]范围内)。
#feFlood(探照灯)
参考MDN https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feFlood
The <feFlood> SVG filter primitive fills the filter subregion with the color and opacity defined by flood-color and flood-opacity.
SVG滤镜原语<feFlood>使用定义好的颜色flood-color和透明度flood-opacity填充了滤镜的分区。
- (x,y)、width、height定义了绘制矩形的范围
- flood-color(探照灯 或 泛滥)颜色
- flood-opacity (探照灯 或 泛滥)透明度
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" >
<filter id="floodFilter" filterUnits="userSpaceOnUse">
<feFlood x="10" y="10" width="100" height="100" flood-color="green" flood-opacity="0.5"/>
</filter>
<use filter="url(#floodFilter)"/>
<circle cx="10" cy="10" r="3" fill="red" />
<circle cx="110" cy="110" r="3" fill="red" />
</svg>
#feGaussianBlur(高斯模糊)
- in 标识为给定的滤镜原始输入:SourceGraphic | SourceAlpha | BackgroundImage | BackgroundAlpha | FillPaint | StrokePaint | <filter-primitive-reference>
- stdDeviation 模糊量
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="300" >
<filter id="SourceGraphic">
<feGaussianBlur in="SourceGraphic" stdDeviation="10" />
</filter>
<filter id="SourceAlpha">
<feGaussianBlur in="SourceAlpha" stdDeviation="10" />
</filter>
<filter id="BackgroundImage">
<feGaussianBlur in="BackgroundImage" stdDeviation="10" />
</filter>
<filter id="BackgroundAlpha">
<feGaussianBlur in="BackgroundAlpha" stdDeviation="10" />
</filter>
<filter id="FillPaint">
<feGaussianBlur in="FillPaint" stdDeviation="10" />
</filter>
<filter id="StrokePaint">
<feGaussianBlur in="StrokePaint" stdDeviation="10" />
</filter>
<circle cx="60" cy="60" r="40" fill="green" />
<circle cx="160" cy="60" r="40" fill="green" filter="url(#SourceGraphic)" />
<circle cx="260" cy="60" r="40" fill="green" filter="url(#SourceAlpha)" />
<circle cx="360" cy="60" r="40" fill="green" filter="url(#BackgroundImage)" />
<circle cx="460" cy="60" r="40" fill="green" filter="url(#BackgroundAlpha)" />
<circle cx="560" cy="60" r="40" fill="green" filter="url(#FillPaint)" />
<circle cx="660" cy="60" r="40" fill="green" filter="url(#StrokePaint)" />
<filter id="SourceGraphic2">
<feGaussianBlur in="SourceGraphic" stdDeviation="2" />
</filter>
<filter id="SourceGraphic5">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
<filter id="SourceGraphic10">
<feGaussianBlur in="SourceGraphic" stdDeviation="10" />
</filter>
<filter id="SourceGraphic20">
<feGaussianBlur in="SourceGraphic" stdDeviation="20" />
</filter>
<filter id="SourceGraphic50">
<feGaussianBlur in="SourceGraphic" stdDeviation="50" />
</filter>
<filter id="SourceGraphic100">
<feGaussianBlur in="SourceGraphic" stdDeviation="100" />
</filter>
<circle cx="60" cy="160" r="40" fill="blue" />
<circle cx="160" cy="160" r="40" fill="blue" filter="url(#SourceGraphic2)" />
<circle cx="260" cy="160" r="40" fill="blue" filter="url(#SourceGraphic5)" />
<circle cx="360" cy="160" r="40" fill="blue" filter="url(#SourceGraphic10)" />
<circle cx="460" cy="160" r="40" fill="blue" filter="url(#SourceGraphic20)" />
<circle cx="560" cy="160" r="40" fill="blue" filter="url(#SourceGraphic50)" />
<circle cx="660" cy="160" r="40" fill="blue" filter="url(#SourceGraphic100)" />
</svg>
#feOffset(位移)
- <filter>标签的(x,y)分别是需要位移的起始位置
- <feOffset> 中真正被移动的图像是(x,y)到(width-x-dx,height-y-dy)的矩形区域
- (dx,dy)分别是相对原始图像向右和向下的位移
<svg xmlns="http://www.w3.org/2000/svg" width="700" height="500">
<filter id="feOffset_x1" x="-50%" y="-10%" width="150%" height="150%">
<feOffset in="SourceGraphic" dx="0" dy="0" />
</filter>
<filter id="feOffset_x2" x="-10%" y="-10%" width="150%" height="150%">
<feOffset in="SourceGraphic" dx="0" dy="0" />
</filter>
<filter id="feOffset_x3" x="50%" y="-10%" width="150%" height="150%">
<feOffset in="SourceGraphic" dx="0" dy="0" />
</filter>
<filter id="feOffset_w1" x="0%" y="0%" width="50%" height="150%">
<feOffset in="SourceGraphic" dx="0" dy="0" />
</filter>
<filter id="feOffset_w2" x="0%" y="0%" width="75%" height="150%">
<feOffset in="SourceGraphic" dx="0" dy="0" />
</filter>
<filter id="feOffset_w3" x="0%" y="0%" width="100%" height="150%">
<feOffset in="SourceGraphic" dx="0" dy="0" />
</filter>
<filter id="feOffset_w4" x="0%" y="0%" width="150%" height="150%">
<feOffset in="SourceGraphic" dx="0" dy="0" />
</filter>
<filter id="feOffset_d1" x="-10%" y="-10%" width="100%" height="150%">
<feOffset in="SourceGraphic" dx="0" dy="0" />
</filter>
<filter id="feOffset_d2" x="-10%" y="-10%" width="110%" height="150%">
<feOffset in="SourceGraphic" dx="60" dy="0" />
</filter>
<filter id="feOffset_d3" x="-10%" y="-10%" width="110%" height="150%">
<feOffset in="SourceGraphic" dx="90" dy="0" />
</filter>
<filter id="feOffset_d4" x="-10%" y="-10%" width="135%" height="150%">
<feOffset in="SourceGraphic" dx="90" dy="0" />
</filter>
<g style="stroke:orange;stroke-width:3;fill:green;">
<circle cx="70" cy="70" r="60" />
<circle cx="70" cy="70" r="60" style="fill:blue;" />
<circle cx="220" cy="70" r="60" />
<circle cx="220" cy="70" r="60" style="fill:blue;filter:url(#feOffset_x1);" />
<circle cx="370" cy="70" r="60" />
<circle cx="370" cy="70" r="60" style="fill:blue;filter:url(#feOffset_x2);" />
<circle cx="520" cy="70" r="60" />
<circle cx="520" cy="70" r="60" style="fill:blue;filter:url(#feOffset_x3);" />
<circle cx="70" cy="200" r="60" />
<circle cx="70" cy="200" r="60" style="fill:blue;filter:url(#feOffset_w1);" />
<circle cx="220" cy="200" r="60" />
<circle cx="220" cy="200" r="60" style="fill:blue;filter:url(#feOffset_w2);" />
<circle cx="370" cy="200" r="60" />
<circle cx="370" cy="200" r="60" style="fill:blue;filter:url(#feOffset_w3);" />
<circle cx="520" cy="200" r="60" />
<circle cx="520" cy="200" r="60" style="fill:blue;filter:url(#feOffset_w4);" />
<circle cx="70" cy="340" r="60" />
<circle cx="70" cy="340" r="60" style="fill:blue;filter:url(#feOffset_d1);" />
<circle cx="220" cy="340" r="60" />
<circle cx="220" cy="340" r="60" style="fill:blue;filter:url(#feOffset_d2);" />
<circle cx="370" cy="340" r="60" />
<circle cx="370" cy="340" r="60" style="fill:blue;filter:url(#feOffset_d3);" />
<line x1="400" y1="340" x2="460" y2="340" fill="purple"/>
<circle cx="520" cy="340" r="60" />
<circle cx="520" cy="340" r="60" style="fill:blue;filter:url(#feOffset_d4);" />
</g>
<path d="M70,10 v400 M220,10 v400 M220,10 v400 M370,10 v400 M520,10 v400
M10,70 h600 M10,200 h600 M10,340 h600
M280,10 v400 M430,10 v400 M550,10 v400" stroke="red" stroke-width="1" />
</svg>