HTML5 canvas 元素詳細(xì)教程六:組合。
之前的例子里面,我們總是將一個(gè)圖形畫(huà)在另一個(gè)之上,大多數(shù)情況下,這樣是不夠的。比如說(shuō),它這樣受制于圖形的繪制順序。不過(guò),我們可以利用 globalCompositeOperation
屬性來(lái)改變這些做法。
globalCompositeOperation
我們不僅可以在已有圖形后面再畫(huà)新圖形,還可以用來(lái)遮蓋,清除(比 clearRect
方法強(qiáng)勁得多)某些區(qū)域。
globalCompositeOperation = type
type
是下面 12 種字符串值之一:
注意:下面所有例子中,藍(lán)色方塊是先繪制的,即“已有的 canvas 內(nèi)容”,紅色圓形是后面繪制,即“新圖形”。
source-over (default) 這是默認(rèn)設(shè)置,新圖形會(huì)覆蓋在原有內(nèi)容之上。 |
|
destination-over 會(huì)在原有內(nèi)容之下繪制新圖形。 |
|
source-in 新圖形會(huì)僅僅出現(xiàn)與原有內(nèi)容重疊的部分。其它區(qū)域都變成透明的。 |
|
destination-in 原有內(nèi)容中與新圖形重疊的部分會(huì)被保留,其它區(qū)域都變成透明的。 |
|
source-out 結(jié)果是只有新圖形中與原有內(nèi)容不重疊的部分會(huì)被繪制出來(lái)。 |
|
destination-out 原有內(nèi)容中與新圖形不重疊的部分會(huì)被保留。 |
|
source-atop 新圖形中與原有內(nèi)容重疊的部分會(huì)被繪制,并覆蓋于原有內(nèi)容之上。 |
|
destination-atop 原有內(nèi)容中與新內(nèi)容重疊的部分會(huì)被保留,并會(huì)在原有內(nèi)容之下繪制新圖形 |
|
lighter 兩圖形中重疊部分作加色處理。 |
|
darker 兩圖形中重疊的部分作減色處理。 |
|
xor 重疊的部分會(huì)變成透明。 |
|
copy 只有新圖形會(huì)被保留,其它都被清除掉。 |
|
注意:copy
和 darker
屬性值在 Gecko 1.8 型的瀏覽器(Firefox 1.5 betas,等等)上暫時(shí)還無(wú)效。
裁切路徑 Clipping paths
裁切路徑和普通的 canvas 圖形差不多,不同的是它的作用是遮罩,用來(lái)隱藏沒(méi)有遮罩的部分。如右圖所示。紅邊五角星就是裁切路徑,所有在路徑以外的部分都不會(huì)在 canvas 上繪制出來(lái)。
如果和上面介紹的 globalCompositeOperation
屬性作一比較,它可以實(shí)現(xiàn)與source-in
和 source-atop
差不多的效果。最重要的區(qū)別是裁切路徑不會(huì)在 canvas 上繪制東西,而且它永遠(yuǎn)不受新圖形的影響。這些特性使得它在特定區(qū)域里繪制圖形時(shí)相當(dāng)好用。
在 繪制圖形 一章中,我只介紹了 stroke
和 fill
方法,這里介紹第三個(gè)方法clip
。
clip()
我們用 clip
方法來(lái)創(chuàng)建一個(gè)新的裁切路徑。默認(rèn)情況下,canvas 有一個(gè)與它自身一樣大的裁切路徑(也就是沒(méi)有裁切效果)。
clip
的例子
這個(gè)例子,我會(huì)用一個(gè)圓形的裁切路徑來(lái)限制隨機(jī)星星的繪制區(qū)域。
首先,我畫(huà)了一個(gè)與 canvas 一樣大小的黑色方形作為背景,然后移動(dòng)原點(diǎn)至中心點(diǎn)。然后用 clip
方法創(chuàng)建一個(gè)弧形的裁切路徑。裁切路徑也屬于 canvas 狀態(tài)的一部分,可以被保存起來(lái)。如果我們?cè)趧?chuàng)建新裁切路徑時(shí)想保留原來(lái)的裁切路徑,我們需要做的就是保存一下 canvas 的狀態(tài)。
裁切路徑創(chuàng)建之后所有出現(xiàn)在它里面的東西才會(huì)畫(huà)出來(lái)。在畫(huà)線性漸變時(shí)這個(gè)就更加明顯了。然后在隨機(jī)位置繪制 50 大小不一(經(jīng)過(guò)縮放)的顆,當(dāng)然也只有在裁切路徑里面的星星才會(huì)繪制出來(lái)。
function draw() { var ctx = document.getElementById('canvas').getContext('2d'); ctx.fillRect(0,0,150,150); ctx.translate(75,75); // Create a circular clipping path ctx.beginPath(); ctx.arc(0,0,60,0,Math.PI*2,true); ctx.clip(); // draw background var lingrad = ctx.createLinearGradient(0,-75,0,75); lingrad.addColorStop(0, '#232256'); lingrad.addColorStop(1, '#143778'); ctx.fillStyle = lingrad; ctx.fillRect(-75,-75,150,150); // draw stars for (var j=1;j<50;j++){ ctx.save(); ctx.fillStyle = '#fff'; ctx.translate(75-Math.floor(Math.random()*150), 75-Math.floor(Math.random()*150)); drawStar(ctx,Math.floor(Math.random()*4)+2); ctx.restore(); } } function drawStar(ctx,r){ ctx.save(); ctx.beginPath() ctx.moveTo(r,0); for (var i=0;i<9;i++){ ctx.rotate(Math.PI/5); if(i%2 == 0) { ctx.lineTo((r/0.525731)*0.200811,0); } else { ctx.lineTo(r,0); } } ctx.closePath(); ctx.fill(); ctx.restore(); }
只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。 | ||
![]() |
||
網(wǎng)站導(dǎo)航:
博客園
IT新聞
Chat2DB
C++博客
博問(wèn)
管理
|
||