上篇文章我們了解了canvas的定義、獲取和基礎的繪圖操作,其中的繪圖功能我們講解了線段繪制、上色、描邊等方面知識點。
今天我們來講講矩形(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>
效果如下:
你也可以使用 Rect( x, y, width, height ) 的方法創建矩形路徑,之后再通過 .stroke() 或 .fill() 方法來給矩形上色:
var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); //獲取該canvas的2D繪圖環境對象 ctx.rect(20,20,150,100); //創建矩形路徑 ctx.stroke(); //描邊 ctx.beginPath(); //重置畫筆,避免污染 ctx.rect(50,90,50,50); //創建矩形路徑 ctx.fill(); //填充
效果如下:
上方我們繪制了兩個默認黑色的實心和描邊矩形,相信你也聯想到上一章我們繪制線段時,若沒有定義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; //將放射狀漸變對象賦值給fillStyle ctx.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); //定義放射狀漸變對象,設定起始圓和結束圓中點重疊,且起始圓半徑為0 grd.addColorStop(0,"yellow"); //定義漸變線起點顏色 grd.addColorStop(0.5,"blue"); //定義漸變線中間點的顏色 grd.addColorStop(1,"rgba(255,0,0,0)"); //定義漸變線結束點的顏色,其中顏色透明度為0 ctx.fillStyle = grd; //將放射狀漸變對象賦值給fillStyle ctx.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); //定義放射狀漸變對象,設定起始圓和結束圓中點重疊,且起始圓半徑為20 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);
⑶ 我們在⑵的基礎上挪動起始圓的中點,不要讓它跟結束圓的中點重疊,代碼和效果圖如下:
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);
效果:
不過如果你掌握了RadialGradient上色原理,倒是可以隨意定位起始圓和結束圓的方位和大小。我從TimeLangoliers的博客(點擊查看出處)看到這張原理圖:
他還依照此原理圖寫了一個例子:

var canvas = document.getElementById(id); if (canvas == null) return false; var context = canvas.getContext('2d'); var g1 = context.createRadialGradient(100, 150, 10, 300, 150, 50); g1.addColorStop(0.1, 'rgb(255,0,0)'); g1.addColorStop(0.5, 'rgb(0,255,0)'); g1.addColorStop(1, 'rgb(0,0,255)'); context.fillStyle = g1; context.fillRect(0, 0, 400, 300);
至此我們學習了通過 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(); //填充
效果如下:
本章內容先到這里,下章我們一起學習下圓形和弧線的繪制。共勉~
文章列表