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>