Canvas教程(5)——繪制矩形

使用closePath()閉合圖形

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

<!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?!趕快換一個(gè)吧??!
    </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)了,最后一筆閉合的時(shí)候有問題,導(dǎo)致左上角有一個(gè)缺口。這種情況是設(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?!趕快換一個(gè)吧??!
    </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()閉合圖形

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

給矩形上色

這里我們要介紹一個(gè)和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?!趕快換一個(gè)吧??!
    </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é)果:

給矩形上色

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

封裝繪制方法

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

JavaScript函數(shù)

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

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

函數(shù)的作用

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

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

sum=7+8 ;
alert(sum); 

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

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

使用函數(shù)完成:

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

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

定義函數(shù)

如何定義一個(gè)函數(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ù)可以多個(gè),根據(jù)需要增減參數(shù)個(gè)數(shù)。參數(shù)之間用(逗號,)隔開。

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

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

x和y則是函數(shù)的兩個(gè)參數(shù),調(diào)用函數(shù)的時(shí)候,我們可通過這兩個(gè)參數(shù)把兩個(gè)實(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?!趕快換一個(gè)吧!!
    </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)幫我們封裝好了一個(gè)繪制矩形的方法——rect()。這個(gè)方法接收4個(gè)參數(shù)x, y, width, height,實(shí)際調(diào)用時(shí)也就是

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é)開頭那個(gè)魔性的圖像嗎?


度娘魔性圖

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

<!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?!趕快換一個(gè)吧!!
    </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>

演示 5-5

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

魔性正方形

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

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


如果您喜歡本書,請使用支付寶掃描下面的二維碼捐助作者。

二維碼

謝謝您的支持!也歡迎您訂閱本書。

如果書中有疏漏或錯誤之處,敬請您指出,期待您的pull request。如果有任何疑問也可以發(fā)送issue。

本人郵箱:airing@ursb.me

本人博客:http://ursb.me

本書地址:http://airingursb.gitbooks.io/canvas

本書github:http://github.com/airingursb/canvas

Canvas--Draw on the Web
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一:canvas簡介 1.1什么是canvas? ①:canvas是HTML5提供的一種新標(biāo)簽 ②:HTML5 ...
    GreenHand1閱讀 4,882評論 2 32
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,234評論 25 708
  • Core Graphics Framework是一套基于C的API框架,使用了Quartz作為繪圖引擎。它提供了低...
    ShanJiJi閱讀 1,725評論 0 20
  • 選擇了開始,就別輕易放棄,因?yàn)榉艞壍拇鷥r(jià)更高。一旦你下次再開始,就意味著你之前的努力是做無用功。 我記得這句話我?guī)?..
    讀書少的絲瓜閱讀 368評論 0 2
  • 您活的太累了。 就在前幾天,我們一塊聊天,您又在說:村里那個(gè)誰誰他看不起我!我問:您是怎么判斷出他看不起您的?您用...
    Z和風(fēng)細(xì)雨M閱讀 303評論 5 10

友情鏈接更多精彩內(nèi)容