Canvas基础篇:路径绘制
路径绘制
在之前的文章 Canvas基础篇:绘制矩形 中,讲述了如何绘制矩形。本篇文章将讲述如何通过路径绘制图形,包括路径绘制模式和常用API。
路径绘制模式
矩形绘制时,分为边框矩形 strokeRect()
、填充矩形 fillRect()
、清除矩形 clearRect()
三种模式。相比于矩形绘制,路径绘制只有边框模式stroke()
和 填充模式 fill()
两种,其具体差别在后面的描述中会详细讲解。
路径绘制四步走:
- 使用
beginPath()
新建一条路径,并使用moveTo(x, y)
确定绘图起点的横/纵坐标。 - 使用画图API去绘图,如linrTo(x, y)绘制一条直线,具体的绘图API在之后的文章中会详细介绍。
- 使用
closePath()
封闭路径,该步骤可以省略,具体情形在后面会详细介绍。 - 使用边框模式
stroke()
或 填充模式fill()
渲染图形。
beginPath()
beginPath()用来新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。我们可以看以下两个示例:
不加beginPath()的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>不带beginPath绘图</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 绘制第一个矩形
ctx.rect(50, 50, 100, 100);
ctx.fillStyle = 'red';
ctx.fill();
// 绘制第二个矩形
ctx.rect(200, 50, 100, 100);
ctx.fillStyle = 'green';
ctx.fill();
</script>
</body>
</html>
不加beginPath()的效果预览
在代码中,我们为两个矩形分别设置了red和blue两个不同fillStyle,但实际绘制中,两个矩形都是使用的green。其原因就是,没有加beginPath(),导致Canvas认为两个矩形是在同一绘制路径中,存在相同属性就会覆盖。下面我们来看看使用beginPath()的效果:
加beginPath()的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>带beginPath的绘图</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 绘制第一个矩形
ctx.beginPath();
ctx.rect(50, 50, 100, 100);
ctx.fillStyle = 'red';
ctx.fill();
// 绘制第二个矩形,使用 beginPath()
ctx.beginPath();
ctx.rect(200, 50, 100, 100);
ctx.fillStyle = 'green';
ctx.fill();
</script>
</body>
</html>
加beginPath()的效果预览
从上图可以看出,两个矩形各自使用自己的属性,为两个独立的图形,互不干扰。
closePath()
closePath()通过绘制一条从当前点到开始点的直线来闭合图形。上述两个示例中,大家可能发现了,我在使用beginPath()
后,并没有使用closePath()
,这是为什么呢?因为closePath()
在绘图中并不是必须的,主要有以下两种情形:
- 图形已经闭合了,即当前点为开始点,该函数什么也不做,可以省略。
- 当我们调用 fill() 时,所有没有闭合的形状都会自动填充闭合,所以你需要再调用 closePath() ,也可以省略。
fill()
fill()通过填充路径的内容区域生成实心的图形,下面我们可以通过绘制一个三角形,来体会fill()的实际效果:
fill绘制三角形代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>fill绘制三角形</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(50, 50)
ctx.lineTo(50, 100)
ctx.lineTo(100, 100)
ctx.fill();
</script>
</body>
</html>
fill绘制三角形效果预览
从上述代码和效果图中,我们可以看出:代码并没有添加 closePath()
,但 fill()
自动填充路径的内容区域,生成了一个实心三角形。
stroke()
stroke()通过线条来绘制图形轮廓,我们可以通过绘制一个三角形,来体会stroke()的实际效果:
不带closePath()的代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>stroke绘制三角形-不带closePath</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(50, 50)
ctx.lineTo(50, 100)
ctx.lineTo(100, 100)
ctx.stroke();
</script>
</body>
</html>
不带closePath()的效果预览
从上图可以看到,页面中只有两条折线,并没有形成三角性。
带closePath()的代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>stroke绘制三角形-带closePath</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
ctx.beginPath();
ctx.moveTo(50, 50)
ctx.lineTo(50, 100)
ctx.lineTo(100, 100)
ctx.closePath()
ctx.stroke()
</script>
</body>
</html>
带closePath()的效果预览
从上我们可以看出,使用closePath()后,绘图最后一个点会直接和第一个点相连闭合。
结语
本文主要介绍了Canvas中路径绘制的主要步骤,对于文章中错误的地方或者有任何问题,欢迎在评论区留言分享!