暗黑模式
裁剪和遮罩
前端教程SVG
裁剪(clipping)
<svg> 的内容如果超过了视口,超出的部分就不会被绘制(当 overflow=hidden 时),这就是一种 clipping,裁剪区域是一个矩形。 SVG 通过<clipPath>元素达成任意形状的裁剪,而不局限于矩形。
<clipPath> 基本语法和示例
xml
<clipPath id="clipId" clipPathUnits="userSpaceOnUse">
...childElement
</clipPath>
<xx clip-path="url(#clipId)" />1
2
3
4
2
3
4
chipPathUnits="userSpaceOnUse|objectBoundingBox"子元素所使用的坐标系统,与前面学过 *Units 类似,默认 userSpaceOnUse- userSpaceOnUse:相对于整个 SVG
- objectBoundingBox:
<clipPath>是一个 1×1 的方形,因此<clipPath>内的元素使用的数值介于 0~1
- childElement 可以是:
- 形状元素,
<rect><circle><ellipse><polygon><path> - 文本元素,
<text> <use>元素
- 形状元素,
下面的 codepen 列举了2个例子:
- 左图使用了
<polygon>为三角形的<clipPath> - 右图使用了
<text>为“上海”的<clipPath>
裁剪函数
除了定义 <clipPath> 元素并通过 url() 来引用裁剪之外,SVG 也支持许多简写的裁剪函数:
circle()圆形ellipse()椭圆inset()矩形polygon()多边形path()自定义路径
直接使用 CSS 的 property 来引用这些函数:
css
.someShape {
clip-path: path(...);
}1
2
3
2
3
path()函数只接受用户单位的坐标(不能是 cm/mm 这样的长度,也不能是百分比),其他函数没有此限制。circle()和ellipse()这两个函数不常用,因为我们可以使用border-radius和overflow: hidden来达成相同的果效
下面的 codepen 中示范了 polygon() 的用法:
- 上部分中:HTML的
<header>,<header>:before,<h1>都应用了裁剪,所以可以看到3个重叠的裁剪区域; - 下部分中:SVG的
<image>应用了同样的裁剪。 polygon(...)使用了 CSScalc()函数,因此可以实现响应式calc(100% -30px) 0即 X 坐标是 100% width 减去 30,Y 坐标是 0;100% calc(100% -30px)即 X 坐标是 100% width,Y 坐标是 100% height 减去 30;
遮罩(masking)
<clipPath> 的一个限制是:要么让某个区域显示、要么完全不显示,无法做到让某个区域按照需求透明化; opacity``fill-opacity 可以实现透明化,但是也有限制:只能对整个图形透明化,无法精确到细节; 此时我们需要用 <mask> 元素来达成按需透明化图形的效果:可以把 <mask> 元素当成一个灰度图来看,图中纯黑色 #000000 代表完全透明,纯白色 #FFFFFF 代表完全不透明。
基本语法和示例
xml
<mask id="myMask" maskUnits="" maskContentUnits="" x="" y="" width="" height="">
...childElement
</mask>1
2
3
2
3
maskUnits="userSpaceOnUse | objectBoundingBox"定义了xywidthheight所使用的坐标系统,默认 objectBoundingBox- objectBoundingBox 定义
<mask>为 1×1 的方形 - userSpaceOnUse 相对于整个 SVG
- objectBoundingBox 定义
maskContentUnits="userSpaceOnUse | objectBoundingBox"定义了<mask>内部元素所使用的坐标系统,默认 userSpaceOnUse- objectBoundingBox 定义
<mask>为 1×1 的方形 - userSpaceOnUse 相对于整个 SVG
- objectBoundingBox 定义
xy定义了<mask>元素的左上角坐标,默认(-10%, -10%)widthheight定义了<mask>元素的宽高,默认都是 120%
通过下面的 codepen 来实际感受一下:
- 左图:原始图片
- 中间图:背景色为径向渐变的矩形,中间区域完全白色,代表完全不透明,向外逐渐变为黑色,代表逐渐透明直至完全不显示;此例中的
<mask>就用这个矩形来作为灰度图使用; - 右图:原始图片 +
<mask>合成的图片
双色调图片
什么是双色调(或多色调)?大家可以参考这个教程了解一下,我们使用 SVG <mask>实现与教程里类似的效果:
你也可以通过以下的 codepen 来交互操作、感受<mask>实现双色调图片的原理:
CSS mask
CSS Masking 模块引入了更加精简的遮罩语法:mask mask-image mask-mode mask-size mask-composite,然而目前主流浏览器尚未支持~~;
更多请参考 MDN - mask
小结
本节我们讲解了 SVG 中如何实现裁剪和遮罩,下一节我们介绍 filters(滤镜) 和 blend(混合)。






