html5 Canvas畫圖教程(4)—未閉合的路徑及漸變色的填充方法

字號:


    一般繪圖的方式有兩種,即填充和描邊,前面的文章已經(jīng)講了描邊的方法stroke,本文就講一下Canvas中填充圖形的方法。
    填充即fill(),很直白吧?而且和strokeStyle表示描邊樣式一樣,fillStyle即表示填充樣式。
    ctx.fillStyle = '顏色';默認的填充樣式是不透明的黑色
    提問:未閉合的路徑可以填充嗎?
    可以。Canvas會從你當前路徑的終點直接連接到起點,然后填充。如圖:
    名單
    但你可以發(fā)現(xiàn),最后一段沒有描邊。
    記得我們前一篇文章用4條線畫了一個正方形,但canvas不會這么差勁,連直接繪制矩形的函數(shù)都沒有。你可以使用fillRect()直接填充一個矩形:
    代碼如下:
    ctx.fillRect(x,y,width,height);
    這里的x,y是指矩形的左上角起點的坐標,記住。
    說到fillRect,就不得不提strokeRect,你猜對了,他的意思就是直接描邊出一個矩形。
    還有fillText與strokeText,至于作用嘛,你可能都猜到了,我這里先不講,大家先預(yù)習(xí)吧。
    Canvas填充漸變色
    在Canvas中,漸變色同樣分為兩種,即線性漸變和徑向漸變,而且創(chuàng)建他們的方法也是獨立的。我們先看如何創(chuàng)建線性漸變。
    創(chuàng)建線性漸變=createLinearGradient——看,依然很直接的單詞。他的語法如下:
    createLinearGradient(x1,y1,x2,y2)有4個參數(shù)呢!看起來好復(fù)雜,其實這個挺簡單的,因為我們前面已經(jīng)說了,平面世界里的一個點是由x坐標和y坐標確定的。所以,x1,y1就是表示線性漸變的起點坐標,x2,y2就表示終點坐標。
    這樣做的好處很明顯,如果我們想創(chuàng)建一個斜著的線性漸變,很方便。但我們先創(chuàng)建一個水平的線性漸變試試吧。
    var linear = ctx.createLinearGradient(100,100,200,100);漸變好像創(chuàng)建了,那么我們可以填充了嗎?————這個漸變是空的,沒有顏色。
    往漸變條里加顏色的方法是addColorStop(位置,顏色).但要注意了,這個addColorStop不是加在畫筆上,而是加在前面的那個保存漸變的變量上,我這里是linear.
    代碼如下:
    var linear = ctx.createLinearGradient(100,100,200,100);
    linear.addColorStop(0,'#fff');
    linear.addColorStop(0.5,'#f0f');
    linear.addColorStop(1,'#333');
    我這里用了3個addColorStop,即為漸變條加上了3個顏色。
    注意:addColorStop的位置參數(shù),永遠是介于0-1之間的數(shù)字,可以是兩位小數(shù),表示百分比。他沒法接收’3px’這樣的參數(shù)。
    這時候,我們就可以填充漸變色了,但我們必須先把定義好的漸變賦給fillStyle.
    代碼如下:
    var linear = ctx.createLinearGradient(100,100,200,100);
    linear.addColorStop(0,'#fff');
    linear.addColorStop(0.5,'#f0f');
    linear.addColorStop(1,'#333');
    ctx.fillStyle = linear; //把漸變賦給填充樣式
    ctx.fillRect(100,100,100,100);
    ctx.stroke();
    名單
    注意,fillRect與strokeRect畫出的都是獨立的路徑,如上面的代碼,在fillRect后調(diào)用描邊,并不會把剛剛畫出的矩形描邊,strokeRect同理。
    經(jīng)過測試后,發(fā)現(xiàn)了一個很蛋疼的問題,就是線性漸變的坐標是相對于整個Canvas范圍而言的。比如我這里,我的線性漸變起點就是100,100,如果我畫了一個矩形在0,0的位置,用這個漸變來填充,就會發(fā)現(xiàn)沒有填充——因為我的漸變的范圍根本就超過了矩形的范圍。
    這真是一個坑爹的設(shè)定。
    提問:漸變起點之前與漸變終點之后還會填充顏色嗎?
    會。起點之前的顏色就是起點色,終點之后的顏色一直是終點色。
    如何終止終點色,你可以在結(jié)束色之后再填一個透明的結(jié)束色。如:
    代碼如下:
    linear.addColorStop(0.99,'#333');
    linear.addColorStop(1,'rgba(51,51,51,0)');
    依照前面的計劃,我再建一個傾斜的線性漸變試試。只需要改createLinearGradient的參數(shù)即可.
    代碼如下:
    var linear = ctx.createLinearGradient(100,100,200,200);
    效果如圖:
    名單
    然后,讓我們來試試徑向漸變(圓形漸變)。與createLinearGradient類似,創(chuàng)建徑向漸變的方法是:createRadialGradient,但他們的參數(shù)可大不相同:
    createRadialGradient(x1,y1,r1,x2,y2,r2)其中的x1,y1,x2,y2依舊表示起點和終點,不過這里的起點和終點都是一個圓,而x,y則是圓心的坐標。所以,r1與r2分別是起點圓的半徑和終點圓的半徑。如圖:
    名單
    在我的印象中,貌似徑向漸變就是一個圓,圓心就是起點,圓的半徑就是終點。但canvas里面的徑向漸變竟然搞的不一樣了,起點一個圓,終點一個圓,和我的理解有差距。
    我們從最簡單的做起。首先,做一個很正規(guī)的徑向漸變,即漸變圓形的圓心就是漸變的起點。由于正規(guī)的徑向漸變,中心即圓心,所以我們應(yīng)該盡量避免發(fā)生偏斜。那么,我們把終點圓的圓心與起點圓的圓心重合吧?
    代碼如下:
    var radial = ctx.createRadialGradient(55,55,10,55,55,55); //重合的圓心坐標
    radial.addColorStop(0,'#fff');
    radial.addColorStop(0.5,'#ff0');
    radial.addColorStop(0.9,'#555');
    radial.addColorStop(1,'#f00');
    名單
    這里我設(shè)置的徑向漸變起點圓和終點圓的圓心坐標相同,而起點圓半徑為10,終點圓半徑為55.最后畫出的徑向漸變范圍是一個寬高110的圓形,說明漸變范圍以終點圓的范圍為準。
    (可以看到終點圓范圍之外還是有顏色,這個顏色就是終點色,但是,如果你企圖使用radial.addColorStop(1.5,’#0f0′);這樣來定義漸變范圍之外的顏色,你還是會收到一個錯誤).
    那么,起點圓的半徑有什么用呢?——本來正常的徑向漸變的中心(姑且稱之為“變心”…吧)只是一個點,不應(yīng)該是一個圓的。其實我們沒錯,這個起點圓就相當于一個圓點而已,只是可能比較大。
    讓我們把起點圓的半徑變得很大,接近于終點圓的半徑:
    代碼如下:
    var radial = ctx.createRadialGradient(55,55,50,55,55,55); //很接近
    其他的colorStop都不變,然后圖形就變成了這個樣子。
    名單
    也就是說,canvas中徑向漸變的起點色,是從起點圓的范圍之外繪制的,而起點圓的整個顏色都是起點色。
    我們把起點圓的半徑設(shè)為0,那徑向漸變的“變心”,就真的是一個點了。
    大部分時候我們都不需要很正規(guī)的徑向漸變,反而希望他的變心是偏移的,類似下圖:
    名單
    這個時候,canvas徑向漸變兩個圓的優(yōu)勢就出來了,只要我們起點圓與終點圓的圓心不重合,那變心也就會偏移:
    var radial = ctx.createRadialGradient(75,75,0,55,55,55);但此時的漸變范圍依然是終點圓的范圍哈。
    很多人天生就有一種搞破壞的心理,比如這里,終點圓的半徑總比起點圓大,但如果把他們反過來會怎么樣呢?
    代碼如下:
    var radial = ctx.createRadialGradient(75,75,55,55,55,0);
    經(jīng)測試,這樣不會報錯,只是原來的從內(nèi)到外的漸變反過來變成了從外到內(nèi)的漸變了。這是個好用法。
    名單
    還有個問題,如果我們把起點圓的圓心偏移了,并且起點圓的范圍超出了終點圓的范圍,
    名單
    這時會發(fā)生什么?
    名單
    這是什么情況?!
    當起點圓和終點圓只有部分重疊的時候,就會出現(xiàn)這種情況。所以,如果你需要正常的徑向漸變,請保證其中一個圓完全包住了另一個圓。
    另外,既然漸變可以賦給fillStyle,那么也可以賦給strokeStyle。效果你懂的。