canvas系列教程之繪製矩形

虛竹子發表於2019-02-26

使用closePath()閉合圖形

首先我們用上節課的方法繪製一個矩形。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>繪製矩形</title>
</head>
<body>
<div id="canvas-warp">
    <canvas id="canvas" style="border: 1px solid #aaaaaa; display: block; margin: 50px auto;">
        你的瀏覽器居然不支援Canvas?!趕快換一個吧!!
    </canvas>
</div>

<script>
    window.onload = function(){
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 600;
        var context = canvas.getContext("2d");

        context.beginPath();
        context.moveTo(150,50);
        context.lineTo(650,50);
        context.lineTo(650,550);
        context.lineTo(150,550);
        context.lineTo(150,50);     //繪製最後一筆使影象閉合
        context.lineWidth = 5;
        context.strokeStyle = "black";
        context.stroke();

    }
</script>
</body>
</html>
</body>
</html>
複製程式碼

執行結果:

演示5-1
乍一看沒啥問題,但是視力好的童鞋已經發現了,最後一筆閉合的時候有問題,導致左上角有一個缺口(Chrome是沒有這個問題的)。這種情況是設定了lineWidth導致的。如果預設1筆觸的話,是沒有問題的。但是筆觸越大,線條越寬,這種缺口就越明顯。那麼這種情況該怎麼避免呢?

標題已經劇透了,使用closePath()閉合圖形。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>繪製矩形</title>
</head>
<body>
<div id="canvas-warp">
    <canvas id="canvas" style="border: 1px solid #aaaaaa; display: block; margin: 50px auto;">
        你的瀏覽器居然不支援Canvas?!趕快換一個吧!!
    </canvas>
</div>

<script>
    window.onload = function(){
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 600;
        var context = canvas.getContext("2d");

        context.beginPath();
        context.moveTo(150,50);
        context.lineTo(650,50);
        context.lineTo(650,550);
        context.lineTo(150,550);
        context.lineTo(150,50);     //最後一筆可以不畫
        context.closePath();        //使用closePath()閉合圖形

        context.lineWidth = 5;
        context.strokeStyle = "black";
        context.stroke();

    }
</script>
</body>
</html>
</body>
</html>
複製程式碼

執行結果:

演示5-2
這個例子結合上節課的講解,我們知道了繪製路徑的時候需要將規劃的路徑使用beginPath()closePath()包裹起來。當然,最後一筆可以不畫出來,直接使用closePath(),它會自動幫你閉合的。(所以如果你不想繪製閉合圖形就不可以使用closePath())

給矩形上色

這裡我們要介紹一個和stroke()同等重要的方法fill()。和當初描邊一樣,我們在填色之前,也要先用fillStyle屬性選擇要填充的顏色。 比如我們要給上面的矩形塗上黃色,可以這樣寫。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>繪製矩形</title>
</head>
<body>
<div id="canvas-warp">
    <canvas id="canvas" style="border: 1px solid #aaaaaa; display: block; margin: 50px auto;">
        你的瀏覽器居然不支援Canvas?!趕快換一個吧!!
    </canvas>
</div>

<script>
    window.onload = function(){
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 600;
        var context = canvas.getContext("2d");

        context.beginPath();
        context.moveTo(150,50);
        context.lineTo(650,50);
        context.lineTo(650,550);
        context.lineTo(150,550);
        context.lineTo(150,50);     //最後一筆可以不畫
        context.closePath();        //使用closePath()閉合圖形

        context.fillStyle = "yellow";   //選擇油漆桶的顏色
        context.lineWidth = 5;
        context.strokeStyle = "black";

        context.fill();                 //確定填充
        context.stroke();

    }
</script>
</body>
</html>
</body>
</html>
複製程式碼

執行結果:

演示5-3
這裡需要注意的是一個良好的編碼規範。因為之前說過了Canvas是基於狀態的繪製,只有呼叫了stroke()fill()才確定繪製。所以我們要把這兩行程式碼放在最後,其餘的狀態設定的程式碼放在它們之前,將狀態設定與確定繪製的程式碼分隔開。增強程式碼的可讀性。

封裝繪製方法

大家一定發現了,繪製矩形其實都是這樣的四筆,我們每次用這種笨方法畫矩形都要畫這四筆有多麻煩,如果我們要花10個矩形?100個?1000個?都這樣寫,程式碼會臃腫,複用性很低。這裡,我們可以使用JavaScript封裝這些方法。我們知道,一個矩形可以由它的左上角座標和其長寬唯一確定。

JavaScript函式

這裡我們介紹一下JavaScript函式。如果有基礎的同學可以跳過這一大段,直接看後面的。

JavaScript 和 ActionScript 語言的函式宣告呼叫一樣,都是程式語言中最簡單的。

函式的作用

函式的作用,可以寫一次程式碼,然後反覆地重用這個程式碼。如:我們要完成多組數和的功能。

var sum;   
sum = 3+2;
alert(sum);

sum=7+8 ;
alert(sum); 

....  //不停重複兩行程式碼
複製程式碼

如果要實現8組數的和,就需要16行程式碼,實現的越多,程式碼行也就越多。所以我們可以把完成特定功能的程式碼塊放到一個函式裡,直接呼叫這個函式,就省去重複輸入大量程式碼的麻煩。 使用函式完成:

function add2(a,b){
	sum = a + b;
 	alert(sum);
} //  只需寫一次就可以

add2(3,2);
add2(7,8);
....  //只需呼叫函式就可以
複製程式碼

定義函式

如何定義一個函式呢?看看下面的格式:

function 函式名( ) { 函式體; }

function定義函式的關鍵字,“函式名”你為函式取的名字,“函式體”替換為完成特定功能的程式碼。

函式呼叫

函式定義好後,是不能自動執行的,需要呼叫它,直接在需要的位置寫函式名。一般有兩種方式:

  1. 第一種情況:在<script>標籤內呼叫。
<script>
function tcon()
{
	alert("恭喜你學會函式呼叫了!");
}
tcon();	//呼叫函式,直接寫函式名。
</script>
複製程式碼
  1. 第二種情況:在HTML檔案中呼叫,如通過點選按鈕後呼叫定義好的函式。

這種情況以後用到了再說。

有引數的函式

格式如下:

function 函式名(引數1,引數2) { 函式程式碼 }

注意:引數可以多個,根據需要增減引數個數。引數之間用(逗號,)隔開。

按照這個格式,函式實現任意兩個數的和應該寫成:

function add2(x,y)
{
   sum = x + y;
   document.write(sum);
}
複製程式碼

x和y則是函式的兩個引數,呼叫函式的時候,我們可通過這兩個引數把兩個實際的加數傳遞給函式了。 例如,add2(3,4)會求3+4的和,add2(60,20)則會求出60和20的和。

返回值函式

function add2(x,y)
{
   sum = x + y;
   return sum; //返回函式值,return後面的值叫做返回值。
}
複製程式碼

這裡的return和其他語言中的一樣,但是在JS或者AS等弱型別語言中,返回值型別是不需要寫到函式宣告裡的。

至此,我們把JavaScript函式也順便系統的說了一下。下面回到正題~

我們也可以封裝一下我們的矩形,程式碼如下:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>封裝繪製矩形方法</title>
</head>
<body>
<div id="canvas-warp">
    <canvas id="canvas" style="border: 1px solid #aaaaaa; display: block; margin: 50px auto;">
        你的瀏覽器居然不支援Canvas?!趕快換一個吧!!
    </canvas>
</div>

<script>
    window.onload = function(){
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 600;
        var context = canvas.getContext("2d");

        drawRect(context, 150, 50, 50, 50, "red", 5, "blue");
        drawRect(context, 250, 50, 50, 50, "green", 5, "red");
        drawRect(context, 350, 50, 50, 50, "yellow", 5, "black");
    }

    function drawRect(cxt, x, y, width, height, fillColor, borderWidth, borderColor){
        cxt.beginPath();
        cxt.moveTo(x, y);
        cxt.lineTo(x + width, y);
        cxt.lineTo(x + width, y + height);
        cxt.lineTo(x, y + height);
        cxt.lineTo(x, y);
        cxt.closePath();

        cxt.lineWidth = borderWidth;
        cxt.strokeStyle = borderColor;
        cxt.fillStyle = fillColor;

        cxt.fill();
        cxt.stroke();
    }
</script>
</body>
</html>
</body>
</html>
複製程式碼

執行結果:

演示5-4

使用rect()方法繪製矩形

由於繪製矩形是常用的方法,所以在Canvas API中已經幫我們封裝好了一個繪製矩形的方法——rect()。這個方法接收4個引數x, y, width, height,實際呼叫時也就是 context.rect(x,y,width,height)

基於此,我們幫剛才封裝的方法優化一下。

function drawRect(cxt, x, y, width, height, fillColor, borderWidth, borderColor){
        cxt.beginPath();
        cxt.rect(x, y, width, height);
        //cxt.closePath();    可以不用closePath()

        cxt.lineWidth = borderWidth;
        cxt.strokeStyle = borderColor;
        cxt.fillStyle = fillColor;

        cxt.fill();
        cxt.stroke();
}
複製程式碼

呼叫封裝方法,繪製魔性影象

還記得我們第三節開頭那個魔性的影象嗎?

好,我們就拿它開刀,練練手,給我們剛封裝好的方法活動活動筋骨。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>繪製魔性圖形</title>
</head>
<body>
<div id="canvas-warp">
    <canvas id="canvas" style="border: 1px solid #aaaaaa; display: block; margin: 50px auto;">
        你的瀏覽器居然不支援Canvas?!趕快換一個吧!!
    </canvas>
</div>

<script>
    window.onload = function(){
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 600;
        var context = canvas.getContext("2d");

        context.beginPath();
        context.rect(0, 0, 800, 600);
        context.fillStyle = "#AA9033";

        context.fill();

        context.beginPath();
        for(var i=0; i<20; i++){
            drawWhiteRect(context, 200 + 10 * i, 100 + 10 * i, 400 - 20 * i, 400 - 20 * i);
            drawBlackRect(context, 205 + 10 * i, 105 + 10 * i, 390 - 20 * i, 390 - 20 * i);
        }

        context.beginPath();
        context.rect(395, 295, 5, 5);
        context.fillStyle = "black";
        context.lineWidth = 5;

        context.fill();
        context.stroke();
    }

    function drawBlackRect(cxt, x, y, width, height){
        cxt.beginPath();
        cxt.rect(x, y, width, height);

        cxt.lineWidth = 5;
        cxt.strokeStyle = "black";

        cxt.stroke();
    }

    function drawWhiteRect(cxt, x, y, width, height){
        cxt.beginPath();
        cxt.rect(x, y, width, height);

        cxt.lineWidth = 5;
        cxt.strokeStyle = "white";

        cxt.stroke();
    }
</script>
</body>
</html>
</body>
</html>
複製程式碼

執行結果:

演示5-5
是不是很有魔性?是不是非常的酷?這段程式碼就不花篇幅解釋了,大家自己課下琢磨琢磨,也可以嘗試著用已經學過的知識去繪製一個酷酷的影象。這節課內容有點多,其實也只是介紹了四個屬性和方法——closePath()fillStylefill()rect(),還有一個擴充套件的JavaScript函式講解。

好了,多花點時間消化消化。然後我們帶著我們完成的藝術品,繼續前進~?

相關文章