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

組合與剪切

組合與剪切主要是對應多個圖形來說的,組合指的是多個圖形重疊時的組合方式,剪切是指使用路徑來指定繪圖的區域,類似於Photoshop中的蒙版的效果。

組合

圖形的組合是通過globalCompositeOperation屬性來操作的,該屬性可以取下面的值:

  • source-over: 後繪製的圖形覆蓋原圖,該值爲默認值
  • source-in: 保留後繪製圖形和原圖形重疊的部分,使用後繪製圖形的樣式,其他區域透明,也就是保留相交的部分
  • source-out: 保留後繪製圖形不和原圖形重疊的部分,其他區域透明
  • source-atop: 保留後繪製圖形和原圖形重疊的部分,使用後繪製圖形的樣式,原圖中的非重疊部分不變
  • destination-over: 後繪製圖形被原圖覆蓋,也就是重疊部分顯示原圖
  • destination-in: 保留後繪製圖形和原圖形重疊的部分,使用原圖的樣式,其他區域透明
  • destination-out: 保留原圖不和後繪製圖形重疊的部分,其他區域透明
  • destination-atop: 保留後繪製圖形和原圖形重疊的部分,使用原圖的樣式,後繪製圖形中的非重疊部分不變
  • lighter: 後繪製圖形和原圖重疊的部分進行疊加
  • copy: 顯示後繪製圖形,不顯示原圖
  • xor: 後繪製圖形和原圖重疊的部分進行異或操作
  • multiply: 將後繪製圖形和原圖的像素相乘,圖形變暗
  • screen: 將後繪製圖形和原圖的像素分別反向後相乘再反向,圖形變亮
  • overlay: 組合使用multiply和screen,使亮的部分更亮,暗的部分更暗
  • darken: 取兩個圖形中較暗的像素值,例如,#aa0011與#cc3300計算後爲#aa0000
  • ighten: 取兩個圖形中較亮的像素值,例如,#aa0011與#cc3300計算後爲#aa3311
  • color-dodge: 使用原圖像素除以後繪製圖形的反向像素值
  • color-burn: 使用原圖反向像素除以後繪製圖形的像素,然後再反向
  • hard-light: 組合使用multiply和screen,它與overlay的區別是將原圖和後繪製圖形進行交換
  • soft-light: 類似於hard-light,但比hard-light柔和
  • difference: 使用後繪製圖形的像素值減去原圖的像素值
  • exclusion: difference操作後降低對比度
  • hue: 使用後繪製圖形的色調和原圖的亮度、色度
  • saturation: 使用後繪製圖形的色度和原圖的亮度、色調
  • color: 使用後繪製圖形的色度、色調和原圖的亮度
  • luminosity:使用後繪製圖形的亮度和原圖的色度、色調

示例:

<body>
    <canvas id='c2d'>瀏覽器不支持canvas</canvas>
    <script>
        const canvas = document.getElementById('c2d');
        if (canvas.getContext) {
            let ctx = canvas.getContext('2d');

            ctx.fillStyle = 'red';
            ctx.fillRect(30,60,60,40);

            ctx.globalCompositeOperation = 'destination-over';

            ctx.fillStyle = 'blue';
            ctx.fillRect(70,40,60,40);
        }
    </script>
</body>
剪切

剪切的作用其實是指定新的繪圖區域,如果將圖像繪製到剪切區域外面就顯示不出來了,但是剪切操作不會影響剪切之前的圖形。剪切使用的是clip方法,如下:

  • clip([fillRule="nonzero"])
  • clip(path[,fillRule="nonzero"])
    fillRule:用來指定用你什麼算法來判斷一個點是否在被剪切的區域內,可取“nonzero”或“evenodd”
    當路徑是使用beginPath創建時,使用第一種方式直接調用clip,當路徑是使用Path2D創建時,需要使用第二種方式將創建的路徑作爲參數傳入。
    示例:
<body>
    <canvas id='c2d'>瀏覽器不支持canvas</canvas>
    <script>
        const canvas = document.getElementById('c2d');
        if (canvas.getContext) {
            let ctx = canvas.getContext('2d');

            ctx.fillRect(110,15,30,45);

            ctx.beginPath();
            ctx.arc(60,60,45,0,2*Math.PI);
            ctx.stroke();

            ctx.clip();
            ctx.fillRect(0,0,60,60);
        }
    </script>
</body>

首先畫一個以(110,15)爲左上頂點,寬爲30、高爲45的矩形,接着剪切了一個(60,60)爲圓形、45爲半徑的圓,然後又畫了一個以(0,0)爲左上角,寬和高都是60的矩形。這時第一個矩形可以正常顯示,但是第二個矩形只有剪切區域中的部分(也就是和剪切區域相交的部分)纔可以顯示出來。

座標檢測

座標檢測就是檢測指定的點是否在所畫的路徑中,可以用於動畫和遊戲的碰撞檢測中。座標檢測使用的是isPointInPath方法,方法如下:

  • isPointInPath(x,y[,fillRule="nonzero"])
  • isPointInPath(path,x,y[,fillRule="nonzero"])
    參數中,fillRule也用於指定算法,一般不需要修改;x和y爲要檢測點的座標;path爲使用Path2D新建出來的路徑,如果是beginPath新建的路徑,就可以直接調用。
    示例:
<body>
    <canvas id='c2d'>瀏覽器不支持canvas</canvas>
    <div></div>
    <script>
        const canvas = document.getElementById('c2d');
        if (canvas.getContext) {
            let ctx = canvas.getContext('2d');

            const newPath = new Path2D();
            newPath.rect(30,30,40,60);

            const div = document.querySelector('div');
            const spanValue =  `<span>30,40 is in Path: ${ctx.isPointInPath(newPath,30,40)}</span>`;
            const spanValue1 =  `<span>20,40 is in Path: ${ctx.isPointInPath(newPath,20,40)}</span>`;
            div.innerHTML = spanValue + '<br>' + spanValue1;
        }
    </script>
</body>

顏色和樣式是通過strokeStyle和fillStyle兩個屬性修改的,它們的默認值都是black,strokeStyle表示畫線(描邊)用的樣式,fillStyle表示填充用的樣式,它們可以被賦予三種類型的值:純色、漸變和模式。

純色

純色有以下三種賦值方法:

  • 直接賦予顏色值,包括賦予十六進制和顏色的單詞,例如#323232、red等
  • 使用rgb函數賦值,rgb函數有三個十進制(0~255)的參數,分別表示紅、綠、藍的值
  • 使用rgba函數賦值,rgba函數在rgb函數的基礎上添加了透明度(alpha),它用第四個參數表示透明度。透明度的取值範圍爲【0,1】,其中,0表示完全透明,1表示完全不透明。
    示例:
<body>
    <canvas id='c2d'>瀏覽器不支持canvas</canvas>
    <script>
        const canvas = document.getElementById('c2d');
        if (canvas.getContext) {
            let ctx = canvas.getContext('2d');

            ctx.fillStyle = "blue";
            ctx.beginPath();
            ctx.rect(0,0,20,20);
            ctx.fill();

            ctx.fillStyle = "rgb(249,27,27)";
            ctx.beginPath();
            ctx.rect(20,20,20,20);
            ctx.fill();

            ctx.fillStyle = "rgb(249,27,27, 0.5)";
            ctx.beginPath();
            ctx.rect(40,40,20,20);
            ctx.fill(); 
        }
    </script>
</body>

漸變

漸變的顏色是通過CanvasGradient對象來表示的,它可以使用下面兩個方法來創建:

  • createLinearGradient(x0,y0,x1,y1): 創建線性漸變
  • createRadialGradient(x0,y0,x1,y1,r1): 創建徑向漸變,也就是散漸變
    CanvasGradient對象包含一個addColorStop方法,用來添加漸變的顏色控制點,語法如下:
addColorStop(offset,color)

offset用於設置控制點,取值範圍【0,1】;color用於設置控制點的顏色。
示例:

<body>
    <canvas id='c2d'>瀏覽器不支持canvas</canvas>
    <script>
        const canvas = document.getElementById('c2d');
        if (canvas.getContext) {
            let ctx = canvas.getContext('2d');

            let lineGradient = ctx.createLinearGradient(20,20,100,150); 
            lineGradient.addColorStop(0, 'red');           
            lineGradient.addColorStop(0.5, 'rgba(255,255,0,0.7)');           
            lineGradient.addColorStop(1, '#ff6d00');
            ctx.fillStyle = lineGradient;

            ctx.beginPath();
            ctx.arc(50,50,30,0,2*Math.PI);
            ctx.fill();   

            let radiaGradient = ctx.createRadialGradient(130,50,10,130,50,30);
            radiaGradient.addColorStop(0,'rgba(255,204,205,0.3)');      
            radiaGradient.addColorStop(0.5,'#ffff00');      
            radiaGradient.addColorStop(1,'#ff6d00'); 
            ctx.fillStyle = radiaGradient;
            ctx.fillRect(100,20,60,60);     
        }
    </script>
</body>

模式

模式使用CanvasPattern對象來表示的,它使用createPattern方法來創建,語法如下:

 createPattern(image,repetition);

參數中,image爲CanvasImageSource類型,它可以是html中的img節點、video節點、canvas節點或者CanvasRenderingContext2D對象。repetion爲重複方式,它可以取下面4個值:

  • repeat: 水平和豎直兩個方向重複
  • repeat-x: 水平重複
  • repeat-y: 豎直重複
  • no-repeat: 不重複

模式的用法就好像使用圖片作爲畫筆繪圖,其中repetition屬性跟css中的background-repeat屬性類似。
示例:

<body>
    <canvas id='c2d'>瀏覽器不支持canvas</canvas>
    <script>
        const canvas = document.getElementById('c2d');
        if (canvas.getContext) {
            let ctx = canvas.getContext('2d');

            var img = new Image();
            img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
            img.onload = function () {
                var pattern = ctx.createPattern(img, 'repeat');
                ctx.fillStyle = pattern;
                ctx.fillRect(0, 0, 400, 400);
            };
        }
    </script>
</body>

插入文本

在繪圖的過程中經常需要插入一些文本內容,在CanvasRenderingContext2D中可以使用下面的方法來插入:

  • fillText(text,x,y[,maxWidth]):實心文本
  • strokeText(text,x,y[,maxWidth]):空心wenb
    相關屬性:
  • font: 字體
  • textAlign:排列方式,可選值[start, end, left, right, center]
  • direction: 文本方向
  • textBaseline: 文本的基線,漢字用不到,值爲top,hanging,middle,alphabetic,ideographic,bottom.

實例:

<!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.font='28px 行楷';
            ctx.fillText('愛我中華', 10, 50);

            ctx.font = '38px 宋體';
            ctx.strokeText('中國加油', 10, 100);
        }
    </script>
</body>
</html>

插入圖片

在CanvasRenderingContext2D中可以插入圖片,使用drawImage方法,有以下三種調用方式:

  • drawImage(image, x, y)
    指定圖片繪製位置的左上角
  • drawImage(image,x,y,width,height)
    指定繪製後的寬和高,這個方法可能會產生變形
  • drawImage(image,sx,sy,sWidth,sHeight,dx,dy,dWidth,dHeight)
    可以截取原圖的一部分繪製到當前canvas中,並且可以進行縮放,它的後8個參數中的前4個表示在原圖中要截取得位置,sx,sy爲截取的左上角的位置,sWidth和sHeight爲截取的寬度和高度,後4個參數表示在當前canvas中繪製的位置,dx,dy爲繪製的左上角,dWidth和dHeight爲繪製的寬度和高度。

參數中,image爲CanvasImageSource類型,可以是html中的img節點、video節點、canvas節點或者Canvas'RenderingContext2D對象。

實例:

<!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" width="800" height="800">瀏覽器不支持canvas</canvas>
    <img id="pic" src="./img/Pic2.png" hidden="true">
    <script>
        window.onload = function () {
            const canvas = document.querySelector('#c2d');
            if (canvas.getContext) {
                const ctx = canvas.getContext('2d');
                const pic = document.getElementById('pic');

                ctx.drawImage(pic, 0, 0, 100, 100);
                ctx.drawImage(pic, 50, 50, 100, 100);
                ctx.drawImage(pic, 100, 100, 100, 100);
            }
        }
    </script>
</body>

</html>

環境的保存和恢復

在繪圖的過程中經常需要對環境進行設置,例如填充樣式、描邊,在操作完之後,往往需要恢復到原來的環境,CanvasRenderingContext2D中可以使用save和restore方法快速操作。
環境的保存和恢復還可以進行多層嵌套。多次使用save方法可以創建多個保存點,每次調用restore方法都會按save相反的順序獲取所保存的環境。
實例:

<!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" width="600" height="600">瀏覽器不支持canvas</canvas>
    <script>
        const canvas = document.querySelector('#c2d');
        if(canvas.getContext) {
            const ctx = canvas.getContext('2d');
            ctx.save();

            ctx.fillStyle = 'red';
            ctx.fillRect(0,0,100,100);

            ctx.restore();
            ctx.fillRect(100,100,100,100);
        }
    </script>
</body>
</html>

移動座標原點

方法:translate(x,y):x,y代表移動後x,y座標

旋轉座標系

方法:rotate(angle), 旋轉角度,整數爲逆時針,負數爲順時針。

實例

<!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" width="500" height="500">不支持canvas</canvas>
    <script>
        const canvas = document.querySelector('#c2d');
        if(canvas.getContext) {
            const ctx = canvas.getContext('2d');
            ctx.fillRect(0,0,10,30);

            ctx.translate(10,30);
            ctx.fillRect(0,0,10,30);

            ctx.translate(10,30);
            ctx.rotate(-Math.PI * 1/2);
            ctx.fillStyle='red';
            ctx.fillRect(0,0,10,30);
        }
    </script>
</body>
</html>

縮放

方法: scale(x, y)
座標系除了可以移動和旋轉外還可以進行縮放,縮放使用的是scale方法,它有兩個參數,分別標識橫軸和縱軸縮放的比例, 1爲原始大小,大於1爲放大,小於1爲縮小。
示例:

<!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" height="600" width="600">瀏覽器不支持canvas</canvas>
    <script>
        const canvas = document.querySelector('#c2d');
        if(canvas.getContext) {
            const ctx = canvas.getContext('2d');
            
            ctx.fillText('愛我中華', 10, 50);

            ctx.scale(2,2);

            ctx.translate(50,50);

            ctx.fillText('愛我中華', 10, 50);
        }
    </script>
</body>
</html>

同樣是填充一個文本,由於第二次填充文字時,x軸和y軸都同比增加了2倍,所以文字的大小也相應的增加。

陰影

屬性值:

  • shadowOffsetX: 陰影的水平偏移距離
  • shadowOffsetY: 陰影的豎直偏移距離
  • shadowBlur: 陰影的模糊效果,數字越大越模糊
  • shadowColor: 陰影顏色

示例:

<!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.shadowOffsetX = -7;
            ctx.shadowOffsetY = 5;
            ctx.shadowBlur = 3;
            ctx.shadowColor = 'rgba(255,255,0,0.7)';
            
            ctx.fillStyle = 'red';
            ctx.fillRect(15,30,130,40);
        }
    </script>

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