文章出處

上篇文章我們了解了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);
View Code

 至此我們學習了通過 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();    //填充

效果如下:

本章內容先到這里,下章我們一起學習下圓形和弧線的繪制。共勉~

donate


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()