簡體   English   中英

在 html canvas 內部合並兩個形狀

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM