渐变Pattern与滤镜
渐变和 pattern 的坐标在 gradientUnits / patternUnits 里,不在你想象的「贴在物体上」。滤镜会把矢量子树打成中间位图。三者都是生产里对齐失败和掉帧的高发区。
1. objectBoundingBox 与零尺寸
默认 gradientUnits="objectBoundingBox":x1 y1 x2 y2 是包围盒上的 0..1 比例,不是用户单位。
<linearGradient id="g" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#3b5bfd"/>
<stop offset="1" stop-color="#9b87f5"/>
</linearGradient>
包围盒宽或高为 0(水平 line、零高度 rect、退化 transform)时,按规范这个坐标系建不出来,渐变经常变成透明或纯黑,三引擎表现还不一致。
export function canUseObjectBoundingBox(el: SVGGraphicsElement): boolean {
const box = el.getBBox({ fill: true, stroke: false, markers: false, clipped: false });
return box.width > 0 && box.height > 0;
}
细线、坐标轴、1px 分隔:改 userSpaceOnUse,端点写用户单位;或给几何一个最小厚度再填。
userSpaceOnUse 的坐标活在 引用时刻 的用户空间(含该元素 CTM 之前的那套)。相机靠改 viewBox 时,用户单位下的端点跟着文档走,这通常是你要的。不要把 CSS 像素写进 userSpaceOnUse 还指望缩放后仍贴边。
2. Pattern 两套单位
patternUnits 管瓦片怎么铺到物体上;patternContentUnits 管 pattern 内部图形怎么解释。默认也是 objectBoundingBox,同样会在零尺寸盒上失败。
生产约定:
- 图标/卡片的装饰底纹:
objectBoundingBox,内容用 0..1。 - 世界坐标网格、地图纹理:两边都
userSpaceOnUse,内容按用户单位画一格,用patternTransform只描述「一砖多大」,不要再乘相机 scale。相机是 viewBox,见 相机与锚点缩放。
href 引用别的 pattern 做 inheriting,新代码同样不要 xlink:href。
3. 滤镜会光栅化
filter 把作用对象(含后代)画进离屏缓冲再做 feGaussianBlur 等。输出是位图,放大后发糊、旋转后边缘锯齿,都是预期。
半径、stdDeviation 在 滤镜区的用户空间 里。改 viewBox 放大「相机」时,同样的 blur(8) 打在更大缓冲上——和 Canvas filter 被 CTM 放大是同一类成本。
| 做法 | 适用 | 不适用 |
|---|---|---|
| 静态阴影预烘焙进 path / PNG | 图标、徽章 | 每帧形状都变 |
局部 filter 在叶子上 | 单个悬浮高亮 | 整棵场景 <g filter> |
userSpaceOnUse 滤镜区 | 要钉死在世界坐标的灯光 | 跟着物体包围盒的倒影 |
| 导出时离线滤镜 | 出 PNG/PDF | 交互热路径 |
filterUnits 默认 objectBoundingBox,区是盒外扩 x y width height(默认 -10% / 120%)。模糊被裁切:区太小。区太大:缓冲爆炸。零尺寸盒同样让滤镜区退化。
组上的 opacity 也会逼出离屏层,见 绘制顺序与层叠。滤镜 + 组透明度叠加接近相乘,生产里别叠。
4. 适用 / 不适用
适用:主题化图标渐变、小面积卡片阴影、导出时的一次性处理。
不适用:无限画布每帧全场景 blur、用滤镜模拟布尔挖洞、用 pattern 当瓦片引擎(节点数和重绘见 06 性能)。
5. 失败形态
| 症状 | 原因 |
|---|---|
| 直线/细 rect 渐变消失 | objectBoundingBox 宽或高为 0 |
| 缩放后模糊核变成「糊全屏」 | 滤镜半径 × 相机放大,滤镜打在巨大组上 |
| 砖块双重缩放 | patternTransform 又乘了 CSS scale / 相机 |
| 模糊被方框裁死 | 默认滤镜区 120% 不够 stdDeviation |
| 渐变跟着物体「滑出」 | 混用了 userSpaceOnUse 端点与物体局部坐标 |
权威资料
核对日期:2026-08-26