如何将clipPath应用于带有相对于div位置的clipPath位置的div

3

我不确定标题是否表达准确,但以下是问题。

我有一个类似云形的SVG路径,我想在CSS中使用clip-path属性。

<path d="M46.9819755,61.8637972 C42.0075109,66.8848566 35.0759468,70 27.4091794,70 C12.2715076,70 0,57.8557238 0,42.875 C0,32.9452436 5.3914988,24.2616832 13.4354963,19.534921 C14.8172134,8.52285244 24.3072531,0 35.8087666,0 C43.9305035,0 51.0492374,4.2498423 55.01819,10.6250065 C58.2376107,8.87215568 61.9363599,7.875 65.8704472,7.875 C78.322403,7.875 88.4167076,17.8646465 88.4167076,30.1875 C88.4167076,32.1602271 88.1580127,34.0731592 87.6723639,35.8948845 L87.6723639,35.8948845 C93.3534903,38.685457 97.2583784,44.4851888 97.2583784,51.1875 C97.2583784,60.6108585 89.5392042,68.25 80.0171204,68.25 C75.4841931,68.25 71.3598367,66.5188366 68.2822969,63.6881381 C65.5613034,65.4654463 62.3012892,66.5 58.7971106,66.5 C54.2246352,66.5 50.0678912,64.7384974 46.9819755,61.8637972 Z" fill="lightblue" />

当我在HTML中添加一个SVG元素,并使用该路径定义<clipPath>时,浏览器会将裁剪路径定位在左上角。如果我给被裁剪的元素应用边距,那么遮罩就没有链接到元素,仍停留在其初始位置。
其他类似的线程说明需要将属性clipPathUnits="objectBoundingBox"添加到<clipPath>对象中,但这似乎并不能解决我的问题。我甚至将路径从绝对路径转换为相对路径,并尝试以这种方式执行,但结果相同。
是否可能以某种方式将剪裁路径与被裁剪元素关联起来,使当应用于被裁剪元素时,裁剪路径也会移动?
如果有帮助,这是相对路径:
<path d="M46.9819755,61.8637972c-4.974,5.021,-11.906,8.136,-19.573,8.136c-15.137,0,-27.409,-12.144,-27.409,-27.125c0,-9.93,5.392,-18.613,13.436,-23.34c1.381,-11.012,10.871,-19.535,22.373,-19.535c8.122,0,15.24,4.25,19.209,10.625c3.22,-1.753,6.918,-2.75,10.852,-2.75c12.452,0,22.547,9.99,22.547,22.313c0,1.972,-0.259,3.885,-0.745,5.707l0,0c5.682,2.791,9.586,8.59,9.586,15.293c0,9.423,-7.719,17.062,-17.241,17.062c-4.533,0,-8.657,-1.731,-11.735,-4.562c-2.721,1.778,-5.981,2.812,-9.485,2.812c-4.572,0,-8.729,-1.761,-11.815,-4.636z fill="lightblue" />

还有一些测试 HTML/CSS。(我将 left 属性设置为 10px,以便您看到剪切问题发生)

.clippedElement {
  width: 200px;
  height: 200px;
  position: absolute;
  left: 10px;
  top: 0;
  background-color: lightblue;
  -webkit-clip-path: url(#cloudClip);
  -moz-clip-path: url(#cloudClip);
  clip-path: url(#cloudClip);
}
<svg>
  <defs>
    <clipPath id="cloudClip">
      <path d="M46.9819755,61.8637972 C42.0075109,66.8848566 35.0759468,70 27.4091794,70 C12.2715076,70 0,57.8557238 0,42.875 C0,32.9452436 5.3914988,24.2616832 13.4354963,19.534921 C14.8172134,8.52285244 24.3072531,0 35.8087666,0 C43.9305035,0 51.0492374,4.2498423 55.01819,10.6250065 C58.2376107,8.87215568 61.9363599,7.875 65.8704472,7.875 C78.322403,7.875 88.4167076,17.8646465 88.4167076,30.1875 C88.4167076,32.1602271 88.1580127,34.0731592 87.6723639,35.8948845 L87.6723639,35.8948845 C93.3534903,38.685457 97.2583784,44.4851888 97.2583784,51.1875 C97.2583784,60.6108585 89.5392042,68.25 80.0171204,68.25 C75.4841931,68.25 71.3598367,66.5188366 68.2822969,63.6881381 C65.5613034,65.4654463 62.3012892,66.5 58.7971106,66.5 C54.2246352,66.5 50.0678912,64.7384974 46.9819755,61.8637972 Z"
      />
    </clipPath>
  </defs>
</svg>
<div class="clippedElement"></div>


1
为什么objectBoundingBox不能解决你的问题? - Robert Longson
我不确定。当我添加那个属性时,div根本不显示。它只是纯白色的。随意尝试操作示例代码。 - Lazar Vuckovic
2
你需要将所有的用户单位值转换为边界框单位值。边界框值应该在0到1的范围内。我猜在你的情况下,这意味着将所有的值除以200。 - Robert Longson
感谢您的输入。我已经使用RaphaelJS将路径转换为相对路径,但我猜这不是它应该去的地方。我明天才能测试这个,但我会让您知道最新情况。 - Lazar Vuckovic
1
嗨,罗伯特,只是想感谢你指引我正确的方向。我成功解决了问题。答案已经发布,附带一个小的PHP代码片段,我用它来将路径转换为边界框值。 - Lazar Vuckovic
1个回答

10

感谢Robert的评论,我解决了我的问题。

这里是我使用的PHP片段,用于将绝对路径转换为相对路径,以便值介于0和1之间。

$absolute_path = "M46.9819755,61.8637972 C42.0075109,66.8848566 35.0759468,70 27.4091794,70 C12.2715076,70 0,57.8557238 0,42.875 C0,32.9452436 5.3914988,24.2616832 13.4354963,19.534921 C14.8172134,8.52285244 24.3072531,0 35.8087666,0 C43.9305035,0 51.0492374,4.2498423 55.01819,10.6250065 C58.2376107,8.87215568 61.9363599,7.875 65.8704472,7.875 C78.322403,7.875 88.4167076,17.8646465 88.4167076,30.1875 C88.4167076,32.1602271 88.1580127,34.0731592 87.6723639,35.8948845 L87.6723639,35.8948845 C93.3534903,38.685457 97.2583784,44.4851888 97.2583784,51.1875 C97.2583784,60.6108585 89.5392042,68.25 80.0171204,68.25 C75.4841931,68.25 71.3598367,66.5188366 68.2822969,63.6881381 C65.5613034,65.4654463 62.3012892,66.5 58.7971106,66.5 C54.2246352,66.5 50.0678912,64.7384974 46.9819755,61.8637972 Z";
function regex_callback($matches) {
    static $count = -1;
    $count++;
    $width = 98;
    $height = 70;
    if($count % 2) {
        return $matches[0] / $height;
    } else {
        return $matches[0] / $width;
    }
}

$relative_path = preg_replace_callback('(\d+(\.\d+)?)', 'regex_callback', $absolute_path);

由于裁剪路径不是矩形,我无法使用一个数字来分割数值,而必须使用裁剪路径本身的宽度和高度。

.clippedElement {
  width: 98px;
  height: 70px;
  position: absolute;
  left: 10px;
  top: 0;
  background-color: lightblue;
  -webkit-clip-path: url(#cloudClip);
  -moz-clip-path: url(#cloudClip);
  clip-path: url(#cloudClip);
}
<svg width="98" height="70">
<defs>
    <clipPath id="cloudClip" clipPathUnits="objectBoundingBox">
        <path d="M0.47940791326531,0.88376853142857 C0.42864807040816,0.95549795142857 0.3579178244898,1 0.27968550408163,1 C0.12521946530612,1 0,0.82651034 0,0.6125 C0,0.47064633714286 0.055015293877551,0.34659547428571 0.13709690102041,0.2790703 C0.15119605510204,0.12175503485714 0.24803319489796,0 0.36539557755102,0 C0.44827044387755,0 0.52091058571429,0.060712032857143 0.56141010204082,0.15178580714286 C0.59426133367347,0.12674508114286 0.63200367244898,0.1125 0.67214742040816,0.1125 C0.79920819387755,0.1125 0.90221130204082,0.25520923571429 0.90221130204082,0.43125 C0.90221130204082,0.45943181571429 0.89957155816327,0.48675941714286 0.89461595816327,0.51278406428571 L0.89461595816327,0.51278406428571 C0.95258663571429,0.55264938571429 0.99243243265306,0.63550269714286 0.99243243265306,0.73125 C0.99243243265306,0.86586940714286 0.91366534897959,0.975 0.81650122857143,0.975 C0.77024686836735,0.975 0.72816159897959,0.95026909428571 0.69675813163265,0.90983054428571 C0.66899289183673,0.93522066142857 0.63572744081633,0.95 0.59997051632653,0.95 C0.55331260408163,0.95 0.51089684897959,0.92483567714286 0.47940791326531,0.88376853142857 Z"></path>
    </clipPath>
</defs>
</svg>
<div class="clippedElement"></div>


一个非常棒的代码!<3 相关问题请参见这里,其中包含更多信息。 - giovannipds
您,真应该得到一枚奖牌!非常感谢。 - giovannipds
更多人遇到了同样的问题 - giovannipds
2
我发现了这个在线工具,你可以输入路径坐标,它会将其转换为对象边界框所需的分数/十进制系统 - yoksel.github.io/relative-clip-path - 真不错! - Gavin Kemp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接