fedisplacementmap 是一种svg滤镜,通过位移贴图的像素亮度值对目标图形进行像素级偏移扭曲,不改变原始路径,仅影响渲染采样;贴图需同源/cors、尺寸匹配、灰度有效、scale非零,且须用feimage引入并指定in2引用。

feDisplacementMap 是什么,它怎么扭曲图形
feDisplacementMap 不是直接画图或上色的滤镜,而是用一张“位移贴图”(displacement map)的像素亮度值,去推动目标图形的每个像素点发生偏移。贴图越亮,对应位置的图形像素就往指定方向(dx/dy)挪得越远;越暗则反向挪。关键点在于:它不改变图形本身形状或路径,只在渲染时做像素级重采样——所以源图形必须是栅格化可采样的(比如 <image></image>、带描边/填充的 <path></path>,或包裹在 <g></g> 里的组合),纯矢量路径若没光栅化可能无效果。
位移贴图必须满足哪些条件才能生效
浏览器对位移贴图有硬性要求,不符合就静默失效(图形看起来完全没变化):
- 贴图必须通过
<feimage></feimage>引入,且需同源或已设置 CORS(跨域图片会触发安全错误,控制台报Unable to get image data from canvas) - 贴图尺寸建议与目标图形宽高一致,否则会自动拉伸,导致位移比例失真
- 必须是灰度信息有效的图像:PNG(带 alpha 也可)、JPEG 都行,但 SVG 贴图需确保内部没有未渲染的
<filter></filter>或动态<animate></animate>,否则部分浏览器(如 Safari)可能读不到像素值 -
scale属性不能为 0;典型值在 1–30 之间,scale="0"相当于关闭位移,scale="50"可能导致大面积像素丢失
如何写一个最小可用的位移扭曲示例
下面是一个可直接运行的 HTML 片段,用一张简单渐变 PNG 作为位移贴图,扭曲一个红色圆形:
<svg width="300" height="300"><defs><filter id="displace"><feimage href="displace-map.png" result="map"></feimage><fedisplacementmap in="SourceGraphic" in2="map" scale="8" xchannelselector="R" ychannelselector="G"></fedisplacementmap></filter></defs><circle cx="150" cy="150" r="80" fill="red" filter="url(#displace)"></circle></svg>
注意几个实操细节:
-
in2="map"必须指向<feimage></feimage>的result名,不能写成href地址 -
xChannelSelector和yChannelSelector默认是R和G,意味着用贴图红色通道控制水平位移、绿色通道控制垂直位移;若贴图只有灰度,用R或Luminance都可以,但Luminance在 Firefox 中支持更稳 - Chrome 和 Edge 对
feImage的href支持 data URL,但 Safari 要求必须是真实路径或 Blob URL
常见失效原因和调试方法
图形没扭曲?先别改 scale,检查这几个地方:
- 打开开发者工具 → Elements 面板,确认
<feimage></feimage>节点是否被解析(有些浏览器会把无效 href 当作空节点忽略) - 把
feDisplacementMap暂时换成feColorMatrix并设values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0",看图形是否正常显示——排除源图形本身不可滤镜的问题 - 临时把位移贴图换成纯白 PNG,再换成纯黑 PNG,观察图形是否分别朝相反方向整体偏移——验证通道映射和
scale是否起作用 - 在
<filter></filter>内加一个<fecomposite operator="in" in="map" in2="SourceGraphic"></fecomposite>,把贴图直接叠在图形上,确认贴图是否加载成功并可见
位移是亚像素级重采样操作,过度依赖高 scale 值或低分辨率贴图,容易出现边缘撕裂或模糊,实际项目中建议在 5–15 区间内微调,并始终用 image-rendering: pixelated 控制贴图缩放行为(如果贴图是程序生成的)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











