二、基本图形绘制
1.栅格
在我们开始画图之前,我们需要了解一下画布栅格(canvas grid)以及坐标空间。
如下图所示,canvas 元素默认被网格所覆盖。通常来说网格中的一个单元相当于 canvas 元素中的一像素。栅格的起点为左上角(坐标为(0,0))。所有元素的位置都相对于原点定位。所以图中蓝色方形左上角的坐标为距离左边(X 轴)x 像素,距离上边(Y 轴)y 像素(坐标为(x,y))

2.绘制路径
2.1 beginPath()
作用:开始绘制新路径
语法:
ctx.beginPath()2.2 closePath()
作用:闭合路径,返回到当前路径的起始点,会从当前点到起始点绘制一条闭合直线。
- 如果图形已经封闭,或者只有一个点,那么此方法不会产生任何效果。
语法:
ctx.closePath()2.3 moveTo(x,y)
作用:将一个新的子路径的起始点移动到点(x,y)
语法:
ctx.moveTo(x,y)2.4 lineTo(x,y)
作用:由当前点到点(x,y)绘制一条直线路径
- 只是路径,不会显示出来
语法:
ctx.lineTo(x,y)2.5 fill()
作用:给当前或已存在的路径围成的区域填充黑色
语法:
ctx.fill()2.6 stroke()
作用:把当前或已存在的路径变成黑色线段
语法:
ctx.stroke()2.7 案例
const ctx=canvas.getContext('2d')
// 绘制线段
ctx.beginPath()
ctx.moveTo(100,100)
ctx.lineTo(200,200)
ctx.closePath()
ctx.stroke()
// 绘制三角形
ctx.beginPath()
ctx.moveTo(300,100)
ctx.lineTo(400,200)
ctx.lineTo(300,200)
ctx.fill()
ctx.closePath()
3.绘制矩形
| 绘制方法 | 描述 |
|---|---|
| rect(x,y,width,height) | 绘制矩形路径,只是路径,并不会显示 |
| fillRect(x,y,width,height) | 绘制一个默认填充黑色的矩形 |
| strokeRect(x,y,width,height) | 绘制一个默认黑色边框的矩形 |
| clearRect(x,y,width,height) | 指定矩形区域的像素都变透明 |
| roundRect(x,y,width,height,radii) | 绘制一个圆角矩形 |
3.1 rect()
作用:绘制一个矩形路径,并不会真实显示
想要显示需要用到fill()填充颜色,或者stroke()方法给边框添加颜色
绘制矩形路径并填充颜色,默认黑色
ctx.rect(10, 10, 100, 100);
ctx.fill();
绘制矩形路径并给边框添加颜色,默认黑色
ctx.rect(10, 10, 100, 100);
ctx.stroke();
3.2 fillRect()
作用:直接创建一个默认填充黑色的矩形
语法:
ctx.fillRect(10, 10, 100, 100);
// 效果等同于
ctx.rect(10, 10, 100, 100);
ctx.fill();
3.3 strokeRect()
作用:直接创建一个默认黑色边框的矩形
语法:
ctx.strokeRect(10, 10, 100, 100);
// 效果等同于
ctx.rect(10, 10, 100, 100);
ctx.stroke();
3.4 clearRect()
作用:指定矩形区域的背景变透明
// 创建黑色矩形
ctx.fillRect(10, 10, 100, 100);
// 使黑色矩形中间指定区域透明
ctx.clearRect(35, 35, 50, 50);
上述代码先是在坐标为(10,10)的位置创建了一个100*100的黑色矩形,然后在位置为(35,35)的位置清除了面积为50*50的矩形
3.5 roundRect()
作用:指定区域绘制圆角矩形
语法:
ctx.roundRect(x, y, width, height, radii)参数:
- x:矩形起点的 x 轴坐标(以像素为单位)。
- y:矩形起点的 y 轴坐标(以像素为单位)。
- width:矩形的宽度。正值在右边,负值在左边。
- height:矩形的高度。正值下降,负值上升。
- radii:一个数字或数组,指定要用于矩形拐角的圆弧半径。有以下几种写法
- 纯数字:四个角
- 数组:
- 一个值:[ 四个角 ]
- 两个值:[ 左上和右下,右上和左下 ]
- 三个值:[ 左上,右上和左下,右下 ]
- 四个值:[ 左上,右上,右下,左下 ]
例子:
const ctx=canvas.getContext('2d')
// 圆角矩形边框
ctx.beginPath()
ctx.roundRect(100,100,100,100,10)
ctx.stroke()
ctx.closePath()
// 圆角实心矩形
ctx.beginPath()
ctx.roundRect(300,100,100,100,[10,0,10])
ctx.fill()
ctx.closePath()
4.绘制弧线
以下方法用于绘制弧形。
arc():arcTo():
4.1 arc()
作用:通过指定圆心和半径绘制弧形。
语法:
// 格式
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)参数:
- x,y:圆心坐标
- radius:半径
- startAngle:圆弧的起始角度
- endAngle:圆弧的终止角度
- anticlockwise表示做图时应该逆时针画(
true)还是顺时针画(false),这个参数用来控制扇形的方向(比如上半圆还是下半圆)。
关于弧度:
整个圆的弧长也就是圆的周长,弧度是弧长与半径的比,所以360°=2Πr/r=2Π
360° = 2Π
180° = Π
1° = Π/180°
1rad° = 180°/Π绘制实心圆:
ctx.arc(50, 50, 30, 0, 2 * Math.PI, true)
绘制空心半圆:
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.moveTo(50, 100)
ctx.arc(100, 100, 50, 0, Math.PI, false)
ctx.stroke()
4.1 arcTo()
作用:通过指定两根切线和半径绘制弧形。
语法:
ctx.arcTo(x1,y1,x2,y2,r)参数:
- x1,y1:第一个控制点的坐标
- x2,y2:第二个控制点的坐标
- r:弧的半径。
注意点:
- 基础点和点1的连线与圆弧相切
- 点1和点2的连线与元素相切

5.绘制椭圆
5.1 ellipse()
作用:绘制一个椭圆
语法:
ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);参数:
- x:椭圆圆心的 x 轴坐标。
- y:椭圆圆心的 y 轴坐标。
- radiusX:椭圆长轴的半径。
- radiusY:椭圆短轴的半径。
- rotation:椭圆的旋转角度,以弧度表示 (非角度度数)。
- startAngle:将要绘制的起始点角度,从 x 轴测量,以弧度表示 (非角度度数)。
- endAngle:椭圆将要绘制的结束点角度,以弧度表示 (非角度度数)。
- anticlockwise :可选布尔值,true是否逆时针绘制,false为顺时针,默认顺时针

例子:
ctx.beginPath()
ctx.ellipse(500,100,50,30,0,0,Math.PI*2)
ctx.stroke()
ctx.closePath()
6.贝塞尔曲线
贝塞尔曲线分为二次贝塞尔曲线和三次贝塞尔曲线
- 二次贝塞尔曲线分为起始点、终点和一个控制点
- 三次贝塞尔曲线分为起始点、终点和两个控制点
- 起始点为绘制上下文当前所在的坐标位置,其他点的坐标为函数的实参传入
6.1 quadraticCurveTo()
作用:绘制二次贝塞尔曲线
语法:
quadraticCurveTo(cpx, cpy, x, y);参数:
- cpx,cpy:控制点的坐标。
- x,y:终点的坐标。
示例:
const can = document.querySelector("#can");
const ctx = can.getContext("2d");
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.quadraticCurveTo(230, 30, 50, 100); // 绘制曲线
ctx.stroke();
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.arc(50, 20, 5, 0, 2 * Math.PI); // 起始点
ctx.arc(50, 100, 5, 0, 2 * Math.PI); // 终点
ctx.fill();
ctx.fillStyle = "red";
ctx.beginPath();
ctx.arc(230, 30, 5, 0, 2 * Math.PI); // 控制点
ctx.fill();
6.2 bezierCurveTo()
作用:绘制三次贝塞尔曲线
语法:
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);参数:
- cp1x,cp1y:第一个控制点的坐标。
- cp2x,cp2y:第二个控制点的坐标。
- x,y:结束点的坐标。
示例:
const can = document.querySelector("#can");
const ctx = can.getContext("2d");
ctx.beginPath();
ctx.moveTo(100, 50);
ctx.bezierCurveTo(150,100,50,150,100,200); // 绘制曲线
ctx.stroke();
ctx.closePath();
// 起始点
ctx.beginPath();
ctx.arc(100, 50, 5, 0, Math.PI * 2);
ctx.fillStyle = "blue";
ctx.fill();
ctx.closePath();
// 终点
ctx.beginPath();
ctx.arc(100, 200, 5, 0, Math.PI * 2);
ctx.fillStyle = "blue";
ctx.fill();
ctx.closePath();
// 控制点1
ctx.beginPath();
ctx.arc(150, 100, 5, 0, Math.PI * 2);
ctx.fillStyle = "red";
ctx.fill();
ctx.closePath();
// 控制点2
ctx.beginPath();
ctx.arc(50, 150, 5, 0, Math.PI * 2);
ctx.fillStyle = "red";
ctx.fill();
ctx.closePath();
