SVG 图像裁剪与遮罩技术详解
在 SVG 中,可以通过两种方式控制图形的显示区域:裁剪路径(<clipPath>)和遮罩(<mask>)。
裁剪路径 <clipPath>
裁剪路径用于按指定形状对图形进行裁剪,仅保留路径内的部分。关键属性为 clipPathUnits,决定裁剪坐标系统的参考标准。取值包括:
userSpaceOnUse:使用 SVG 整体坐标系统(默认)objectBoundingBox:基于目标图形自身边界框的比例坐标系统
要应用裁剪效果,需将 <clipPath> 元素赋予 ID,并通过图形的 clip-path 属性引用。
示例一:全局坐标裁剪
<svg width="320" height="320" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="clip-shape" clipPathUnits="userSpaceOnUse">
<path d="M60,120 A20,20 0 1 0 60,140 L140,155 L280,130 L140,105 L60,120 Z"/>
</clipPath>
</defs>
<rect x="0" y="60" width="100%" height="150" fill="red"/>
<rect x="0" y="60" width="100%" height="150" fill="#fff" clip-path="url(#clip-shape)"/>
</svg>
示例二:相对坐标裁剪
<svg width="320" height="320" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="relative-clip" clipPathUnits="objectBoundingBox">
<circle cx="0.4" cy="0.5" r="0.2"/>
</clipPath>
</defs>
<rect x="0" y="60" width="100" height="100" fill="red"/>
<rect x="0" y="60" width="100" height="100" fill="#fff" clip-path="url(#relative-clip)"/>
</svg>
遮罩 <mask>
遮罩通过 alpha 通道控制图形透明度,实现更复杂的视觉效果。其核心属性如下:
x,y: 遮罩起始位置,默认 -10%width,height: 遮罩尺寸,默认 120%maskContentUnits: 内容坐标系类型(userSpaceOnUse或objectBoundingBox),默认userSpaceOnUsemaskUnits: 遮罩本身坐标系类型,默认objectBoundingBox
遮罩内部图形的颜色决定了遮盖强度:
- 白色(#FFFFFF)表示完全可见
- 黑色(#000000)表示完全隐藏
- 灰色则对应不同程度的透明度
示例一:基础圆形遮罩
<svg width="320" height="320" xmlns="http://www.w3.org/2000/svg">
<defs>
<mask id="basic-mask"
maskUnits="objectBoundingBox"
maskContentUnits="userSpaceOnUse"
x="0" y="0" width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
<circle cx="100" cy="100" r="60" fill="black"/>
</mask>
</defs>
<rect x="40" y="40" width="60" height="60" fill="red"/>
<rect x="100" y="40" width="60" height="60" fill="green"/>
<rect x="40" y="100" width="60" height="60" fill="blue"/>
<rect x="100" y="100" width="60" height="60" fill="orange"/>
<rect x="40" y="40" width="120" height="120" fill="white" mask="url(#basic-mask)"/>
</svg>
此示例创建了一个"窥视孔"效果,透过黑色圆圈可以看到下层图形。
示例二:渐变遮罩
<svg width="320" height="320" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="fade-out">
<stop offset="0%" stop-color="black"/>
<stop offset="100%" stop-color="white"/>
</radialGradient>
<mask id="gradient-mask"
maskUnits="objectBoundingBox"
maskContentUnits="userSpaceOnUse"
x="0" y="0" width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
<circle cx="100" cy="100" r="60" fill="url(#fade-out)"/>
</mask>
</defs>
<rect x="40" y="40" width="60" height="60" fill="red"/>
<rect x="100" y="40" width="60" height="60" fill="green"/>
<rect x="40" y="100" width="60" height="60" fill="blue"/>
<rect x="100" y="100" width="60" height="60" fill="orange"/>
<rect x="40" y="40" width="120" height="120" fill="white" mask="url(#gradient-mask)"/>
</svg>
利用径向渐变作为遮罩内容,实现了中心清晰、边缘模糊的效果。