Canvas笔记

canvas总结

一、canvas简介

1. 概念

canvas是HTML5提出来的,支持IE9以上的浏览器。

是一块画布,可以通过 JS 在上面进行各种图示图表、图像、动画的绘制。

2. 应用场景

  • 验证码
  • Echarts
  • 网页游戏
  • 图片、视频处理
  • 图片裁剪

二、canvas使用

1. 创建画布

1.1 创建画布

在 html 中创建指定大小的画布,默认 300 * 150px

注:宽高必须设置在标签属性上,如果写在css中,name是对原来的图像尺寸进行缩放

1
2
// 您当前的浏览器不支持 (不支持该语法的就是显示文字,支持的就不会显示出来)
<canvas id="myCanvas" width="400" height="300"></canvas>

1.2 获取并渲染

1
2
3
4
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d'); // 2D 渲染上下文
</script>

1.3 绘制图形

绘制填充矩形,默认颜色是黑色

ctx.fillRect(x,y,width,height)

参数:x:x 轴坐标,正方向是向右,坐标原点是 canvas 的左上角

​ y:y 轴坐标,正方向是向下

​ width:矩形宽度,单位 像素

​ height:矩形高度

绘制边框矩形

ctx.strokeRect(x, y, width, height)

擦除指定大小区域的矩形

ctx.clearRect(x, y, width, height)

1.4 样式控制

设置图形的填充颜色

ctx.fillStyle = color;

设置图形的边框颜色

ctx.strokeStyle = color;

设置边框线条的粗细

ctx.lineWidth = 值

2. 路径

1. 简介

在canvas中,除了矩形之外,其他的图形都必须通过路径绘制,然后再选择是描边还是填充

2. 路径绘制

语法 描述
ctx.beginPath() 表示开始进行路径绘制,每次调用该方法后,将会绘制新的路径
ctx.moveTo(x,y) 路径的起始点坐标
ctx.lineTo(x,y) 从上一点绘制到当前坐标,两点连成直线
ctx.closePath() 结束路径绘制,自动将起点坐标和结束点坐标链接
ctx.fill() 填充路径
ctx.stroke 描边路径
ctx.arc(x, y, r, startAngle, endAngle, bool) 圆弧路径绘制(x轴,y轴,圆的半径,开始绘制圆的角度,结束绘制圆的角度,默认逆时针)
ctx.quadraticCurveTo(cp1x, cp1y, x, y) 贝塞尔二次曲线,绘制一般曲线(控制点x轴的坐标,控制点y轴的坐标,x轴坐标,y轴坐标)

3. 完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
const myCanvas = document.getElementById('myCanvas')
const ctx = myCanvas.getContext('2d')

// 绘制矩形
ctx.fillStyle = '#ffff00'
// 填充矩形
ctx.fillRect(50, 50, 100, 100)

ctx.strokeStyle = '#ff0000'
ctx.lineWidth = 5
// 边框举行
ctx.strokeRect(200, 50, 100, 100)
ctx.clearRect(0, 0, 400, 300)

// 案例
// for (var i = 0; i < 6; i++) {
// for (var j = 0; j < 6; j++) {
// ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ',' + Math.floor(255 - 42.5 * j) + ',0)';
// ctx.fillRect(j * 50, i * 50, 50, 50);
// }
// }

// 路径绘制
// ctx.beginPath()
// ctx.moveTo(50, 50)
// ctx.lineTo(100, 100)
// ctx.lineTo(50, 100)
// ctx.closePath()

// 绘图
// ctx.stroke()
// ctx.fill()

ctx.beginPath()
ctx.arc(200, 150, 50, 0, Math.PI * 2, true)
ctx.stroke()

ctx.beginPath()
ctx.arc(60, 150, 50, 0, Math.PI, false)
ctx.closePath()
ctx.stroke()

// 曲线绘制
ctx.beginPath()
ctx.moveTo(100, 100)
ctx.quadraticCurveTo(50, 200, 200, 100)
ctx.stroke()

3. 图像绘制

1. 简介

将图片绘制到 canvas 中

2. 语法

ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

参数:

  • image:图片源(图像、画布或视频)
  • dx:绘制到画布中的 x 坐标点
  • dy:绘制到画布中的 y 坐标点
  • sx:可选,截取源图的 x 坐标点
  • sy:可选,截取源图的 y 坐标点
  • sWidth:可选,截取源图的宽度,实现对源图的截取
  • sHeight:可选,截取源图的高度
  • dWidth:可选,绘制到画布中图片宽度,可以实现图片的缩放
  • dHeight:可选,绘制到画布中图片高度,可以实现图片的缩放

:通过 canvas 绘制图形时,该图像必须在网页中加载出来,否则无法绘制

3. 获取像素点信息

ctx.getImageData(sx, sy, sw, sh);

参数:四个参数依次为获取像素点的 x、y 轴坐标及其宽高。

:该方法返回 ImageData 对象,是一个数组,该数组中依次保存了像素点信息(RGBA)。必须通过服务器访问网页才可以调用。

4. 绘制位图

将 getImageData 对象数据绘制到 canvas 中。

ctx.putImageData(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

5. 代码事例1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// html		
<canvas id="myCanvas" width="600" height="500"></canvas>
// js
const myCanvas = document.getElementById('myCanvas')
const ctx = myCanvas.getContext('2d')

// 通过 js 动态创建图片节点
const img = new Image()
img.src = 'h.jpg'
// 保证图片加载完成后再去绘制
img.onload = function () {
ctx.drawImage(img, 0, 0) // 原图输出
// 对原图进行缩放
// ctx.drawImage(img, 0, 0, 500, 500)
// 截取原图在绘制
// ctx.drawImage(img, 200, 150, 100, 100, 0, 0, 100, 100)

const imgData = ctx.getImageData(0, 0, 480, 480)
console.log(imgData);
}

6. 代码事例2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<canvas id="myCanvas" width="600" height="500"></canvas>

<button id="btn1">载入图像</button>
<button id="btn2">灰图</button>

<script>
const myCanvas = document.getElementById('myCanvas');
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
const ctx = myCanvas.getContext('2d');

// 先通过 js 动态创建图片节点
const img = new Image(); // 创建 img 对象
img.src = 'h.jpg';

btn1.onclick = function () {
ctx.drawImage(img, 0, 0, 200, 200);
}

btn2.onclick = function () {
const imageData = ctx.getImageData(0, 0, 200, 200);
const data = imageData.data; // 像素点数据
console.log(data);

// 灰图
// 求每个像素点 rgb 的平均值,然后再把平均值 覆盖到 rgb
// data 中每四个元素表示一个像素点,分别是 r g b a
// for (var i = 0; i < data.length; i += 4) {
// var avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
// data[i] = avg;
// data[i + 1] = avg;
// data[i + 2] = avg;
// }

for (var i = 0; i < data.length; i += 4) {
// var avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
data[i] = Math.floor(Math.random() * data[i]);
data[i + 1] = Math.floor(Math.random() * data[i + 1]);
data[i + 2] = Math.floor(Math.random() * data[i + 2]);
}

// 其他调整:补色、反色、调整色环

// 再将像素点信息绘制为图像
ctx.putImageData(imageData, 200, 0);
}
</script>