clip-rule

clip-rule CSS 属性定义了如何确定遮罩框中的哪些像素在由 剪切路径 定义的剪切形状内,哪些在形状外,当路径的某些部分与其他部分重叠时。具体来说,它在确定包含时选择“非零”和“奇偶”方法。clip-rule 可以应用于所有 SVG 元素,但仅对作为剪切路径一部分的元素有效。clip-rule 属性的 CSS 值可以覆盖 clip-rule 属性的 SVG 值。

语法

css
/* Keywords */
clip-rule: nonzero;
clip-rule: evenodd;

/* Global values */
clip-rule: inherit;
clip-rule: initial;
clip-rule: revert;
clip-rule: revert-layer;
clip-rule: unset;

nonzero

对于剪切遮罩框中的每个点,都会以随机方向绘制一条射线。每当射线与剪切路径的任何部分相交时,如果剪切路径的部分从左到右穿过射线,则计数增加 1,而如果路径部分从右到左穿过射线,则计数减少 1。如果计数的最终总数为零,则该点在路径形状之外。否则,它在路径形状内。

even-odd

对于剪切遮罩框中的每个点,都会以随机方向绘制一条射线。每当射线与剪切路径的任何部分相交时,计数增加 1。如果计数的最终总数为偶数,则该点在路径形状之外;否则,它在路径形状内。零被视为偶数。

正式语法

clip-rule = 
nonzero |
evenodd

示例

为具有所有顺时针路径的路径选择规则

在这个 SVG 图像中,我们有两个被剪切的矩形,每个矩形都使用一个剪切规则。有两个 <clipPath> 元素,以便可以将一个设置为使用非零剪切规则,另一个使用奇偶规则。两个路径都以顺时针方向绘制其内部和外部部分。

html
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 50">
  <g stroke="#123" fill="#BCD">
    <!-- basic rectangle and clipping path visualization follow -->
    <rect x="10" y="10" width="30" height="30" />
    <path
      d="M 65,5 l 20,20 -20,20 -20,-20 20,-20 m 0,10 l 10,10 -10,10 -10,-10 10,-10 z"
      fill="none"
      stroke-width="0.5" />
    <!-- rectangles to be clipped follow -->
    <rect x="110" y="10" width="30" height="30" clip-path="url(#clipper1)" />
    <rect x="160" y="10" width="30" height="30" clip-path="url(#clipper2)" />
  </g>
  <!-- clipping paths follow -->
  <clipPath id="clipper1" clipPathUnits="objectBoundingBox">
    <path
      d="M 0.5 -0.15 l 0.65 0.65 -0.65,0.65 -0.65,-0.65 0.65,-0.65 m 0,0.33 l 0.33,0.33 -0.33,0.33 -0.33,-0.33 0.33,-0.33 z"
      clip-rule="evenodd" />
  </clipPath>
  <clipPath id="clipper2" clipPathUnits="objectBoundingBox">
    <path
      d="M 0.5 -0.15 l 0.65 0.65 -0.65,0.65 -0.65,-0.65 0.65,-0.65 m 0,0.33 l 0.33,0.33 -0.33,0.33 -0.33,-0.33 0.33,-0.33 z"
      clip-rule="nonzero" />
  </clipPath>
</svg>

对于应用于被剪切矩形的剪切路径,CSS clip-rule 属性用于将一条路径设置为使用 nonzero 规则,另一条路径设置为使用 evenodd 规则。这些会覆盖 SVG 中 clip-path 属性的值,这些值被有意地设置为与 CSS 强加的值相反。

css
#clipper1 {
  clip-rule: nonzero;
}
#clipper2 {
  clip-rule: evenodd;
}

由于路径的内部和外部部分都以顺时针(从左到右)方向移动,因此两种剪切规则产生的剪切形状将不同。对于 nonzero,形状外部部分内的任何射线都会累积到大于零的值,因为它将遇到一个或多个从左到右的路径片段。对于 even-odd,两个路径部分之间的点将具有奇数计数,而任何在内部路径内或外部路径外的点都将具有偶数计数。

为具有不同绕组路径的路径选择规则

此示例使用与上一个示例相同的 SVG,不同之处在于剪切路径的内部部分以逆时针方向缠绕。

html
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 50">
  <g stroke="#123" fill="#BCD">
    <!-- basic rectangle and clipping path visualization follow -->
    <rect x="10" y="10" width="30" height="30" />
    <path
      d="M 65,5 l 20,20 -20,20 -20,-20 20,-20 m 0,10 l 10,10 -10,10 -10,-10 10,-10 z"
      fill="none"
      stroke-width="0.5" />
    <!-- rectangles to be clipped follow -->
    <rect x="110" y="10" width="30" height="30" clip-path="url(#clipper1)" />
    <rect x="160" y="10" width="30" height="30" clip-path="url(#clipper2)" />
  </g>
  <!-- clipping paths follow -->
  <clipPath id="clipper1" clipPathUnits="objectBoundingBox">
    <path
      d="M 0.5 -0.15 l 0.65 0.65 -0.65,0.65 -0.65,-0.65 0.65,-0.65 m 0,0.33 l -0.33,0.33 0.33,0.33 0.33,-0.33 -0.33,-0.33 z" />
  </clipPath>
  <clipPath id="clipper2" clipPathUnits="objectBoundingBox">
    <path
      d="M 0.5 -0.15 l 0.65 0.65 -0.65,0.65 -0.65,-0.65 0.65,-0.65 m 0,0.33 l 0.33,0.33 -0.33,0.33 -0.33,-0.33 0.33,-0.33 z" />
  </clipPath>
</svg>

我们应用与之前相同的 CSS。

css
#clipper1 {
  clip-rule: nonzero;
}
#clipper2 {
  clip-rule: evenodd;
}

在这种情况下,由于路径的外部部分以顺时针(从左到右)方向移动,而路径的内部部分以逆时针(从右到左)方向移动,因此无论使用哪种剪切规则,最终的剪切形状都将相同。

规范

规范
CSS 遮罩模块级别 1
# the-clip-rule

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅