鍍金池/ 教程/ HTML/ Ch5 繪制矩形
Ch22 最后的API
Ch14 旋轉(zhuǎn)變換
Ch19 全局陰影與圖像合成
Ch12 三次貝塞爾曲線
Ch4 多線條組成圖形
Ch7 填充顏色
Ch6 線條的屬性
Ch20 裁剪和繪制圖像
CANVAS——Draw on the Web
Ch18 文本對齊與度量
Ch8 填充樣式
Ch15 縮放變換
Ch9 繪制標(biāo)準(zhǔn)圓弧
Ch2 開始前的準(zhǔn)備
Ch16 矩陣變換
Ch3 從線段開始
Ch10 使用切點(diǎn)繪制圓弧
Ch21 非零環(huán)繞原則
Ch11 二次貝塞爾曲線
Ch5 繪制矩形
Ch17 文本顯示與渲染
Ch1 HTML5簡介
Ch13 平移變換

Ch5 繪制矩形

使用closePath()閉合圖形

首先我們用上節(jié)課的方法繪制一個矩形。

<!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

運(yùn)行結(jié)果:

繪制矩形

乍一看沒啥問題,但是視力好的童鞋已經(jīng)發(fā)現(xiàn)了,最后一筆閉合的時候有問題,導(dǎo)致左上角有一個缺口。這種情況是設(shè)置了lineWidth導(dǎo)致的。如果默認(rèn)1筆觸的話,是沒有問題的。但是筆觸越大,線條越寬,這種缺口就越明顯。那么這種情況該怎么避免呢?

標(biāo)題已經(jīng)劇透了,使用clothPath()閉合圖形。

<!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

運(yùn)行結(jié)果:

使用closePath()閉合圖形

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

給矩形上色

這里我們要介紹一個和stroke()同等重要的方法fill()。和當(dāng)初描邊一樣,我們在填色之前,也要先用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

運(yùn)行結(jié)果:

給矩形上色

這里需要注意的是一個良好的編碼規(guī)范。因?yàn)橹罢f過了Canvas是基于狀態(tài)的繪制,只有調(diào)用了stroke()fill()才確定繪制。所以我們要把這兩行代碼放在最后,其余的狀態(tài)設(shè)置的代碼放在它們之前,將狀態(tài)設(shè)置確定繪制的代碼分隔開。增強(qiáng)代碼的可讀性。

封裝繪制方法

大家一定發(fā)現(xiàn)了,繪制矩形其實(shí)都是這樣的四筆,我們每次用這種笨方法畫矩形都要畫這四筆有多麻煩,如果我們要花10個矩形?100個?1000個?都這樣寫,代碼會臃腫,復(fù)用性很低。這里,我們可以使用JavaScript封裝這些方法。我們知道,一個矩形可以由它的左上角坐標(biāo)和其長寬唯一確定。

JavaScript函數(shù)

這里我們介紹一下JavaScript函數(shù)。如果有基礎(chǔ)的同學(xué)可以跳過這一大段,直接看后面的。

JavaScript 和 ActionScript 語言的函數(shù)聲明調(diào)用一樣,都是編程語言中最簡單的。

函數(shù)的作用

函數(shù)的作用,可以寫一次代碼,然后反復(fù)地重用這個代碼。如:我們要完成多組數(shù)和的功能。

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

sum=7+8 ;
alert(sum); 

....  //不停重復(fù)兩行代碼

如果要實(shí)現(xiàn)8組數(shù)的和,就需要16行代碼,實(shí)現(xiàn)的越多,代碼行也就越多。所以我們可以把完成特定功能的代碼塊放到一個函數(shù)里,直接調(diào)用這個函數(shù),就省去重復(fù)輸入大量代碼的麻煩。

使用函數(shù)完成:

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

add2(3,2);
add2(7,8);
....  //只需調(diào)用函數(shù)就可以

定義函數(shù)

如何定義一個函數(shù)呢?看看下面的格式:

function  函數(shù)名( )
{
     函數(shù)體;
}

function定義函數(shù)的關(guān)鍵字,“函數(shù)名”你為函數(shù)取的名字,“函數(shù)體”替換為完成特定功能的代碼。

函數(shù)調(diào)用

函數(shù)定義好后,是不能自動執(zhí)行的,需要調(diào)用它,直接在需要的位置寫函數(shù)名。一般有兩種方式:

  • 第一種情況:在<script>標(biāo)簽內(nèi)調(diào)用。
<script>
function tcon()
{
    alert("恭喜你學(xué)會函數(shù)調(diào)用了!");
}
tcon(); //調(diào)用函數(shù),直接寫函數(shù)名。
</script>
  • 第二種情況:在HTML文件中調(diào)用,如通過點(diǎn)擊按鈕后調(diào)用定義好的函數(shù)。

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

有參數(shù)的函數(shù)

格式如下:

function 函數(shù)名(參數(shù)1,參數(shù)2)
{
     函數(shù)代碼
}

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

按照這個格式,函數(shù)實(shí)現(xiàn)任意兩個數(shù)的和應(yīng)該寫成:

function add2(x,y)
{
   sum = x + y;
   document.write(sum);
}

x和y則是函數(shù)的兩個參數(shù),調(diào)用函數(shù)的時候,我們可通過這兩個參數(shù)把兩個實(shí)際的加數(shù)傳遞給函數(shù)了。

例如,add2(3,4)會求3+4的和,add2(60,20)則會求出60和20的和。

返回值函數(shù)

function add2(x,y)
{
   sum = x + y;
   return sum; //返回函數(shù)值,return后面的值叫做返回值。
}

這里的return和其他語言中的一樣,但是在JS或者AS等弱類型語言中,返回值類型是不需要寫到函數(shù)聲明里的。


至此,我們把JavaScript函數(shù)也順便系統(tǒng)的說了一下。下面回到正題~

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

<!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

運(yùn)行結(jié)果:

封裝繪制矩形方法

使用rect()方法繪制矩形

猶豫繪制矩形是常用的方法,所以在Canvas API中已經(jīng)幫我們封裝好了一個繪制矩形的方法——rect()。這個方法接收4個參數(shù)x, y, width, height,實(shí)際調(diào)用時也就是

context.rect(x,y,width,height);

基于此,我們幫剛才封裝的方法優(yōu)化一下。

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();
}

調(diào)用封裝方法,繪制魔性圖像

還記得我們第三節(jié)開頭那個魔性的圖像嗎? 度娘魔性圖

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

<!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

運(yùn)行結(jié)果:

魔性正方形

是不是很有魔性?是不是非常的酷?這段代碼就不花篇幅解釋了,大家自己課下琢磨琢磨,也可以嘗試著用已經(jīng)學(xué)過的知識去繪制一個酷酷的圖像。這節(jié)課內(nèi)容有點(diǎn)多,其實(shí)也只是介紹了四個屬性和方法——closePath()fillStyle、fill()rect(),還有一個擴(kuò)展的JavaScript函數(shù)講解。

好了,多花點(diǎn)時間消化消化。然后我們帶著我們完成的藝術(shù)品,繼續(xù)前進(jìn)~

上一篇:Ch7 填充顏色下一篇:Ch22 最后的API