前言:<canvas>HTML5 新增的,一个可以使用脚本(通常为JavaScript)在其中绘制图像的 HTML 元素。它可以用来制作照片集或者制作简单(也不是那么简单)的动画,甚至可以进行实时视频处理和渲染。

Canvas基本使用

<canvas>看起来和<img>标签一样,只是 <canvas> 只有两个可选的属性 width、heigth 属性,而没有 src、alt 属性。

如果不给<canvas>设置widht、height属性时,则默认 width为300、height为150,单位都是px。也可以使用css属性来设置宽高,但是如宽高属性和初始比例不一致,他会出现扭曲。所以,建议永远不要使用css属性来设置<canvas>的宽高。

兼容性

某些较老的浏览器(尤其是IE9之前的IE浏览器)或者浏览器不支持HTML元素<canvas>,然后可以用替代内容来渲染。

用文本替换:

1
2
3
<canvas>
你的浏览器不支持canvas,请升级你的浏览器
</canvas>

<img> 替换:

1
2
3
<canvas>
<img src="./404.jpg" alt="">
</canvas>

结束标签</canvas>不可省

<img>元素不同,<canvas>元素需要结束标签(</canvas>)。如果结束标签不存在,则文档的其余部分会被认为是替代内容,将不会显示出来。

渲染

<canvas>会创建一个固定大小的画布,会公开一个或多个 渲染上下文(画笔),使用 渲染上下文来绘制和处理要展示的内容。

获取渲染上下文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<body>
<canvas id="myCanvas" width="300px" height="150px">
你的浏览器不支持canvas,请升级你的浏览器
</canvas>
</body>

<script>
// 获取canvas对象
const canvas = document.querySelector('#myCanvas')
function draw(){
if (!canvas?.getContext){
console.log('不支持getContext');
return;
}
//获得 2d 上下文对象
var ctx = canvas.getContext('2d');
}
// 调用函数
draw()
</script>

属性

颜色、样式和阴影

属性 描述
fillStyle 设置或返回用于填充绘画的颜色、渐变或模式
strokeStyle 设置或返回用于笔触的颜色、渐变或模式
shadowColor 设置或返回用于阴影的颜色
shadowBlur 设置或返回用于阴影的模糊级别
shadowOffsetX 设置或返回阴影距形状的水平距离
shadowOffsetY 设置或返回阴影距形状的垂直距离

方法 描述
createLinearGradient() 创建线性渐变(用在画布内容上)
createPattern() 在指定的方向上重复指定的元素
createRadialGradient() 创建放射状/环形的渐变(用在画布内容上)
addColorStop() 规定渐变对象中的颜色和停止位置

线条样式

属性 描述
lineCap 设置或返回线条的结束端点样式
lineJoin 设置或返回两条线相交时,所创建的拐角类型
lineWidth 设置或返回当前的线条宽度
miterLimit 设置或返回最大斜接长度

矩形

方法 描述
rect() 创建矩形
fillRect() 绘制“被填充”的矩形
strokeRect() 绘制矩形边框(无填充)
clearRect() 在给定的矩形内清除指定的像素

路径

方法 描述
fill() 填充当前绘图(路径)
stroke() 绘制已定义的路径
beginPath() 起始一条路径,或重置当前路径
moveTo() 把路径移动到画布中的指定点,不创建线条
closePath() 创建从当前点回到起始点的路径
lineTo() 添加一个新点,然后在画布中创建从该点到最后指定点的线条
clip() 从原始画布剪切任意形状和尺寸的区域
quadraticCurveTo() 创建二次贝塞尔曲线
bezierCurveTo() 创建三次方贝塞尔曲线
arc() 创建弧/曲线(用于创建圆形或部分圆)
arcTo() 创建两切线之间的弧/曲线
isPointInPath() 如果指定的点位于当前路径中,则返回 true,否则返回 false

转换

方法 描述
scale() 缩放当前绘图至更大或更小
rotate() 旋转当前绘图
translate() 重新映射画布上的 (0,0) 位置
transform() 替换绘图的当前转换矩阵
setTransform() 将当前转换重置为单位矩阵。然后运行 transform()

文本

属性 描述
font 设置或返回文本内容的当前字体属性
textAlign 设置或返回文本内容的当前对齐方式
textBaseline 设置或返回在绘制文本时使用的当前文本基线

方法 描述
fillText() 在画布上绘制“被填充的”文本
strokeText() 在画布上绘制文本(无填充)
measureText() 返回包含指定文本宽度的对象

图像绘制

方法 描述
drawImage() 向画布上绘制图像、画布或视频

像素操作

属性 描述
width 返回 ImageData 对象的宽度
height 返回 ImageData 对象的高度
data 返回一个对象,其包含指定的 ImageData 对象的图像数据

方法 描述
createImageData() 创建新的、空白的 ImageData 对象
getImageData() 返回 ImageData 对象,该对象为画布上指定的矩形复制像素数据
putImageData() 把图像数据(从指定的 ImageData 对象)放回画布上

合成

属性 描述
globalAlpha 设置或返回绘图的当前 alpha 或透明值
globalCompositeOperation 设置或返回新图像如何绘制到已有的图像上

绘制矩形

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

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

    绘制一个填充的矩形

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

    绘制一个矩形的边框

  3. clearRect(x, y, widh, height)

    清除指定的矩形区域,然后这块区域会变的完全透明。

案例:绘制两个矩形

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
<!DOCTYPE html>
<html lang="en">
<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>Canvas的基本使用</title>
</head>
<body>
<canvas id="myCanvas" width="300px" height="150px">
你的浏览器不支持canvas,请升级你的浏览器
</canvas>
</body>

<script>
// 获取canvas对象
const canvas = document.querySelector('#myCanvas')
function draw(){
if (!canvas?.getContext){
console.log('不支持getContext');
return;
}
//获得 2d 上下文对象
var ctx = canvas.getContext('2d');
// 设置或返回用于填充绘画的颜色、渐变或模式
ctx.fillStyle = "rgb(200,0,0)";
// fillRect(x,y,width,height) 绘制一个填充的矩形
ctx.fillRect (10, 10, 55, 50);
// 设置或返回用于笔触的颜色、渐变或模式
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect (50, 50, 55, 50);
}
// 调用函数
draw()
</script>

</html>

绘制路径(path)

图形的基本元素是路径。

路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。

一个路径,甚至一个子路径,都是闭合的。

使用路径绘制图形需要一些额外的步骤:

  1. 创建路径起始点
  2. 调用绘制方法去绘制出路径
  3. 把路径封闭
  4. 一旦路径生成,通过描边或填充路径区域来渲染图形。

下面是需要用到的方法:

  1. beginPath()

    新建一条路径,路径一旦创建成功,图形绘制命令被指向到路径上生成路径

  2. moveTo(x, y)

    把画笔移动到指定的坐标(x, y)。相当于设置路径的起始点坐标。

  3. closePath()

    闭合路径之后,图形绘制命令又重新指向到上下文中

  4. stroke()

    通过线条来绘制图形轮廓

  5. fill()

    通过填充路径的内容区域生成实心的图形

绘制线段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
// 获取canvas对象
const canvas = document.querySelector('#myCanvas')
function draw(){
if (!canvas?.getContext){
console.log('不支持getContext');
return;
}
//获得 2d 上下文对象
var ctx = canvas.getContext('2d');
ctx.beginPath(); //新建一条path
ctx.moveTo(50, 50); //把画笔移动到指定的坐标
ctx.lineTo(300, 80); //绘制一条从当前位置到指定坐标(200, 50)的直线.
//闭合路径。会拉一条从当前点到path起始点的直线。如果当前点与起始点重合,则什么都不做
ctx.closePath();
ctx.stroke(); //绘制路径
}
// 调用函数
draw()
</script>

绘制三角形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
// 获取canvas对象
const canvas = document.querySelector('#myCanvas')
function draw(){
if (!canvas?.getContext){
console.log('不支持getContext');
return;
}
//获得 2d 上下文对象
var ctx = canvas.getContext('2d');
ctx.beginPath(); //新建一条path
ctx.moveTo(50, 50); //把画笔移动到指定的坐标
ctx.lineTo(150, 50); //绘制一条从当前位置到指定坐标(150, 50)的直线.
ctx.lineTo(150, 120); //绘制一条从当前位置到指定坐标(150, 120)的直线.
//闭合路径。会拉一条从当前点到path起始点的直线。如果当前点与起始点重合,则什么都不做
ctx.closePath();
ctx.stroke(); //绘制路径
}
// 调用函数
draw()
</script>

绘制圆弧

有两个方法可以绘制圆弧:

  1. arc(x, y, r, startAngle, endAngle, anticlockwise):

(x, y)为圆心,以r为半径,从 startAngle弧度开始到endAngle弧度结束。anticlosewise是布尔值,true表示逆时针,false表示顺时针。(默认是顺时针)

注意:

  1. 这里的度数都是弧度。
  2. 0弧度是指的x轴正方形
1
radians=(Math.PI/180)*degrees   //角度转换成弧度
  1. arcTo(x1, y1, x2, y2, radius):

根据给定的控制点和半径画一段圆弧,最后再以直线连接两个控制点。

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
<script>
// 获取canvas对象
const canvas = document.querySelector('#myCanvas')
function draw(){
if (!canvas?.getContext){
console.log('不支持getContext');
return;
}
//获得 2d 上下文对象
var ctx = canvas.getContext('2d');
ctx.beginPath(); //新建一条path
ctx.arc(50, 50, 80, 0, Math.PI / 2, false);
ctx.stroke(); //绘制路径

ctx.beginPath();
ctx.arc(150, 50, 40, 0, -Math.PI / 2, true);
ctx.closePath();
ctx.stroke();

ctx.beginPath();
ctx.arc(30, 30, 50, -Math.PI / 2, Math.PI / 2, false);
ctx.fill();

}
// 调用函数
draw()
</script>

绘制贝塞尔曲线

绘制二次贝塞尔曲线

quadraticCurveTo(cp1x, cp1y, x, y):

参数1和2:控制点坐标

参数3和4:结束点坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
// 获取canvas对象
const canvas = document.querySelector('#myCanvas')
function draw(){
if (!canvas?.getContext){
console.log('不支持getContext');
return;
}
//获得 2d 上下文对象
var ctx = canvas.getContext('2d');
ctx.beginPath(); //新建一条path
ctx.moveTo(120, 120); //起始点
var cp1x = 60, cp1y = 40; //控制点
var x = 120, y = 70; // 结束点
//绘制二次贝塞尔曲线
ctx.quadraticCurveTo(cp1x, cp1y, x, y);
ctx.stroke();

}
// 调用函数
draw()
</script>