带有剪切路径的svg文本无法正确剪切?

时间:2018-10-18 10:16:49

标签: svg clip-path

将clipPath应用于以下svg中的text元素时遇到问题。

<!DOCTYPE html>
<html>

<head>
  <title>Svg clipping issue</title>
</head>

<body>
  <div style="width:500px;height:180px;">
    <svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" height="100%"
      width="100%">
      <defs>
        <clipPath id="myClip">
          <rect transform="matrix(1,-0,-0,1,-0,-25.7478256)" x="198.1017" y="98.565216" width="65" height="25"></rect>
        </clipPath>
      </defs>
      <polygon points="198.1017,98.565216 263.84082,98.565216 263.84082,72.817383 198.1017,72.817383" clip-path="url(#myClip)"
        fill="#FF0000" stroke-width="none"></polygon>
      <text transform="matrix(1,-0,-0,1,-0,-25.7478256)" clip-path="url(#myClip)" font-family="Microsoft Sans Serif"
        font-size="8.25pt" fill="#000000">
        <tspan text-anchor="middle" x="230.6017" y="108.755646">Line 1</tspan>
        <tspan text-anchor="middle" x="230.6017" y="121.205841">A very very long line</tspan>
      </text>
      <rect transform="matrix(1,-0,-0,1,-0,-25.7478256)" x="198" y="98" width="65" height="25" fill="none" stroke="#0000FF"></rect>

    </svg>
  </div>
</body>

</html>

clipPath应用于多边形和文本元素。在多边形上,clipPath可以正常工作,因为我们仍然可以看到多边形。

在文本上有一个问题,整个文本是clipped,但看起来应该像this

如果我们从文本元素中删除clipPath,显然我们可以see整个文本,但这不是我们想要的。

任何人都知道发生了什么事,或者这是浏览器中的渲染错误?在Firefox,Chrome,Edge,IE上我们得到相同的结果。

2 个答案:

答案 0 :(得分:4)

您遇到的问题是因为应用于元素的任何变换也都将应用于与其附加的剪辑路径。因此您的剪辑路径被

变换了两次
transform="matrix(1,-0,-0,1,-0,-25.7478256)"

位于<text>元素和<clipPath>元素上。

您可以通过几种方式解决此问题:

  1. transform元素中删除<text>并更改其坐标,以使其正确地位于矩形上方。或反过来做矩形。
  2. 将矩形和文本都包装在一个组中,并对其应用剪切路径(如@Mehdi所建议的那样)
  3. 单独制作<clipPath>,不进行转换。 请参见下面的示例

<!DOCTYPE html>
<html>

<head>
  <title>Svg clipping issue</title>
</head>

<body>
  <div style="width:500px;height:180px;">
    <svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" height="100%"
      width="100%">
      <defs>
        <clipPath id="myClip">
          <rect transform="matrix(1,-0,-0,1,-0,-25.7478256)" x="198.1017" y="98.565216" width="65" height="25"></rect>
        </clipPath>
        <clipPath id="myClip2">
          <rect x="198.1017" y="98.565216" width="65" height="25"></rect>
        </clipPath>
      </defs>
      <polygon points="198.1017,98.565216 263.84082,98.565216 263.84082,72.817383 198.1017,72.817383" clip-path="url(#myClip)"
        fill="#FF0000" stroke-width="none"></polygon>
      <text transform="matrix(1,-0,-0,1,-0,-25.7478256)" clip-path="url(#myClip2)" font-family="Microsoft Sans Serif"
        font-size="8.25pt" fill="#000000">
        <tspan text-anchor="middle" x="230.6017" y="108.755646">Line 1</tspan>
        <tspan text-anchor="middle" x="230.6017" y="121.205841">A very very long line</tspan>
      </text>
      <rect transform="matrix(1,-0,-0,1,-0,-25.7478256)" x="198" y="98" width="65" height="25" fill="none" stroke="#0000FF"></rect>

    </svg>
  </div>
</body>

</html>

答案 1 :(得分:1)

问题可能与clip-path is not applicable to a tspan的事实有关。

您可以通过将裁剪应用于包含textpolygon的组来解决此问题:

 <g clip-path="url(#myClip)">
      <polygon /* ... */></polygon>
      <text transform="matrix(1,-0,-0,1,-0,-25.7478256)" font-family="Microsoft Sans Serif" font-size="8.25pt" fill="#000000">
        /* ... */
      </text>
  </g>

更新的代码段:

<!DOCTYPE html>
<html>

<head>
  <title>Svg clipping issue</title>
</head>

<body>
  <div style="width:500px;height:180px;">
    <svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" height="100%"
      width="100%">
      <defs>
        <clipPath id="myClip">
          <rect transform="matrix(1,-0,-0,1,-0,-25.7478256)" x="198.1017" y="98.565216" width="65" height="25"></rect>
        </clipPath>
      </defs>
      <g clip-path="url(#myClip)">
          <polygon points="190.1017,120.565216 263.84082,98.565216 263.84082,72.817383 198.1017,72.817383"
        fill="#FF0000" stroke-width="none"></polygon>
          <text transform="matrix(1,-0,-0,1,-0,-25.7478256)" font-family="Microsoft Sans Serif" font-size="8.25pt" fill="#000000">
            <tspan text-anchor="middle" x="230.6017" y="108.755646">Line 1</tspan>
            <tspan text-anchor="middle" x="230.6017" y="121.205841" >A very very long line</tspan>
          </text>
      </g>
      <rect transform="matrix(1,-0,-0,1,-0,-25.7478256)" x="198" y="98" width="65" height="25" fill="none" stroke="#0000FF"></rect>

    </svg>
  </div>
</body>

</html>