標籤:style blog http color 使用 os strong ar
今天我們來講講矩形(Rectangle)和多邊形的繪製。
矩形的繪製一共有兩個口令,分別是 ctx.fillRect(x, y, width, height) 和 ctx.strokeRect(x, y, width, height) ,參數中的 x 和 y 依舊錶示需繪製的矩形的起始點座標(相對canvas原點),width 和 height表示需繪製的矩形寬高。
而 fillRect 表示繪製一個實心矩形,strokeRect 表示繪製一個描邊矩形,我們來一個簡單的例子:
<canvas id="myCanvas" width="200" height="200" style="border:solid 1px #CCC;">您的瀏覽器不支援canvas,建議使用最新版的Chrome</canvas><script>var c = document.getElementById("myCanvas");var ctx = c.getContext("2d"); //擷取該canvas的2D繪圖環境對象ctx.fillRect(10,10,50,50); //從畫布上的(10,10)座標點為起始點,繪製一個寬高均為50px的實心矩形ctx.strokeRect(70,10,50,50); //從畫布上的(70,10)座標點為起始點,繪製一個寬高均為50px的描邊矩形</script>
效果如下:
上方我們繪製了兩個預設黑色的實心和描邊矩形,相信你也聯想到上一章我們繪製線段時,若沒有定義strokeStyle,則線段也是預設為黑色的事情。那麼我們要給這倆矩形上色,或許你也會聯想到應當使用 *Style 來處理,而這想法也是正確的。
在canvas上,給實心對象上色可以用 fillStyle 來定義,給描邊對象上色我們可以用 strokeStyle來定義,它們的賦值均為 color|gradient|pattern ,在上章我們已經細說過,這裡不再贅述。
那麼我們來給上方繪製了的實心矩形填充一個放射狀漸層(黃-藍-紅),將描邊矩形的描邊設為綠色。我們可以這樣做:
<canvas id="myCanvas" width="200" height="200" style="border:solid 1px #CCC;">您的瀏覽器不支援canvas,建議使用最新版的Chrome</canvas><script>var c = document.getElementById("myCanvas");var ctx = c.getContext("2d"); //擷取該canvas的2D繪圖環境對象var grd = ctx.createRadialGradient(35,35,0,35,35,36); //定義放射狀漸層對象,設定漸層線起始點和結束點座標,座標格式為(起始點x,起始點y,結束點x,結束點y)grd.addColorStop(0,"yellow"); //定義漸層線起點顏色grd.addColorStop(0.5,"blue"); //定義漸層線中間點的顏色grd.addColorStop(1,"red"); //定義漸層線結束點的顏色ctx.fillStyle = grd; //將放射狀漸層對象賦值給fillStylectx.fillRect(10,10,50,50); //從畫布上的(10,10)座標點為起始點,繪製一個寬高均為50px的實心矩形ctx.beginPath(); //重設畫筆,這是個好習慣ctx.strokeStyle = "green"; //定義描邊顏色為綠色ctx.strokeRect(70,10,50,50); //從畫布上的(70,10)座標點為起始點,繪製一個寬高均為50px的描邊矩形</script>
效果如下:
這裡要提到的是上一章沒有仔細介紹過的放射狀漸層方法 createRadialGradient ,其文法為
ctx.createRadialGradient( Xstart, Ystart, Radiusstart, Xend, Yend, Radiusend )
其中前三個參數表示漸層起始圓形的中心座標和半徑,後三個參數表示漸層結束圓形的中點座標和半徑。
或許你會被這裡的“半徑”迷惑,回顧我們上章學習的createLinearGradient,它的參數並沒有“半徑”的概念,如果你是一名平面設計師,你更可能覺得放射狀漸層只需要起始點和結束點座標就可以了(畢竟PS/AI中的放射狀漸層只需要這兩個點)。
但canvas在這裡加入的“半徑”參數還是有一定作用的,可以創造出比PS中放射狀漸層稍微複雜一些的效果。
⑴ 我們先來一個最簡單最好理解的例子:
var c = document.getElementById("myCanvas");var ctx = c.getContext("2d"); //擷取該canvas的2D繪圖環境對象var grd = ctx.createRadialGradient(70,70,0,70,70,100); //定義放射狀漸層對象,設定起始圓和結束圓中點重疊,且起始圓半徑為0grd.addColorStop(0,"yellow"); //定義漸層線起點顏色grd.addColorStop(0.5,"blue"); //定義漸層線中間點的顏色grd.addColorStop(1,"rgba(255,0,0,0)"); //定義漸層線結束點的顏色,其中顏色透明度為0ctx.fillStyle = grd; //將放射狀漸層對象賦值給fillStylectx.fillRect(0,0,c.width,c.height); //繪製一個跟畫布大小一樣的實心矩形
我們設定起始圓和結束圓中點相同,且起始圓半徑為0,那麼它的漸層線就是從兩圓的中點開始到結束圓的邊緣結束。我們設定漸層線結束點顏色透明度為0是為了方便查看結束圓的邊界。效果如下:
⑵ 我們在⑴的基礎上將起始圓的半徑設為20,代碼和如下:
var c = document.getElementById("myCanvas");var ctx = c.getContext("2d"); //擷取該canvas的2D繪圖環境對象var grd = ctx.createRadialGradient(70,70,20,70,70,100); //定義放射狀漸層對象,設定起始圓和結束圓中點重疊,且起始圓半徑為20grd.addColorStop(0,"yellow"); grd.addColorStop(0.5,"blue"); grd.addColorStop(1,"rgba(255,0,0,0)"); ctx.fillStyle = grd; ctx.fillRect(0,0,c.width,c.height);
⑶ 我們在⑵的基礎上挪動起始圓的中點,不要讓它跟結束圓的中點重疊,代碼和如下:
var c = document.getElementById("myCanvas");var ctx = c.getContext("2d"); //擷取該canvas的2D繪圖環境對象var grd = ctx.createRadialGradient(60,40,20,70,70,100); //起始圓不僅有半徑,而且中點跟結束圓中點不相同grd.addColorStop(0,"yellow"); grd.addColorStop(0.5,"blue"); grd.addColorStop(1,"rgba(255,0,0,0)"); ctx.fillStyle = grd; ctx.fillRect(0,0,c.width,c.height);
注意我們在定義RadialGradient時,要避免起始圓的範圍超出結束圓的範圍(起始圓應當是結束圓內部的一個真子集),否則繪製出來的效果會出現無法預知的錯誤,例如下面的代碼:
var c = document.getElementById("myCanvas");var ctx = c.getContext("2d"); //擷取該canvas的2D繪圖環境對象var grd = ctx.createRadialGradient(60,60,50,70,70,50); //起始圓的左邊超出了結束圓內部地區grd.addColorStop(0,"yellow"); grd.addColorStop(0.5,"blue"); grd.addColorStop(1,"rgba(255,0,0,0)"); ctx.fillStyle = grd; ctx.fillRect(0,0,c.width,c.height);
效果:
至此我們學習了通過 fillRect 和 strokeRect 來繪製矩形,下面再講一個Rect相關的功能——clearRect。
clearRect類似PS中的方塊橡皮擦,可以擦除畫布上任意一塊矩形地區的內容,其文法如下:
ctx.clearRect( x, y, width, height );
其中 x 和 y 表示起始點座標,width 和 height 表示這塊“橡皮擦”的寬高。舉個例子:
var c = document.getElementById("myCanvas");var ctx = c.getContext("2d"); //擷取該canvas的2D繪圖環境對象ctx.fillStyle = "red"; ctx.fillRect(0,0,c.width,c.height); ctx.beginPath();ctx.fillStyle = "blue"; ctx.fillRect(10,20,60,60); ctx.clearRect(20,20,80,50); //擦除以(20,20)座標為起點,寬高為80*50的地區
效果如下:
注意clearRect不會清除掉之前定義過的樣式、畫筆位置等繪製資訊,打個比方,有時候我們需要清空整個畫布,我們可以這樣做:
var c = document.getElementById("myCanvas");var ctx = c.getContext("2d"); //擷取該canvas的2D繪圖環境對象ctx.fillStyle = "blue"; ctx.fillRect(10,20,60,60); //下面重設畫布大小,從而清空畫布c.width = c.width; //在jQ中可以寫為 c.attr("width", c.width()); c.height = c.height; //在jQ中可以寫為 c.attr("height", c.height()); //重新繪製一個矩形ctx.fillRect(10,20,60,60);
這個方法是通過重設畫布大小,從而觸發清空畫布事件,但前面定義的 fillStyle="blue" 也被清空掉了,從而繪製了一個黑色的矩形:
如果不想清除掉之前定義的樣式,我們可以通過clearRect來實現:
var c = document.getElementById("myCanvas");var ctx = c.getContext("2d"); //擷取該canvas的2D繪圖環境對象ctx.fillStyle = "blue"; ctx.fillRect(10,20,60,60); //下面通過clearRect來擦除畫布ctx.clearRect(0,0,c.width,c.height);//重新繪製一個矩形ctx.fillRect(10,20,60,60);
執行結果如下:
最後聊一下多邊形的繪製,其實現非常簡單,先來個例子:
var c = document.getElementById("myCanvas");var ctx = c.getContext("2d"); //擷取該canvas的2D繪圖環境對象//定義樣式ctx.fillStyle = "blue"; ctx.strokeStyle = "red";ctx.lineWidth = "8";ctx.lineJoin = "round";//繪製多邊形ctx.moveTo(10,10);ctx.lineTo(100,30);ctx.lineTo(120,80);ctx.lineTo(60,60);ctx.lineTo(10,10);ctx.stroke(); //描邊ctx.fill(); //填充
可見我們這裡通過lineTo繪製了多邊形的每條邊(注意起點跟終點是同一個座標),然後通過 stroke() 來描邊、fill() 來填充,其執行效果如下:
眼尖的朋友會發現該多邊形左上方的倆條描邊沒有接在一起,這是因為我們沒有把這個多邊形路徑閉合起來,我們可以通過 ctx.closePath() 來解決這個問題:
var c = document.getElementById("myCanvas");var ctx = c.getContext("2d"); //擷取該canvas的2D繪圖環境對象//定義樣式ctx.fillStyle = "blue"; ctx.strokeStyle = "red";ctx.lineWidth = "8";ctx.lineJoin = "round";//繪製多邊形ctx.moveTo(10,10);ctx.lineTo(100,30);ctx.lineTo(120,80);ctx.lineTo(60,60);ctx.lineTo(10,10);ctx.closePath(); //閉合多邊形路徑ctx.stroke(); //描邊ctx.fill(); //填充
效果如下: