Skip to content

二、基本图形绘制

1.栅格

在我们开始画图之前,我们需要了解一下画布栅格(canvas grid)以及坐标空间。

如下图所示,canvas 元素默认被网格所覆盖。通常来说网格中的一个单元相当于 canvas 元素中的一像素。栅格的起点为左上角(坐标为(0,0))。所有元素的位置都相对于原点定位。所以图中蓝色方形左上角的坐标为距离左边(X 轴)x 像素,距离上边(Y 轴)y 像素(坐标为(x,y))

image-20240521170653385

2.绘制路径

2.1 beginPath()

作用开始绘制新路径

语法

js
ctx.beginPath()

2.2 closePath()

作用:闭合路径,返回到当前路径的起始点,会从当前点到起始点绘制一条闭合直线

  • 如果图形已经封闭,或者只有一个点,那么此方法不会产生任何效果。

语法

js
ctx.closePath()

2.3 moveTo(x,y)

作用:将一个新的子路径的起始点移动到点(x,y)

语法

js
ctx.moveTo(x,y)

2.4 lineTo(x,y)

作用:由当前点到点(x,y)绘制一条直线路径

  • 只是路径,不会显示出来

语法

js
ctx.lineTo(x,y)

2.5 fill()

作用:给当前或已存在的路径围成的区域填充黑色

语法

js
ctx.fill()

2.6 stroke()

作用:把当前或已存在的路径变成黑色线段

语法

js
ctx.stroke()

2.7 案例

js
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()

image-20230711194922093

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()方法给边框添加颜色

绘制矩形路径并填充颜色,默认黑色

js
ctx.rect(10, 10, 100, 100);
ctx.fill();

image-20240521170708542

绘制矩形路径并给边框添加颜色,默认黑色

js
ctx.rect(10, 10, 100, 100);
ctx.stroke();

image-20240521170715975

3.2 fillRect()

作用:直接创建一个默认填充黑色的矩形

语法

js
ctx.fillRect(10, 10, 100, 100);

// 效果等同于
ctx.rect(10, 10, 100, 100);
ctx.fill();

image-20240521170722459

3.3 strokeRect()

作用:直接创建一个默认黑色边框的矩形

语法

js
ctx.strokeRect(10, 10, 100, 100);
// 效果等同于
ctx.rect(10, 10, 100, 100);
ctx.stroke();

image-20240521170731266

3.4 clearRect()

作用:指定矩形区域的背景变透明

js
// 创建黑色矩形
ctx.fillRect(10, 10, 100, 100);

// 使黑色矩形中间指定区域透明
ctx.clearRect(35, 35, 50, 50);

image-20240521170736270

上述代码先是在坐标为(10,10)的位置创建了一个100*100的黑色矩形,然后在位置为(35,35)的位置清除了面积为50*50的矩形

3.5 roundRect()

作用:指定区域绘制圆角矩形

语法

js
ctx.roundRect(x, y, width, height, radii)

参数

  • x:矩形起点的 x 轴坐标(以像素为单位)。
  • y:矩形起点的 y 轴坐标(以像素为单位)。
  • width:矩形的宽度。正值在右边,负值在左边。
  • height:矩形的高度。正值下降,负值上升。
  • radii:一个数字或数组,指定要用于矩形拐角的圆弧半径。有以下几种写法
    • 纯数字:四个角
    • 数组:
      • 一个值:[ 四个角 ]
      • 两个值:[ 左上和右下,右上和左下 ]
      • 三个值:[ 左上,右上和左下,右下 ]
      • 四个值:[ 左上,右上,右下,左下 ]

例子

js
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()

image-20240521170742832

4.绘制弧线

以下方法用于绘制弧形。

  • arc()
  • arcTo()

4.1 arc()

作用:通过指定圆心和半径绘制弧形。

语法

js
// 格式
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)

参数

  • xy:圆心坐标
  • radius:半径
  • startAngle:圆弧的起始角度
  • endAngle:圆弧的终止角度
  • anticlockwise表示做图时应该逆时针画(true)还是顺时针画(false),这个参数用来控制扇形的方向(比如上半圆还是下半圆)。

关于弧度

整个圆的弧长也就是圆的周长,弧度是弧长与半径的比,所以360°=2Πr/r=2Π

360° = 2Π
180° = Π
1° = Π/180°
1rad° = 180°/Π

绘制实心圆

js
ctx.arc(50, 50, 30, 0, 2 * Math.PI, true)

image-20240521170749355

绘制空心半圆:

js
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()

image-20240521170754640

4.1 arcTo()

作用:通过指定两根切线和半径绘制弧形。

语法

js
ctx.arcTo(x1,y1,x2,y2,r)

参数

  • x1,y1:第一个控制点的坐标
  • x2,y2:第二个控制点的坐标
  • r:弧的半径。

注意点

  • 基础点和点1的连线与圆弧相切
  • 点1和点2的连线与元素相切

image-20240521170800537

5.绘制椭圆

5.1 ellipse()

作用:绘制一个椭圆

语法

js
ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);

参数

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

image-20230711215438288

例子

js
ctx.beginPath()
ctx.ellipse(500,100,50,30,0,0,Math.PI*2)
ctx.stroke()
ctx.closePath()

image-20230711214839655

6.贝塞尔曲线

贝塞尔曲线分为二次贝塞尔曲线和三次贝塞尔曲线

  • 二次贝塞尔曲线分为起始点、终点和一个控制点
  • 三次贝塞尔曲线分为起始点、终点和两个控制点
  • 起始点为绘制上下文当前所在的坐标位置,其他点的坐标为函数的实参传入

6.1 quadraticCurveTo()

作用:绘制二次贝塞尔曲线

语法

js
quadraticCurveTo(cpx, cpy, x, y);

参数

  • cpx,cpy:控制点的坐标。
  • x,y:终点的坐标。

示例

js
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();

image-20230713155930196

6.2 bezierCurveTo()

作用:绘制三次贝塞尔曲线

语法

js
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);

参数

  • cp1xcp1y:第一个控制点的坐标。
  • cp2xcp2y:第二个控制点的坐标。
  • xy:结束点的坐标。

示例

js
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();

image-20230713160852784

MIT Licensed