Skip to content

canvas 笔记

1.初识 Canvas

<canvas><img>很相像,唯一的不同就是它并没有 src 和 alt 属性。实际上,<canvas> 标签只有两个属性 width 和 height。这些都是可选的。

html
<canvas id="tutorial" width="150" height="150"></canvas>
CanvasSvg
依赖分辨率不依赖分辨率
不支持事件处理器支持事件处理器
弱的文本渲染能力适合大型渲染区域的应用程序(如在线地图)
能够以 png 或 jpg 格式保存图像复杂度高会减慢渲染速度
适合图像密集型游戏,很多对象会被频繁重绘不适合游戏应用

注意: 如果你绘制出来的图像是扭曲的, 尝试用 width 和 height 属性为明确规定宽高,而不是使用 CSS。

1.1 一个模板骨架

html
<body>
  <canvas id="c1" width="600" height="600"></canvas>
  <script>
    // 1.找到画布对象
    /** @type {HTMLCanvasElement} */
    let canvas = document.querySelector('#c1')
    // 2.获取画笔
    let ctx = canvas.getContext('2d') // 2d:平面对象  webgl:3d对象 // 2d 游戏引擎 --> 白鹭引擎  3d 游戏引擎 -->three.js
    // 3.绘制路径
    ctx.rect(50, 50, 300, 300)
    // 4.填充
    ctx.fillStyle = 'skyblue'
    ctx.fill()
    // 描边
    ctx.strokeStyle = 'red'
    ctx.lineWidth = 10
    ctx.stroke()
  </script>
</body>

如这里所示,它最初是空白的。

1.2 canvas 来绘制图形

canvas 提供了三种方法绘制矩形:

上面提供的方法之中每一个都包含了相同的参数。x 与 y 指定了在 canvas 画布上所绘制的矩形的左上角(相对于原点)的坐标。width 和 height 设置矩形的尺寸。

1.2.1 线条

html
<body>
  <canvas id="canvas1" width="300" height="300"></canvas>
  <script>
    const canvas = document.getElementById('canvas1')
    const ctx = canvas.getContext('2d')
    // 设置绘制的起点
    ctx.beginPath()
    ctx.moveTo(10, 10)
    // 设置经过的位置
    ctx.lineTo(10, 200)
    ctx.lineTo(200, 200)
    ctx.lineTo(200, 100)
    ctx.closePath()
    // 设置线条的样式
    ctx.lineWidth = 10
    ctx.strokeStyle = 'aqua'
    // 设置线段头部样式
    ctx.lineCap = 'round' // 线段头 线段末 默认为butt
    ctx.lineJoin = 'round' // 线段拐角 默认为miter

    ctx.stroke()
  </script>
</body>

1.2.2 圆或者圆弧

html
<body>
  <canvas id="canvas" width="300" height="300"></canvas>
  <script>
    const ctx = document.getElementById('canvas').getContext('2d')
    ctx.beginPath()
    //arc(中心x,中心y,半径长度,圆弧起始点,圆弧终点,逆时针/顺时针)
    ctx.arc(150, 150, 100, 0, Math.PI + Math.PI / 2, true)
    ctx.lineTo(150, 150)
    ctx.lineTo(250, 150)
    ctx.fillStyle = 'bisque'
    ctx.fill()
    ctx.stroke()
  </script>
</body>

1.2.3 文字

html
<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>font</title>
</head>
<body>
  <canvas id="canvas" width="600" height="600"></canvas>
  <script>
    const ctx = document.getElementById('canvas').getContext('2d')
    ctx.font = ' 36px blod 微软雅黑'
    // 设置阴影
    ctx.shadowBlur = 20
    ctx.shadowColor = 'rgba(0,0,0,1)'
    ctx.fillText('冰冻大西瓜', 100, 100)
  </script>
</body>

1.3 绘制图像

1.3.1 绘制图像

html
<body>
  <canvas id="canvas" width="600" height="600"></canvas>
  <script>
    const ctx = document.getElementById('canvas').getContext('2d')
    let img1 = new Image()
    let img2 = new Image()
    img1.src = 'img/1.jpeg'
    img2.src = 'img/2.jpeg'
    img1.onload = function () {
      // 绘制图像
      // ctx.drawImage(图片路径,x位置,y位置)
      // ctx.drawImage(图片路径,x位置,y位置,指定图片宽度,指定图片高度)
      // ctx.drawImage(图片路径,裁剪位置x,裁剪位置y,裁剪长度,裁剪宽度,x位置,y位置,指定图片宽度,指定图片高度)
      ctx.drawImage(img1, 50, 50)
    }
    img2.onload = function () {
      ctx.drawImage(img2, 50, 200, 350, 250)
    }
  </script>
</body>

1.3.2 绘制视频

html
<body>
  <canvas id="canvas" width="600" height="338"></canvas>
  <video id="video" controls src="img/1.mp4" width="600"></video>
  <br />
  <button id="btn">播放/暂停</button>
  <script>
    const ctx = document.getElementById('canvas').getContext('2d')
    const video = document.getElementById('video')
    const btn = document.getElementById('btn')
    let timer, flag
    video.onplay = function () {
      timer = setInterval(() => {
        ctx.clearRect(0, 0, video.width, video.height)
        ctx.drawImage(video, 0, 0, 600, 338)
      }, 16)
    }
    video.onpause = function () {
      clearInterval(timer)
    }
    btn.onclick = function () {
      if (!flag) {
        flag = true
        video.play()
      } else {
        flag = false
        video.pause()
      }
    }
  </script>
</body>