feDisplacementMap是一个位置替换滤镜,就是改变元素和图形的像素位置的,使用feDisplacementMap重新映射替换一个新的位置,形成一个新的图形。根据设定的通道颜色对原图的x, y坐标进行偏移
公式来源:P'(x,y) ← P( x + scale * (XC(x,y) - 0.5), y + scale * (YC(x,y) - 0.5))
- P'(x,y)指的是转换之后的x, y坐标
- x + scale * (XC(x,y) - 0.5), y + scale * (YC(x,y) - 0.5)指的是具体的转换规则。
- XC(x,y)表示当前x,y坐标像素点其X轴方向上设置的对应通道的计算值,范围是0~1。
- YC(x,y)表示当前x,y坐标像素点其Y轴方向上设置的对应通道的计算值,范围是0~1。
- -0.5是偏移值,因此XC(x,y) - 0.5范围是-0.5~0.5,YC(x,y) - 0.5范围也是-0.5~0.5。
- scale表示计算后的偏移值相乘的比例,scale越大,则偏移越大。
xChannelSelector对应XC(x,y),表示X轴坐标使用的是哪个颜色通道进行位置偏移。我们应该都知道,颜色有RGBA四个通道,R表示red红色,G表示green绿色,B表示blue蓝色,A表示alpha可以理解为透明度。因此,xChannelSelector属性值可以是R、G、B、A中的任意一个,默认是A,基于透明度进行位置偏移。
如果xChannelSelector取A,当A=0.5时,此时是没有偏移的,因为(XC(x,y) - 0.5) = 0,
color-interpolation-filters表示滤镜对颜色进行计算时候采用的颜色模式类型。分为linearRGB(默认值)和sRGB
目前Safari 不支持sRGB,所有给linearRGB就可以了。
对于<feDisplacementMap>元素,in表示输入的原始图形,in2表示用来映射的图形。
scale很好理解,就是公式里面的缩放比例,可正可负,默认是0。通常使用正数值处理,值越大,偏移越大
map.png<body>
<input type="range" max="100" min="1" step="1" id="control">
<svg>
<defs>
<filter id="filter-ripple">
<feImage xlink:href="./map.png" x="0" y="0" width="256" height="256" result="ripple"></feImage>
<feDisplacementMap color-interpolation-filters="linearRGB" in="SourceGraphic" in2="ripple" scale="10"></feDisplacementMap>
</filter>
</defs>
</svg>
<svg width="256" height="192" style="outline:1px dotted;">
<image xlink:href="./demo.jpg" width="256" height="192" filter="url(#filter-ripple)" ></image>
</svg>
<script >
var bFControl = document.getElementById("control"),
effect = document.querySelector("#filter-ripple > feDisplacementMap");
bFControl.addEventListener("change",updatebFSVG);
bFControl.addEventListener("input",updatebFSVG);
function updatebFSVG() {
let v = bFControl.value;
effect.setAttribute("scale", v);
}
</script>
</body>
根据透明度计算,map.png左边的透明度是1,右边的是0,
假设scale是40
左边的:x轴偏移 40(1-0.5) = 20 ,y轴偏移 40(1-0.5) = 20
右边的:x轴偏移 40(0-0.5) = -20 ,y轴偏移 40(0-0.5) = -20
网友评论