绘制圆弧

绘制圆弧

1. 前言

上一节我们学习了利用 arc 方法绘制一个标准的圆或者圆弧,arc 方法依托于圆心、半径、起始角和结束角绘制圆弧,今天我们再来学习一下绘制圆弧的方法 arcTo

2. 利用 arcTo 方法绘制弧线

arcTo() 是利用两条相交切线来确定圆弧的位置,开始前我们先要搞懂切线的几个知识点。

如何确定切线?
我们都知道两点确定一条直线,这里两条直线相交处有一个交点,交点是两条线共用的一个点,所以我们只需要三个点就能确定两条切线。

根据切线如何确定圆心?
切线的性质有:
(1)切线和圆只有一个公共点。
(2)切线和圆心的距离等于圆的半径。
(3)切线垂直于经过切点的半径。
(4)经过圆心垂直于切线的直线必过切点。
(5)经过切点垂直于切线的直线必过圆心。

我们根据切线的垂直线必过圆心,即可确定圆心。

我们来看一张图片:

上图中,只要我们确定了 PA、PB 这两条切线和圆的半径 OA,即可确定 AB 这条弧线。上图中,我们沿着 OP 延长线移动 O 点的位置,即可得到半径不同的圆,也就得到了不同的 AB 弧线。

到这里我们明白了:

  • 有三个点就可以确定两条切线。
  • 有圆的半径就可以确定切线间的一条弧线。

arcTo 就是利用上面的原理来绘制弧线的。arcTo 方法有5个参数,前两个参数表示的是上图中 P 点的坐标,也就是切线的交点,第3个和第4个参数表示 PB 切线上的任意一个坐标点,第5个参数表示的是上图中 OA 的长度,也就是绘制圆的半径。

特别注意:
第3、4个参数表示的点不是切点!
第3、4个参数表示的点不是切点!
第3、4个参数表示的点不是切点!

arcTo 方法的参数中只有两个点和一个半径,我们前面讲到要绘制弧线,必须是三个点,那第一个点哪儿去了呢?其实第一个点就是当前画布中笔触所在的位置,也就是当前画布中已经绘制的路径的终点。

先看整体案例:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>网Wiki</title>
    <style>
        #imooc{
            border:px solid #ccc;
        }
    </style>
</head>
<body>
	
	<canvas id="imooc">您的浏览器不支持 HTML5 canvas 标签</canvas>
	
	<script>
		const canvas = document.getElementById('imooc');
		canvas.width=
		canvas.height=
		const ctx = canvas.getContext('2d');
		
		// 绘制弧线
		ctx.beginPath();
		ctx.moveTo(,);
		ctx.arcTo(,, ,, );  //调用了绘制圆的函数
		ctx.strokeStyle = "#456795";
		ctx.lineWidth = ;
		ctx.stroke();
		
		// ==============一下内容为复制内容=================
		// 绘制切线
		ctx.beginPath()
		ctx.strokeStyle="#ccc";
		ctx.lineWidth=;
		ctx.moveTo(,);
		ctx.lineTo(,);
		ctx.lineTo(,);
		ctx.stroke();
		
		//绘制P点
		ctx.beginPath();
		ctx.arc(,,,, *Math.PI)
		ctx.fillStyle = "#000"
		ctx.fill()
		
		//绘制A点
		ctx.beginPath();
		ctx.arc(,,,, *Math.PI)
		ctx.fillStyle = "#000"
		ctx.fill()
		
		
		//绘制B点
		ctx.beginPath();
		ctx.arc(,,,, *Math.PI)
		ctx.fillStyle = "#000"
		ctx.fill()
		
		//绘制切点
		ctx.beginPath();
		ctx.arc(,,,, *Math.PI)
		ctx.fillStyle = "yellow"
		ctx.fill()
		
		
		//绘制切点
		ctx.beginPath();
		ctx.arc(,,,, *Math.PI)
		ctx.fillStyle = "yellow"
		ctx.fill()
		
		//绘制圆心 O 点
		ctx.beginPath();
		ctx.arc(,,,, *Math.PI)
		ctx.fillStyle = "blue"
		ctx.fill()
		
		//绘制辅助圆
		ctx.beginPath();
		ctx.lineWidth = ;
		ctx.strokeStyle="#ccc"
		ctx.arc(,,,, *Math.PI)
		ctx.stroke()
		
	</script>
</body>
</html>

运行结果:

我们对上面的绘制弧线代码做拆分讲解:

  1. 开始一个新路径。

    ctx.beginPath();
    
  2. 确定第一个坐标点 A 点,A 点是当前已有路径的终点。

    ctx.moveTo(40,40);
    

    我换一个写法:

    ctx.moveTo(40,0);
    ctx.lineTo(80,40);
    

    这时候 A 点的位置就变成了 (80, 40)。

  3. 根据切线交点、第二条切线上的某个点和半径开始绘制弧线。

    ctx.arcTo(260,40, 260,200, 60);  //调用了绘制圆的函数
    

    这里需要注意三点:
    (1) A 点和 PA 切线的切点会被自动连接起来,但是 PB 切线上的切点和 B点不会自动连接起来。

    (2) A 点肯定在路径上,B 点不一定在路径上。
    (3) 切点由 canvas 自动计算。

  4. 设置绘制样式以及开始描边。

    ctx.strokeStyle = "#456795";
    ctx.lineWidth = 4;
    ctx.stroke();
    

我们从案例中可以看到,绘制一个圆形路径只需要调用一个函数即可,arc 方法和我们之前学过的 rect 绘制矩形的方法类似,也是绘制了一个路径,我们后续对路径的描边或者填充依然是需要调用 stroke 或者 fill 方法的。

3. 绘制圆角矩形

直接看案例:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>网Wiki</title>
    <style>
        #imooc{
            border:px solid #ccc;
        }
    </style>
</head>
<body>
	
	<canvas id="imooc">您的浏览器不支持 HTML5 canvas 标签</canvas>
	
	<script>
		const canvas = document.getElementById('imooc');
		canvas.width=
		canvas.height=
		const ctx = canvas.getContext('2d');
		
		// 绘制圆角矩形
		ctx.beginPath();
		ctx.moveTo(,);
		ctx.arcTo(,, ,, );
		ctx.arcTo(,, ,, ); 
		ctx.arcTo(,, ,, ); 
		ctx.arcTo(,, ,,)
	
		ctx.strokeStyle = "#456795";
		ctx.lineWidth = ;
		ctx.stroke();
		ctx.fillStyle = "#ccc";
		ctx.fill();
	</script>
</body>
</html>

运行结果:

4. arcarcTo 对比

相同点:

  1. 都是绘制圆弧。

不同点:

  1. arc 通过圆心 + 半径 + 弧度绘制圆弧, arcTo 是根据切线 + 半径绘制圆弧。
  2. arc 可以绘制任意弧度的圆弧,arcTo 只能绘制小于180度的圆弧。
  3. arc 可以不需要起点,可以直接绘制, arcTo 绘制前必须存在一个端点。
  4. arc 可以设置绘制方向,arcTo 只能由切线控制。

5. 方法整理

本小节中我们使用到一个新的绘制圆弧的方法 arcTo

5.1 arcTo()方法

arcTo 方法作用是绘制一个切线为 PA 和 PB、半径为 r 的圆弧,圆弧由切线控制。

变量说明:

变量名 类型 是否必须 说明
x1 Number 切线交点P的X坐标。
y1 Number 切线交点P的Y坐标。
x2 Number 指PB切线的任意一点的X坐标。
y2 Number 指PB切线的任意一点的Y坐标。
r Number 圆的半径。

6. 总结

本小节我们主要学习了利用 arcTo 方法绘制圆弧,本节主要难点在于理解绘制的原理,希望同学们多多练习加深记忆。