[英]Merging two shapes inside html canvas
我正在使用 HTML Canvas 元素编写一个手绘 webapp。 到目前为止,我可以在屏幕上绘制如下图所示的形状。
我已将形状的所有点存储到一个 JS 数组中。 例如:
[
[
[118, 171],
[118, 170],
[118, 167],
...
],
[
[236, 131],
[236, 133],
[236, 135],
...
]
]
我现在正在寻找一种合并某些形状的方法,想象一下我想合并下图中的两个形状,这就是它的样子。
我想我必须重绘到 canvas 但过滤掉另一个形状内的所有点。
我的第一个想法是找到一个解决方案来检查一个特定的点是否包含在另一个形状中,如果是这样,跳过它。 但是,这可能行不通,因为moveTo
/ lineTo
/ stroke
会在形状之前的最后一个独立点和形状之后的第一个独立点之间创建一条线。
我查找了可能会有所帮助的合成操作,但还没有找到实现它的方法。
我怎么能接近这个功能?
输入
Output
以下代码不是完整的解决方案。 它使用 Path2D 对象(仍然被 MDN 标记为“实验性技术”)和 isPointInPath() canvas function。
// Canvas boilerplate const canvas = document.querySelector('#mycanvas'); const ctx = canvas.getContext('2d'); // Create our shapes const shape1 = [[100, 100], [70, 200], [150, 250], [300, 250], [300, 100], [150, 50]]; const shape2 = [[60, 60], [60, 160], [110, 210], [260, 210], [260, 60], [110, 10]]; // Create Path2D objects from our shapes let p1 = new Path2D(); p1.moveTo(...shape1[0]); for (let i = 1; i < shape1.length; i++) { p1.lineTo(...shape1[i]); } p1.closePath(); let p2 = new Path2D(); p2.moveTo(...shape2[0]); for (let i = 1; i < shape2.length; i++) { p2.lineTo(...shape2[i]); } p2.closePath(); // Draw the shapes onb the canvas ctx.fillStyle = 'white'; ctx.lineWidth = 4; ctx.strokeStyle = 'green'; ctx.stroke(p1); ctx.strokeStyle = 'blue'; ctx.stroke(p2); // Just for this demo, fill the shapes to make them look joined together ctx.fill(p2); ctx.fill(p1); // Discover whether coordinate points are inside/outside the other shape let inside = [], outside = []; for (let i = 0; i < shape2.length; i++) { if (ctx.isPointInPath(p1, ...shape2[i])) inside.push(shape2[i]); else outside.push(shape2[i]); } for (let i = 0; i < shape1.length; i++) { if (ctx.isPointInPath(p2, ...shape1[i])) inside.push(shape1[i]); else outside.push(shape1[i]); } // Display coordinates inside ctx.fillStyle = 'red'; for (let i = 0; i < inside.length; i++) { ctx.beginPath(); ctx.moveTo(...inside[i]); ctx.arc(...inside[i], 5, 0, 2 * Math.PI); ctx.fill(); } //... and outside ctx.fillStyle = 'black'; for (let i = 0; i < outside.length; i++) { ctx.beginPath(); ctx.moveTo(...outside[i]); ctx.arc(...outside[i], 5, 0, 2 * Math.PI); ctx.fill(); }
<canvas id="mycanvas"></canvas>
要计算第三个形状,它结合了概述合并形状的路径的坐标,您需要计算出每个形状中的哪些线相交,以及在哪里相交,然后以正确的顺序将这些新坐标与现有的外部坐标相结合。 祝你好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.