《JS原理、方法與實踐》- canvas作圖(一)

canvas簡介

canvas標籤是HTML5標準最受歡迎的一個標籤,它的作用就相當於一塊畫布,可以通過JS腳本在canvas上面進行繪畫,而且還可以對畫面的內容進行修改,通過不斷修改可以實現動畫的效果,再跟事件結合後就可以製作遊戲了!

canvas標籤及其所對應的JS對象HTMLCanvasElement本身非常簡單,它們主要包含width、height兩個屬性和一個getContext方法。雖然HTML5中新增了setContext等方法,但是各大瀏覽器支持得並不好。

canvas本身並沒有太多得操作,它主要是通過getContext方法獲取的環境對象進行操作。canvas和它所包含的context對象的關係就好像canvas是一塊畫布,而context是各種筆,拿到筆,然後纔可以繪圖。

canvas的用法

首先獲取canvas對象,然後使用這個對象獲取相應的環境,最後使用獲取的環境繪圖。
代碼示例:

<body>
    <canvas id="c2d" width="300" height="300">瀏覽器不支持canvas</canvas>
    <canvas id="c3d" width="150" height="150">瀏覽器不支持canvas</canvas>
    <script>
        // 獲取canvas對象
        const canvas2d = document.querySelector('#c2d');
        // 使用這個對象獲取相應的環境
        const ctx2d = canvas2d.getContext('2d');'

        // 繪製圖形...

        const canvas3d = document.querySelector('#c3d');
        const ctx3d = canvas3d.getContext('webgl');
    </script>
</body>

從示例中,我們可以看出利用getContext()方法獲取繪圖環境,目前只支持2d('2d')和3d('webgl')環境。

繪製矩形

繪製矩形是canvas中最簡單的功能,跟繪製矩形相關的方法一共包括如下三個:

  • strokeRect(x,y,width,height):繪製矩形邊框
  • fillRect(x,y,width,height):繪製矩形並填充
  • clearRect(x,y,width,height): 清除矩形區域內容,實際上是使用底色填充矩形區域。
    這三個方法的參數中,x,y表示矩形左上角的座標,width和height表示矩形的寬和高,座標原點默認爲canvas的左上角,canvas中矩形的結構如下:



    代碼示例:

    <canvas id="c2d" width="300" height="300">瀏覽器不支持canvas</canvas>
    <script>
        
        const canvas2d = document.querySelector('#c2d');
        const ctx2d = canvas2d.getContext('2d');
        // 繪製矩形
        ctx2d.fillRect(30,50,100,50);
        ctx2d.strokeRect(100,30,100,50);
        ctx2d.clearRect(101,51,28,28);
    </script>

繪製路徑

使用路徑一共可以分爲4步:創建路徑、繪製路徑、關閉路徑和操作路徑,其中繪製路徑最複雜也是最重要的內容。先介紹其他三種操作,最後詳細講解繪製路徑。

創建/關閉路徑

創建路徑

路徑的創建一共有兩種方法,一種是調用CanvasRenderingContext2D的beginPath方法,另一種是新建Path2D對象。
調用CanvasRenderingContext2D的beginPath方法後就可以直接使用CanvasRenderingContext2D來繪製路徑,而使用Path2D新建時會返回新建的路徑,然後在新建出來的路徑上進行操作,例如下面的例子:

    <canvas id="c2d">瀏覽器不支持canvas</canvas>
    <script>
        const c2d = document.querySelector('#c2d');
        const ctx2d = c2d.getContext('2d');

        // 使用beginPath方法創建
        ctx2d.beginPath();
        // 這裏可以使用ctx2d繪製路徑
        // ......

        // 使用Path2D新建路徑
        const newPath = new Path2D();
        // 這裏實際newPath來繪製路徑
        //......
    </script>
關閉路徑

關閉路徑使用的是closePath方法,其主要作用是將路徑閉合起來,也就是從畫筆的終點到路徑的起點繪製一條直線,如果路徑已經閉合,那麼也可以不調用該方法。

操作路徑

對路徑的操作只有兩種:填充和描邊,它們所對應的方法分別是stroke和fill。如果是使beginPath創建的路徑,那麼直接調用就可以了,如果是新建的Path2D路徑,那麼需要將創建出來的路徑傳入參數中,例如下面的例子:

<canvas id="c2d">瀏覽器不支持canvas</canvas>
   <script>
       const c2d = document.querySelector('#c2d');
       const ctx2d = c2d.getContext('2d');

       // 使用beginPath方法創建
       ctx2d.beginPath();
       // 這裏可以使用ctx2d繪製路徑
       // ......
       ctx2d.closePath();
       ctx2d.fill();


       // 使用Path2D新建路徑
       const newPath = new Path2D();
       // 這裏實際newPath來繪製路徑
       //......
       newPath.closePath();
       ctx2d.stroke(newPath);
   </script>

繪製路徑

所有平面上的圖形都是由直線和曲線組成的(點其實是半徑很小的實心圓),因此路徑的繪製主要分爲直線和曲線兩種類型。但是,CanvasRenderingContext2D繪製路徑時除了這兩種類型外還有一個輔助操作的方法。

輔助操作

輔助方法:moveTo(x,y),兩個參數表示移動到的目標點的座標值

繪製直線

方法:lineTo(x,y),它可以從畫筆當前點到參數中傳入的座標點畫一條直線,一般會與moveTo方法配合使用。

樣式的設置

屬性:lineWidth:指定線條的寬度
屬性:lineDashOffset: 指定虛線的偏移量
方法:setLineDash():設置虛線的樣式,參數爲一個數組,數組的元素用來表示實線與空白所佔用的寬度,虛線會按數組中的值進行循環。
示例(畫一個正方形和兩條虛線):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <canvas id="canvas" width="500" width="500"></canvas>
    <script>
        const canvas = document.querySelector('#canvas');
        if(canvas.getContext) {
            const ctx = canvas.getContext('2d');
            ctx.beginPath();
            ctx.lineWidth = 10;
            ctx.moveTo(10,10);
            ctx.lineTo(10,100);
            ctx.lineTo(100,100);
            ctx.lineTo(100,10);
            ctx.closePath();
            ctx.stroke();

            ctx.beginPath();
            ctx.lineWidth = 1;
            ctx.setLineDash([5,10]);
            ctx.moveTo(10,120);
            ctx.lineTo(120,120);
            ctx.closePath();
            ctx.stroke();
            
            ctx.beginPath();
            ctx.setLineDash([5,10]);
            ctx.lineDashOffset = 2;
            ctx.moveTo(10,130);
            ctx.lineTo(130,130);

            ctx.closePath();
            ctx.stroke();
        }
    </script>
</body>
</html>

繪製曲線

繪製圓弧

方法:arc(x,y,radius,startAngle,endAngle,anticlockwise)
參數說明:x,y爲圓心,radius爲半徑,startAngle和endAngle分別是起始角度和結束角度,anticlockwise表示是否逆時針繪製,默認爲順時針。
方法:arcTo(x1,y1,x2,y2,radius)
參數說明:通過兩條切線和半徑來指定一段圓弧,畫筆當前點和(x1,y1), (x1,y1)和(x2,y2)構成兩條切線,參數radius爲半徑。兩條切線和一個半徑可以將一個圓分成兩段圓弧,acrTo方法繪製的是較短的那段。如果畫筆的起始點不是圓弧的切點,那麼acrTo方法還會將起點和切點使用直線連接起來。
示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <canvas width="500" height="500" id='c2d'></canvas>
    <script>
        const canvas = document.getElementById('c2d');
        const ctx = canvas.getContext('2d');

        ctx.beginPath();
        ctx.arc(100,100,100,0, 2*Math.PI,false);
        ctx.closePath();
        ctx.stroke();

        ctx.beginPath();
        ctx.lineTo(250,30);
        ctx.lineWidth = 0.5;
        ctx.arcTo(200,30,250,50,20);
        ctx.closePath();
        ctx.stroke();
    </script>
</body>
</html>
繪製貝塞爾曲線

方法:quadraticCurveTo(cp1x,xp1y,x,y)
方法:bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)
這兩個方法分別用於繪製一個控制點和兩個控制點的貝塞爾曲線,畫筆當前點爲曲線的起點,(x,y)爲曲線的終點,(cpx1,cp1y)和(cp2x,cp2y)都是控制點,理解了貝塞爾曲線,這兩個方法就很容易理解:深入理解貝塞爾曲線
實例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <canvas id="c2d">瀏覽器不支持canvas</canvas>
    <script>
        const canvas = document.querySelector('#c2d');
        if(canvas.getContext) {
            const ctx = canvas.getContext('2d');
            ctx.beginPath();
            ctx.moveTo(30,50);
            ctx.quadraticCurveTo(40,80,100,50);

            ctx.moveTo(130,60);
            ctx.bezierCurveTo(160,30,200,100,260,50);
            ctx.stroke();
        }
    </script>
</body>
</html>

如果我的博客對你有幫助、如果你喜歡我的博客內容,請 “點贊” “評論” “收藏” 一鍵三連哦!
聽說 👉 點贊 👈 的人運氣不會太差,每一天都會元氣滿滿哦 嘿嘿!!! ❤️ ❤️ ❤️
大家的支持就是我堅持下去的動力。點贊後不要忘了👉 關注 👈我哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章