javascript - 如何从 SVG 路径的交集找到新路径(形状)?

标签 javascript node.js svg snap.svg

我需要将 2 条 SVG 路径相交并获取与它们相交的路径。

它应该在浏览器或 Node.js 中工作(其中任何一个,而不是两者)。
我需要交集,clip-path 的使用不正确。
如果由于某种原因交集将使用 transform 没关系(我会自己删除它)。

我认为有一个库,但我只找到了


例如相交以下路径:

M 24.379464,51.504463 23.434524,23.156249 38.742559,12.572916 c 0,0 29.860118,-9.0714281 17.00893,0.755953 -12.851191,9.82738 13.229166,19.465774 13.229166,19.465774 z
m 32.883928,0.28869028 c 0,0 -15.686011,1.51190452 -8.504463,7.18154712 7.181546,5.6696426 50.270836,30.0491076 26.458332,42.3333336 -23.8125,12.284226 47.058036,14.174107 47.058036,14.174107 z

我想得到这样的东西:

M 43.943359 11.123047 C 40.995759 11.900151 38.742188 12.572266 38.742188 12.572266 L 35.236328 14.996094 C 44.091432999999995 21.21816 55.052161 29.822765 57.455078 37.628906 L 66.939453 33.650391 63.632812 30.410156 C 58.77426 27.95814 52.364322 23.85552 52.214844 19.224609 L 43.943359 11.123047 z

这是示例中带有 path 的交互式片段(忽略颜色 - 它们是为了清楚起见)- 需要从 #path1 获取 Intersection> 和 #path2:

svg { width: 10em; width: 100vmin; outline: 1px dotted blue; display: none; }
input { display: none; }
label { width: 10em; float: left; clear: left; cursor: pointer; line-height: 2em; margin: 0 .5em .25em 0; padding: 0 .25em; border: 1px solid; }
:checked + * + * + label { background: antiquewhite; color: blue; }
:checked + * + * + * + * + * + svg { display: inline-block; }
<input type=radio name=svg id=in checked>
<input type=radio name=svg id=out>
<input type=radio name=svg id=cp>

<label for=in>Input</label>
<label for=out>Intersection</label>
<label for=cp>Clip</label>

<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="22 0 76 64">
  <path id="path1"
    style="fill:rgba(255,0,0,.5); stroke:red;stroke-width:0.26458332px;"
    d="M 24.379464,51.504463 23.434524,23.156249 38.742559,12.572916 c 0,0 29.860118,-9.0714281 17.00893,0.755953 -12.851191,9.82738 13.229166,19.465774 13.229166,19.465774 z"
  />
  <path id="path2"
    style="fill:rgba(0,255,0,.5);stroke:green;stroke-width:0.26458332px;"
    d="m 32.883928,0.28869028 c 0,0 -15.686011,1.51190452 -8.504463,7.18154712 7.181546,5.6696426 50.270836,30.0491076 26.458332,42.3333336 -23.8125,12.284226 47.058036,14.174107 47.058036,14.174107 z"
  />
</svg>

<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="22 0 76 64">
  <path
    style="fill:rgba(0,0,255,.5);stroke:blue;stroke-width:0.26458332px;"
    d="M 43.943359 11.123047 C 40.995759 11.900151 38.742188 12.572266 38.742188 12.572266 L 35.236328 14.996094 C 44.091432999999995 21.21816 55.052161 29.822765 57.455078 37.628906 L 66.939453 33.650391 63.632812 30.410156 C 58.77426 27.95814 52.364322 23.85552 52.214844 19.224609 L 43.943359 11.123047 z"
  />
</svg>

<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="22 0 76 64">
  <clipPath id="clip2">
    <use xlink:href="#path2" />
  </clipPath>
  <use xlink:href="#path1" clip-path="url(#clip2)" />
</svg>

Snap.svg 示例:

var p1 = "M 24.379464,51.504463 23.434524,23.156249 38.742559,12.572916 c 0,0 29.860118,-9.0714281 17.00893,0.755953 -12.851191,9.82738 13.229166,19.465774 13.229166,19.465774 z"
var p2 = "m 32.883928,0.28869028 c 0,0 -15.686011,1.51190452 -8.504463,7.18154712 7.181546,5.6696426 50.270836,30.0491076 26.458332,42.3333336 -23.8125,12.284226 47.058036,14.174107 47.058036,14.174107 z"

var intersection = Snap.path.intersection(p1, p2)

console.log(intersection)
.as-console-wrapper.as-console-wrapper { max-height: 100vh }
<script src=//cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js></script>

附言:Same question in Russian.

最佳答案

我们可以使用 PaperJS bool 运算来实现,它可以使用 SVG 路径进行运算。

PaperJS 有 5 种不同的 bool 运算:exclude , subtract , unite , intersect , divide我们将使用其中一个名称为 intersect 的.此操作也是具有相同名称的函数,它们返回 item对象,具有函数 exportSVG() 。它返回真 SVG Path element ,它具有两条路径相交的新形状。

正确解的例子

paper.install(window);
window.onload = function()
{
    paper.setup('canvas');

    var p1 = 'M 24.379464,51.504463 23.434524,23.156249 38.742559,12.572916 c 0,0 29.860118,-9.0714281 17.00893,0.755953 -12.851191,9.82738 13.229166,19.465774 13.229166,19.465774 z',
        p2 = 'm 32.883928,0.28869028 c 0,0 -15.686011,1.51190452 -8.504463,7.18154712 7.181546,5.6696426 50.270836,30.0491076 26.458332,42.3333336 -23.8125,12.284226 47.058036,14.174107 47.058036,14.174107 z',
        path1 = new Path(p1),
        path2 = new Path(p2);

    path1.fillColor = 'rgba(255,0,0,.5)';
    path1.position = new Point(25, 25);

    path2.fillColor = 'rgba(0,255,0,.5)';
    path2.position = new Point(40, 25);
    
    var result = path2.intersect(path1);
    result.selected = true;
    result.fillColor = '#77f';

    //exportSVG() docu: http://paperjs.org/reference/item/#exportsvg
    var svgPathElement = result.exportSVG(),
        dPath = svgPathElement.getAttribute('d');
    
    document.querySelector('path').setAttribute('d', dPath);

    var output = document.querySelector('#output');
    output.innerHTML = '<pre>' + dPath + '</pre>';
    output.innerHTML += '<xmp>' + svgPathElement.outerHTML + '</xmp>';
};
table
{
    margin-left:14px;
    padding-left:14px;
    border-left:1px solid gray;
    display:inline-block
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.0/paper-full.min.js"></script>

<canvas id="canvas" width="75" height="75" resize></canvas>
<table><tr><td><b>Our new shape of both paths intersection in separate SVG:</b></td></tr>
<tr><td>
    <svg width="75" height="75" viewBox="0 0 75 75">
    <path fill="rgba(0,0,255,.5)" d=""/>
    </svg>
</td></tr></table>

<div id="output"></div>

有用的链接:

关于javascript - 如何从 SVG 路径的交集找到新路径(形状)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50011373/

相关文章:

css - Webkit Animation 在其下方打破 SVG

javascript - JS 数组 - 如何构建数组

javascript - redux 状态值返回未定义

mysql - 如何为我的nodejs项目创建mysql数据库?

javascript - Passport.js 注册似乎有效,但用户凭据未插入数据库

objective-c - 检测一个点是否在 SVG 路径内

javascript - 删除对javascript中另一个对象的引用

javascript - 在 Node.js 中如何将 multipart/form-data 上传的图像转换为 base64 格式

node.js - 使用 vue.js、node.js 和express.js 上传原始文件

angularjs - 使用 CSS 或 AngularJS 的 SVG 路径元素悬停缩放