2015-12-06 54 views
1

我在shipVertexes陣列中繪製了4點的船。 在船內,我繪製的圖形與stunVertexes相同。填寫內部多邊形的外部區域

撫摸上下文產生附加圖像。你可以看到大船裏面有一艘小船。 (紅船)

我想填寫內船的外船&之間的空間,在中間留下一個空的(黑色)空間。

當我運行context.fill()時,整個空間被填滿(見黃色船)。

我該如何填寫室內空間的外部?

enter image description here

+0

難道這個問題解決你的問題? http://quickoverflow.com/questions/18838202/fill-polygon-on-canvas – David

+0

@quantumpotato檢查我的答案,它澄清了形狀填充的某些方面。 – AndreaBogazzi

回答

0

使用合成從更大的形態「擦除」的體形較小。

enter image description here

特別地,destination-out合成將 「擦除」 使用新的附圖。

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 

 
ctx.fillStyle='red'; 
 

 
ctx.beginPath(); 
 
ctx.moveTo(50,0); 
 
ctx.lineTo(100,25); 
 
ctx.lineTo(50,150); 
 
ctx.lineTo(0,25); 
 
ctx.closePath(); 
 
ctx.fill(); 
 

 
ctx.beginPath(); 
 
ctx.moveTo(50,10); 
 
ctx.lineTo(80,25); 
 
ctx.lineTo(50,100); 
 
ctx.lineTo(20,25); 
 
ctx.closePath(); 
 
// use compositing to "erase" the smaller shape from the bigger shape 
 
ctx.globalCompositeOperation='destination-out'; 
 
ctx.fill(); 
 
ctx.globalCompositeOperation='source-over';
body{ background-color: black; } 
 
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>

2

有一種更快的方式做到這一點比使用2充滿動作和全球其他合成。

另請注意,使用合成進行擦除將清除wathever在船的洞中。如果在背景中有一些裝飾會丟失。在這種情況下,它看起來是正確的,因爲你有一個空的背景顯示正文標籤的顏色。

填充操作有兩種方法可以理解形狀內部和外部是什麼。最常用的是非零的規則:

「非零」纏繞

這纏繞規則是最常用的也是,是由畫布2D支持的唯一的規則。

要確定一個點是否落入曲線內部,可以繪製一條穿過該點的虛線。接下來,您將計算該線在到達該點之前跨越曲線的次數。對於每一個順時針旋轉,你減去1併爲每逆時針旋轉你加1

non zero rule

申請非零windind你的船,我改變了內部船的圖紙爲了逆時針,並自動生成孔。

如果更改訂單太多複雜的,你可以檢查你的瀏覽器支持偶奇規則:

「偶奇」纏繞

要確定某個點落在路徑內,你再次通過這一點畫一條線。這一次,您只需添加穿過路徑的次數即可。如果總數是偶數,那麼這個點就在外面;如果它很奇怪,那就是內在。路徑的繞組被忽略。例如:

enter image description here

這條規則我只是複製你的原代碼,並填寫我指定當「EVENODD」;

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 

 
ctx.fillStyle='red'; 
 
//ship copy 1 
 
ctx.beginPath(); 
 
ctx.moveTo(50,0); 
 
ctx.lineTo(100,25); 
 
ctx.lineTo(50,150); 
 
ctx.lineTo(0,25); 
 
ctx.moveTo(50,10); 
 
ctx.lineTo(20,25); 
 
ctx.lineTo(50,100); 
 
ctx.lineTo(80,25); 
 
ctx.closePath(); 
 
ctx.fill(); 
 

 
//ship copy 2 
 
ctx.beginPath(); 
 
ctx.translate(180, 0); 
 
ctx.moveTo(50,0); 
 
ctx.lineTo(100,25); 
 
ctx.lineTo(50,150); 
 
ctx.lineTo(0,25); 
 
ctx.moveTo(50,10); 
 
ctx.lineTo(80,25); 
 
ctx.lineTo(50,100); 
 
ctx.lineTo(20,25); 
 
ctx.closePath(); 
 
ctx.fill('evenodd');
body{ background-color: black; } 
 
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>

1

最簡單的是填補所有的船爲紅色,則補之內船在黑:

var canvas = document.getElementById("canvas"); 
 
var ctx = canvas.getContext("2d"); 
 

 
ctx.beginPath(); 
 
ctx.moveTo(50, 0); 
 
ctx.lineTo(100, 25); 
 
ctx.lineTo(50, 150); 
 
ctx.lineTo(0, 25); 
 
ctx.fillStyle = 'red'; 
 
ctx.fill(); 
 

 
ctx.beginPath(); 
 
ctx.moveTo(50, 10); 
 
ctx.lineTo(20, 25); 
 
ctx.lineTo(50, 100); 
 
ctx.lineTo(80, 25); 
 
ctx.closePath(); 
 
ctx.fillStyle = 'black'; 
 
ctx.fill();
body { 
 
    background-color: black; 
 
} 
 
#canvas { 
 
    border: 1px solid red; 
 
}
<canvas id="canvas" width=300 height=300></canvas>