Canvas知識點梳理

1、前言

Canvas是HTML5標準中推出的一個很是受歡迎的功能元素,這個元素負責在頁面中設定一個區域,而後就能夠JS動態地在這個區域中繪製圖形了。而且它仍是跨平臺動畫和遊戲的標準方案。javascript

2、前提條件

2.1 初始化

要使用canvas元素必須先設置其width和height屬性,指定繪圖區域的大小。html

若是瀏覽器不支持該功能,那麼將會顯示你在canvas標籤中鍵入的文本內容。前端

<!-- 寬度爲400,高度爲400的canvas -->
<canvas id="myCvs" width="400" height="400"> Your browser does not support canvas. </canvas>
複製代碼

2.2 建立繪圖環境

在使用canvas元素以前,必須保證要有一個2d的繪圖環境。java

if(myCvs.getContext) {
    var context = myCvs.getContext('2d');
}else {
    console.log('Your browser does not support canvas.');
}
複製代碼

使用2d繪圖環境提供的方法,能夠繪製簡單的2d圖形,好比矩形、弧線和路徑。git

它的座標原點(0, 0)在canvas元素的左上角。 github

2.3 案例

在學習2d繪圖方法以前,咱們試着看一下canvas的一個簡單例子:畫一個綠色矩形。canvas

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Canvas</title>
<style>
    canvas {
        border: 1px solid #000;
    }
</style>
</head>
<body>
    <!-- 寬度爲400,高度爲400的canvas -->
    <canvas id="myCvs" width="400" height="400">
        Your browser does not support canvas.
    </canvas>

    <script>
        var myCvs = document.getElementById('myCvs');

        // 檢測是否支持2d上下文
        if(myCvs.getContext) {
            var context = myCvs.getContext('2d');
        }else {
            console.log('Your browser does not support canvas.');
        }
        function load() {
            context.fillStyle = '#0f0'; // 填充顏色爲綠色
            context.fillRect(50,25,300,150); // 填充矩形 (起點x座標, 起點y座標, 寬度, 高度)
        }
        window.onload = function() {
            load();
        }
    </script>
</body>
</html>
複製代碼

3、基礎使用

canvas在2d上下文環境中提供了一些可供畫圖的屬性和方法,接下來具體看一下。數組

3.1 描邊和填充

描邊,就是隻在圖形的邊緣畫線;瀏覽器

填充,就是用指定的樣式(顏色、漸變或圖像)填充圖像。ide

var myCvs = document.getElementById('myCvs');
if(myCvs.getContext) {
    var context = myCvs.getContext('2d');

    context.strokeStyle = 'red'; // 描邊
    context.fillStyle = 'green'; // 填充
}
複製代碼

3.2 繪製矩形

矩形是惟一一種能夠直接在2d上下文中繪製的形狀。

與矩形有關的方法包括fillRect()、strokeRect()和clearRect()。

它們接收4個參數:矩形的x座標,矩形的y座標,矩形寬度和矩形高度。單位都是像素。

3.2.1 fillRect() 填充矩形

// 繪製紅色矩形
context.fillStyle = 'red'; // 指定填充顏色爲紅色
context.fillRect(10,10,50,50); // 指定填充矩形的4個參數
複製代碼

3.2.2 strokeRect() 描邊矩形

// 繪製綠色描邊矩形
context.strokeStyle = 'green'; // 指定描邊顏色
context.strokeRect(70,10,50,50); // 指定描邊矩形的4個參數
複製代碼

3.2.3 clearRect() 清除矩形區域

// 清除畫布矩形區域
context.clearRect(0,0,400,400);
複製代碼

3.3 繪製路徑

經過路徑能夠創造出複雜的形狀和線條。

3.3.1 路徑方法

  • arc(x, y, radius, startAngle, endAngle, counterclockwise):以(x, y)爲圓心繪製一條弧線,弧線半徑爲radius,起始和結束角度(弧度)分別爲 startAngle和endAngle,最後一個參數counterclockwise表示繪製方向是否按照逆時針方向計算,值false表示按順時針方向計算。
  • arcTo(x1, y1, x2, y2, radius):從上一點開始繪製一條弧線,到(x2,y2)爲止,而且以給定半徑radius穿過(x1,y1)。
  • bezierCurveTo(c1x, c1y, c2x, c2y, x, y):從上一點開始繪製一條曲線,到(x,y)爲止,而且以(c1x,c1y)和(c2x,c2y)爲控制點。
  • lineTo(x, y):從上一點開始繪製一條直線,到(x,y)爲止。
  • moveTo(x, y):將繪圖畫筆移動到(x, y),不畫圖。通常後面就接lineTo()方法。
  • quadraticCurveTo(cx, cy, x, y):從上一點開始繪製一條二次曲線,到(x, y)爲止,而且以(cx, cy)做爲控制點。
  • rect(x, y, width, height):從點(x, y)開始繪製一個矩形,寬度和高度分別由width和height指定。注意這裏畫的是矩形路徑而不是獨立形狀。

3.3.2 繪製流程

在繪製路徑以前,必須調用beginPath()方法,表示要開始繪製新的路徑了。

在建立了新的路徑以後,若是想要繪製一條鏈接到路徑起點的線條,那麼就調用closePath()方法

若是路徑已經完成,想要填充它那麼就調用fill()方法,想要描邊就調用stroke()方法

3.3.3 案例

畫線

// 畫線組成矩形
context.beginPath(); // 指定新路徑
context.moveTo(10,70); // 畫筆移動至(10,70)
context.lineTo(10,120); // 第一點座標
context.lineTo(60,120); // 第二點座標
context.lineTo(60,70); // 第三點座標
context.closePath(); // 閉合路徑
context.strokeStyle = 'blue'; // 指定描邊顏色
context.stroke(); // 描邊
複製代碼

畫圓弧

// 畫圓弧
context.beginPath();
context.arc(95,95,25,0,2*Math.PI,true); // 圓心(95,95) 起始角度0弧度 結束角度2PI弧度 逆時針方向計算
context.closePath();
context.stroke();
複製代碼

三角形

// 三角形
context.beginPath();
context.moveTo(150, 70); // 第一點座標
context.lineTo(125, 120); // 第二點座標
context.lineTo(175, 120); // 第三點座標
context.closePath();
context.fillStyle = 'yellow' // 指定填充顏色
context.fill(); // 填充
複製代碼

貝塞爾曲線

// 二次貝塞爾曲線(1個控制點)
context.beginPath();
context.moveTo(10, 155); // 畫筆移動到(10,155)
context.quadraticCurveTo(60, 200, 300, 155); // 控制點座標(60,200) 結束點座標(300,155)
context.stroke();
// 三次貝塞爾曲線(2個控制點)
context.beginPath();
context.moveTo(10, 355); // 畫筆移動到(10,355)
context.bezierCurveTo(90, 200, 150, 300, 350, 350); // 控制點座標(90,200)和(150,300) 結束點座標(350,350)
context.strokeStyle = 'green';
context.stroke();
複製代碼

案例結果如圖所示:

4、Canvas的圖形變換

在Canvas的2d上下文中還支持各類基本的繪製變換。

這裏介紹平移、旋轉、縮放三種變換在Canvas中的實現。

4.1 保存與恢復

在瞭解各類變換以前,咱們先想一個這樣的問題:在用canvas畫圖時,若是咱們頻繁使用幾個默認值的設定,是否能夠重置爲默認值而沒必要重複定義呢?

這時就要用到2d上下文提供的保存和恢復的方法了,即save()和restore()方法,它們是以堆棧**(先進後出)的形式保存繪圖上下文的設置和變換**。

這裏看個例子,依次保存而後依次恢復讀取設置的顏色。

var myCvs = document.getElementById('myCvs');
var ctx = myCvs.getContext('2d');

ctx.strokeStyle = '#f00';
ctx.save(); // 保存指定顏色-紅色

ctx.strokeStyle = '#0f0';
ctx.save(); // 保存指定顏色-綠色

ctx.strokeStyle = '#00f';
ctx.save(); // 保存指定顏色-藍色

ctx.restore(); // 恢復指定顏色-藍色
ctx.strokeRect(10, 10, 50, 50);

ctx.restore(); // 恢復指定顏色-綠色
ctx.strokeRect(70, 10, 50, 50);

ctx.restore(); // 恢復指定顏色-紅色
ctx.strokeRect(130, 10, 50, 50);
複製代碼

4.2 平移

translate(x, y):將座標原點移動到(x, y)。

這裏用translate()方法配合保存和恢復方法實現顏色漸變。

// 顏色漸變正方形
ctx.translate(10, 80);
for(var i = 1; i < 9; i++) {
    ctx.save(); // 保存上一步(平移原點)的操做
    ctx.translate(30*i, 0); // 將原點沿着x方向平移30*i的距離 到達新的座標原點(30*i, 0)
    ctx.fillStyle = "rgb(" + (30*i) + "," + (255-30*i) + ",255)"; // 指定顏色
    ctx.fillRect(0,0,30,30); // 在(30*i, 0)處按照指定顏色填充矩形
    ctx.restore(); // 讀取上一次保存的操做 從新回到(10, 80)
}
複製代碼

4.3 旋轉

rotate(angle):圍繞原點旋轉圖像的angle弧度。

這裏利用rotate()方法配合保存和恢復方法實現形狀的變換。

// 旋轉正方形
ctx.translate(180, 140); // 將原點平移到(180,140)
for(var i = 1; i < 9; i++) {
    ctx.save(); // 保存上一步(平移原點)的操做
    ctx.rotate(Math.PI * (1/2 + i/4)); // 每次循環將圖形繞着原點旋轉PI/4弧度 總共旋轉8次
    ctx.translate(0, -50); // 旋轉完成後,將原點移動到(0, -50)
    ctx.fillStyle = "rgb(" + (30 * i) + "," + (255 - 30*i) + ",255)"; // 指定顏色
    ctx.fillRect(-30, -30, 30, 30); // 在(0, -50)處按照指定顏色填充矩形
    ctx.restore(); // 讀取上一次保存的操做 從新回到(180, 140)
}
複製代碼

4.4 縮放

scale(scaleX, scaleY):縮放圖像,在x方向乘以scaleX,在y方向乘以scaleY。默認值爲1。

這裏綜合上述幾個方法,繪製一幅海螺圖形。

// 海螺圖形
ctx.translate(200, 80);
for(var i = 1; i < 80; i++) {
    ctx.translate(30, 30);
    ctx.scale(0.95, 0.95); // 設置縮放比例
    ctx.rotate(Math.PI/12);
    ctx.beginPath();
    ctx.fillStyle = '#f00';
    ctx.globalAlpha = '0.3'; // 設置圖形透明度
    ctx.arc(0,0,50,0,Math.PI*2,true);
    ctx.fill();
}
複製代碼

5、Canvas的繪製圖像

文本和圖形是如影隨形的,2d繪圖上下文提供了繪製圖像和文本的方法。

這裏介紹一下繪製圖像的基本操做。

2d繪圖上下文內置了對圖像的支持,提供了drawImage()方法,它有三種不一樣的參數組合。

接下來,依次看看不一樣的參數組合。

5.1 正常繪製圖像

最簡單的參數組合是:傳入一個HTML圖像元素,以及繪製該圖像的起點的x和y座標。

let myCvs = document.getElementById('myCvs');
let context = myCvs.getContext('2d');
let img = new Image();
img.src = './img/canvas.png'; // 我愛前端的一張圖片
img.onload = () => {
    context.drawImage(img, 50, 50); // 1. 正常繪製
}
複製代碼

5.2 壓縮、拉伸繪製圖像

除了上面傳的參數(要繪製的圖像、源圖像x座標、源圖像y座標),還能夠再傳兩個參數,分別表示目標寬度和目標高度。

這裏繪製的圖像大小爲100x100像素。

context.drawImage(img, 50, 50, 100, 100); // 2. 目標寬高均爲100
複製代碼

5.3 區域裁剪繪製圖像

除了上述兩種方式,還能夠選擇把圖像中的某個區域繪製到上下文中。

這時候要傳入9個參數:要繪製的圖像、源圖像的x座標、源圖像的y座標、源圖像的寬度、源圖像的高度、目標圖像的x座標、目標圖像的y座標、目標圖像的寬度、目標圖像的高度。

簡單來講就是,第2至第5個參數告訴咱們圖像上怎麼截取一部分,第6至第9個參數告訴咱們怎麼在canvas上畫出圖像。

context.drawImage(img, 50, 50, 200, 200, 150, 100, 100, 300); // 3. 截取源圖像的(50,50)處200x200像素的區域範圍內的圖像,並把圖像在canvas上的(150,100)處以100x300像素的方式繪製出來。
複製代碼

6、Canvas的繪製文本

除了繪製圖像,2d上下文還提供了繪製文本的方法。

繪製文本主要有兩個方法fillText()和strokeText()

這兩個方法都接收4個參數:要繪製的文本字符串、x座標、y座標和可選的最大像素寬度。

6.1 實心文字

// 實心文字
let myCvs = document.getElementById('myCvs');
let context = myCvs.getContext('2d');
let text = '我愛前端FrontEnd1314!'; // 定義一個字符串做爲文本
context.fillStyle = '#f00'; // 指定填充顏色
context.fillText(text, 30, 60); // 指定文本字符串及x座標y座標
複製代碼

6.2 空心文字

// 空心文字
context.strokeStyle = '#0f0'; // 指定描邊顏色
context.strokeText(text, 30, 120); // 指定文本字符串及x座標y座標
複製代碼

另外,繪製文本還有若干文本屬性能夠設置。

6.3 文字樣式

// 字體樣式
context.font = 'bold 30px 黑體';
複製代碼

6.4 對齊方式

文本的對齊方式有:start、end、left、right、center

// 對齊方式(start end left right center)
context.textAlign = 'start'; // 從左往右顯示文本
// context.textAlign = 'end'; // 從右往左顯示文本
複製代碼

6.5 文字基線

文本的文字基線有:alphabetic、top、bottom、middle、hanging、ideographic

// 文本基線(alphabetic top bottom middle hanging ideographic)
context.textBaseline = 'middle';
複製代碼

6.6 測量字符串寬度

// 測量字符串寬度
let width = context.measureText(text).width/2; // 獲取到文本字符串寬度的一半
context.strokeText(text, 30, 200);
context.strokeStyle = '#00f';
context.strokeText(text, 30-width, 200); // 檢驗可得 就是一半的長度
複製代碼

7、源碼地址

源碼地址:github.com/Knight174/M…

想要練習JS的小夥伴,進入JS練習羣 637059122 一塊兒進步~

相關文章
相關標籤/搜索