是否存在一种JavaScript库,可以对路径(贝塞尔曲线)执行布尔运算?
我知道Paper.js和Raphael.js,但现在都不能执行这些操作。
是否存在一种JavaScript库,可以对路径(贝塞尔曲线)执行布尔运算?
我知道Paper.js和Raphael.js,但现在都不能执行这些操作。
Paper.js现在在其核心中具有布尔运算:
https://github.com/paperjs/paper.js/blob/master/src/path/PathItem.Boolean.js
您可以在此处查看操作示例:
编辑:经测试,我确认pathelement.getPointAtLength()最适合进行命中测试等操作,但对于多边形化来说并不是很好,因为它产生的点太少或太多,并且没有考虑曲率。事实上,紧密的曲线需要更多的点,松散的曲线需要更少的点。更好的方法是将所有路径段转换为三次曲线,并使用一些自适应算法来进行曲线多边形化。我进行了一些测试,可能很快就能介绍一种更好的多边形化方式。
编辑:我已经成功实现了SVG路径多边形化函数,它可以处理各种路径并平铺变换。在测试数千个随机生成的路径和变换时,它似乎是可靠的。而且处理了所有可能的退化情况(曲线共线或某些点相同)而没有问题。虽然它比本地getPointAtLength()快得多,精度也更高,同时生成的点数量显著减少,但该过程仍有提速的空间,例如使用出租车角度代替atan2()以及通过删除所有DOM方法使代码完全兼容Web Workers 。发布之前我想让它百分之百无错误,其理想用例是例如用生成的多边形进行布尔运算的可能性。
我们可以使用PaperJS布尔运算来进行操作,它可以处理SVG路径(包括贝塞尔曲线路径)。
PaperJS有5种不同的布尔运算: exclude
, subtract
, unite
, intersect
, divide
。你可以在这里看到所有这些示例。
这些运算也是同名的函数,并返回item
对象,该对象具有函数exportSVG()
。它返回一个true值的SVG Path元素
,其形状为两个路径的交集。这非常有用 - 您可以获取路径属性d
的值,或将此路径元素附加到您的新SVG元素中。
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><b>D value from path:</b> ' + dPath + '</pre>';
output.innerHTML += '<xmp>HTML string of path: ' + 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>
有用的链接: