HTML學習筆記(四) Canvas

<canvas> 標籤用於定義圖形容器,容器本身是沒有畫圖能力的,但我們可以使用腳本來繪製圖形

1、創建畫布

在 HTML 中,使用 <canvas> 標籤可以創建一個矩形畫布,這個畫布的默認寬高爲 300*150

如果要改變畫布的大小,建議通過內聯樣式或者腳本進行設置,否則很容易會出現畫布扭曲的情況

<!DOCTYPE html>
<html>
<head>
    <title>Canvas Demo</title>
</head>
<body>
    <canvas id="graph" width="300" height="300">您的瀏覽器不支持 canvas 標籤</canvas>
</body>
</html>

2、創建畫筆

在 JavaScript 中,使用 getContext() 方法可以創建一個渲染上下文對象

這個對象就相當於是這個畫布的畫筆,擁有一系列用於畫圖的方法

<script>
	var canvas = document.getElementById('graph')
    var context = canvas.getContext('2d')
    // 開始畫圖
</script>

3、繪製矩形

Canvas 只支持一種原生圖形的繪製方法,那就是矩形,其它圖形都必須通過路徑生成

  • strokeRect(x, y, width, height):繪製一個矩形的邊框
  • fillRect(x, y, width, height):繪製一個填充的矩形
  • clearRect(x, y, width, height):清空指定的矩形區域

其中,參數 x、y 定義矩形左上角的座標,參數 width、height 定義矩形的寬高

<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    ctx.strokeRect(10, 10, 100, 100)
</script>

4、繪製路徑

圖形的基本元素是路徑,路徑是線段和點的集合,在 Canvas 中每一個路徑都是閉合的

  • beginPath():新建一條路徑
  • closePath():結束一條路徑,它會從當前點到起始點拉一條直線,使得路徑閉合
  • moveTo(x, y):將畫筆移動到指定座標
  • stroke():繪製圖形(閉合路徑)的邊框
  • fill():填充圖形(閉合路徑)的內容,如果路徑沒有閉合,首先閉合路徑

  • lineTo(x, y):創建一條直線路徑,從 當前座標(x, y) 連接一條直線
<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    ctx.beginPath()
    ctx.moveTo(150, 90)
    ctx.lineTo(60, 210)
    ctx.lineTo(240, 210)
    ctx.closePath() // 結束一條路徑,從當前點到起始點拉一條直線,使得路徑閉合
    ctx.stroke() // 繪製圖形(閉合路徑)的邊框
</script>
<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    ctx.beginPath()
    ctx.moveTo(150, 90)
    ctx.lineTo(60, 210)
    ctx.lineTo(240, 210)
    ctx.fill() // 填充圖形(閉合路徑)的內容,如果路徑沒有閉合,首先閉合路徑
</script>
  • arc(x, y, r, startAngle, endAngle, anticlockwise):創建一段圓弧路徑

    (x, y) 爲圓心,以 r 爲半徑,從 startAngle 開始,到 endAngle 結束,畫一段圓弧

    如果 anticlockwisetrue,則逆時針畫,如果 anticlockwisefalse,則順時針畫

  • arcTo(x1, y1, x2, y2, radius):創建一段圓弧路徑

    首先我們想象從 當前座標(x1, y1) 畫一條直線,然後從 (x1, y1)(x2, y2) 畫一條直線

    這個方法的作用就是畫一段半徑爲 radius 並且與兩條直線相切的圓弧

    注意哦,從 當前座標(x1, y1) 的直線也會留在畫布上

<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')

    ctx.beginPath()
    ctx.arc(150, 150, 100, Math.PI*1.5, Math.PI*0.5, true)
    ctx.fill()

    ctx.beginPath()
    ctx.moveTo(50, 50)
    ctx.arcTo(250, 50, 250, 250, 100)
    ctx.stroke()
</script>
  • quadraticCurveTo(cpx, cpy, x, y):繪製二次貝塞爾曲線

    其中,(cpx, cpy) 表示控制點的座標,(x, y) 表示結束點的座標

  • bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y):繪製三次貝塞爾曲線

    (cp1x, cp1y) 是第一個控制點的座標,(cp2x, cp2y) 是第二個控制點的座標,(x, y) 是結束點的座標

<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    
    ctx.beginPath()
    ctx.moveTo(25, 100)
    ctx.quadraticCurveTo(75, 50, 125, 100)
    ctx.stroke()

    ctx.beginPath()
    ctx.moveTo(175, 250)
    ctx.bezierCurveTo(205, 200, 245, 200, 275, 250)
    ctx.stroke()
</script>

5、繪製文字

我們可以使用以下兩個方法繪製文字:

  • strokeText(text, x, y):在指定座標 (x, y) 處創建空心文本 text
  • fillText(text, x, y):在指定座標 (x, y) 處創建實心文本 text

還能使用以下屬性指定文字樣式:

  • font:指定文本樣式,與 CSS font 屬性取值相同,默認值爲 10px sans-serif
  • textAlign:指定文本對齊選項,可選值有 startendleftrightcenter
  • textBaseline:指定基線對齊選項,可選值有 alphabetictopmiddlebottomideographichanging
  • direction:指定文本方向,可選值有 inheritltrrtl
<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    
    ctx.font = '50px sans-serif'
    ctx.strokeText('Hello', 80, 160)
</script>

6、添加樣式

(1)顏色

除了使用默認的黑色之外,我們還可以給圖形設置指定的顏色

  • strokeStyle:設置圖形邊框的顏色
  • fillStyle:設置圖形內容的顏色

注意,一旦設置上面兩個屬性,那麼新繪製的圖形都是使用指定好的顏色

<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    
    for (let i = 0; i <= 5; i += 1) {
        for (let j = 0; j <= 5; j += 1) {
            let r = randInt(0, 255)
            let g = randInt(0, 255)
            let b = randInt(0, 255)
            ctx.fillStyle = `rgb(${r}, ${g}, ${b})`
            ctx.fillRect(j * 50, i * 50, 50, 50)
        }
    }

    function randInt(start, end) {
        return Math.floor(Math.random() * (end - start + 1) + start)
    }
</script>

(2)漸變

除了使用常規的顏色,還能通過漸變對象使用漸變效果,漸變效果可以添加在圖形、文本上

首先創建一個漸變對象

  • createLinearGradient(x1, y1, x2, y2):創建線性漸變

    (x1, y2) 定義漸變線的起點座標,(x2, y2) 定義漸變線的終點座標,漸變效果沿漸變線展開

  • createRadialGradient(x1, y1, r1, x2, y2, r2):創建徑向漸變

    定義一個以 (x1, y1) 爲座標、以 r1 爲圓心的圓,定義一個以 (x2, y2) 爲座標、以 r2 爲圓心的圓

    漸變效果發生在兩個圓之間

然後給漸變對象定義漸變的效果

  • addStopColor(position, color):指定漸變顏色

    position 是一個 0 ~ 1 之間的數值,定義在漸變中的相對位置,color 用於定義在該處的顏色

<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    
    var grd = ctx.createLinearGradient(0, 0, 100, 100)
    grd.addColorStop(0.0, 'red')
    grd.addColorStop(0.5, 'green')
    grd.addColorStop(1.0, 'blue')
    
    ctx.fillStyle = grd
    ctx.fillRect(0, 0, 100, 100)
</script>

(3)形狀

除了可以指定顏色,我們還可以指定線段的形狀

  • lineWidth:指定線段寬度
<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    
    for (let i = 0; i <= 2; i += 1) {
        ctx.beginPath()
        ctx.moveTo(100, i * 20 + 50)
        ctx.lineTo(200, i * 20 + 50)
        ctx.lineWidth = i * 10 + 1
        ctx.stroke()
    }
</script>
  • lineCap:指定線段末端的樣式,其取值有三個:

    若爲 butt,則以方形結束

    若爲 round,則以圓形結束

    若爲 square,則以方形結束,但增加一個寬度與線段寬度相同,高度是寬度一半的矩形區域

<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    
    let lineCap = ['butt', 'round', 'square']
    for (let i = 0; i <= 2; i += 1) {
        ctx.beginPath()
        ctx.moveTo(100, i * 20 + 50)
        ctx.lineTo(200, i * 20 + 50)
        ctx.lineWidth = 10
        ctx.lineCap = lineCap[i]
        ctx.stroke()
    }
</script>
  • lineJoin:指定線段之間的連接樣式,其取值有三個:

    若爲 miter,通過延伸相連部分的外邊緣,使其相交於一點,形成一個額外的菱形區域

    若爲 round,填充一個額外的、圓心在相連部分末端的扇形

    若爲 bevel,填充一個額外的、以三角形爲底的區域

<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    
    let lineJoin = ['miter', 'round', 'bevel']
    for (let i = 0; i <= 2; i += 1) {
        ctx.beginPath()
        ctx.moveTo(100, i * 20 + 50)
        ctx.lineTo(150, i * 20 + 100)
        ctx.lineTo(200, i * 20 + 50)
        ctx.lineWidth = 10
        ctx.lineJoin = lineJoin[i]
        ctx.stroke()
    }
</script>

7、創建圖片

  • drawImage(image, x, y, width, height)

    參數 image 表示圖片的來源,既可以是一個 Image 對象,也可以是一個 <img> 元素

    參數 xy 定義圖片位置,表示左上角的座標;參數 widthheight 定義圖片大小,表示圖片的寬高度

<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    
	var img = new Image()
    img.src = 'https://cdn.pixabay.com/photo/2020/02/15/16/09/loveourplanet-4851331__340.jpg'
    
    img.onload = function() {
        ctx.drawImage(img, 0, 0, 300, 300)
    }
</script>
  • drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight):剪裁圖片

    參數 image 表示圖片的來源,既可以是一個 Image 對象,也可以是一個 <img> 元素

    sx, sy, sWidth, sHeight 定義對原圖片的切片,dx, dy, dWidth, dHeight 定義在畫布上的繪製

<script>
    var cvs = document.getElementById('graph')
    var ctx = cvs.getContext('2d')
    
	var img = new Image()
    img.src = 'https://cdn.pixabay.com/photo/2020/02/15/16/09/loveourplanet-4851331__340.jpg'
    
    img.onload = function() {
        ctx.drawImage(img, 180, 40, 100, 100, 0, 0, 300, 300)
    }
</script>

【 閱讀更多 HTML 系列文章,請看 HTML學習筆記

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