Canvas基础篇:二次贝塞尔曲线
前言
在我的上一篇文章中 Canvas基础篇:图形绘制,讲述了如何使用Canvas绘制直线和圆弧,本篇文章将讲解如何使用Canvas绘制二次贝塞尔曲线。
二次贝塞尔曲线
定义与概念
二次贝塞尔曲线:通过三个点来定义的一条曲线,这三个点分别代表起始点P1、控制点C1 和终点P2,其本质是一个二元一次方程。二次贝塞尔曲线从起始点开始,逐渐向控制点靠近,然后再从控制点向终点延伸,其形状由这三个点的位置共同决定。
数学表达式
给定起始点P1(x1, y1)、控制点C1(cx1, cy1) 和终点P2(x2, y2),二次贝塞尔曲线的参数方程如下:
B
(
t
)
=
(
1
−
t
)
2
P
1
+
2
t
(
1
−
t
)
C
1
+
t
2
P
2
,其中
t
∈
[
0
,
1
]
。
B(t)=(1−t)^2 P_1 + 2t(1−t) C_1 + t^2 P_2,其中t∈[0,1]。
B(t)=(1−t)2P1+2t(1−t)C1+t2P2,其中t∈[0,1]。
将其展开为极坐标形式如下:
x
(
t
)
=
(
1
−
t
)
2
x
1
+
2
t
(
1
−
t
)
c
x
1
+
t
2
x
2
x(t) = (1−t)^2 x_1 + 2t(1−t) cx_1 + t^2 x_2
x(t)=(1−t)2x1+2t(1−t)cx1+t2x2
y
(
t
)
=
(
1
−
t
)
2
y
1
+
2
t
(
1
−
t
)
c
y
1
+
t
2
y
2
y(t) = (1−t)^2 y_1 + 2t(1−t) cy_1 + t^2 y_2
y(t)=(1−t)2y1+2t(1−t)cy1+t2y2
随着t从0变化到1,(x(t),y(t))就会描绘出二次贝塞尔曲线。当t=0时,B(0)=P1,即曲线的起始点;当t=1时,B(1)=P2,即曲线的终点。
语法说明
在Canvas中,我们可以使用quadraticCurveTo()
方法绘制二次贝塞尔曲线,其语法如下:
quadraticCurveTo(cx1, cy1, x2, y2)
其中(cx1, cy1)代表控制点坐标,(x2, y2)代表终点坐标;对于起点坐标,一般通过moveTo()
方法定义。
二次贝塞尔曲线示例
效果预览
代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>二次贝塞尔曲线</title>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<script>
// 获取 canvas 元素和绘图上下文
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 定义起始点、控制点和终点
const startX = 50;
const startY = 200;
const controlX = 200;
const controlY = 50;
const endX = 350;
const endY = 200;
// 开始绘制路径
ctx.beginPath();
// 移动到起始点
ctx.moveTo(startX, startY);
// 绘制二次贝塞尔曲线
ctx.quadraticCurveTo(controlX, controlY, endX, endY);
// 设置线条样式
ctx.strokeStyle = 'blue';
ctx.lineWidth = 2;
// 绘制路径
ctx.stroke();
</script>
</body>
</html>
二次贝塞尔曲线图解
二次贝塞尔曲线静态图解
上述代码为我们直观的展示了如何在Canvas中绘制一条二次贝塞尔曲线,但是曲线中各个点的位置并没有标明,我们可以通过下面的图解示例为大家更好的理解二次贝塞尔曲线:
上图中,起始点P1到终点P2的曲线即为我们的目标曲线:二次贝塞尔曲线;起点P1到控制点C1和终点P2到控制点C1的两条线,为曲线的辅助线。
上述图示的源码,我放在了 二次贝塞尔曲线静态图解 HTML 代码资源 ,有兴趣可以下载预览!
二次贝塞尔曲线动态图解
当然,上面的二次贝塞尔曲线静态图解可能还是不够直观,在这里我们通过固定起点和终点,动态调整控制点的位置,来更直观地观察二次贝塞尔曲线的变化:
上述图示的源码,我放在了 二次贝塞尔曲线动态图解 HTML 代码资源 ,有兴趣可以下载预览!
二次贝塞尔曲线应用实例
官方实例
在Canvas官方文档中,使用了多个二次贝塞尔曲线来渲染对话气泡,其效果图如下所示:
效果预览
代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>二次贝塞尔曲线官方实例</title>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<script>
// 获取 canvas 元素和绘图上下文
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(75, 25);
ctx.quadraticCurveTo(25, 25, 25, 62.5);
ctx.quadraticCurveTo(25, 100, 50, 100);
ctx.quadraticCurveTo(50, 120, 30, 125);
ctx.quadraticCurveTo(60, 120, 65, 100);
ctx.quadraticCurveTo(125, 100, 125, 62.5);
ctx.quadraticCurveTo(125, 25, 75, 25);
ctx.stroke();
</script>
</body>
</html>
自定义实例:波浪线
上述我们引入了Canvas官方文档中的一个实例,这里我们自定义一个实例:使用二次贝塞尔曲线实现一个波浪线,其效果图如下所示:
效果预览
代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>二次贝塞尔曲线自定义实例-波浪线</title>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<script>
// 获取 canvas 元素和绘图上下文
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const startX = 0;
const startY = canvas.height / 2;
const waveHeight = 50;
const waveLength = 100;
const numWaves = Math.ceil(canvas.width / waveLength);
ctx.beginPath();
ctx.moveTo(startX, startY);
for (let i = 0; i < numWaves; i++) {
const controlX = startX + waveLength * (i + 0.5);
const controlY = startY + (i % 2 === 0 ? waveHeight : -waveHeight);
const endX = startX + waveLength * (i + 1);
const endY = startY;
ctx.quadraticCurveTo(controlX, controlY, endX, endY);
}
ctx.stroke();
</script>
</body>
</html>
结语
本文主要介绍了二次贝塞尔曲线的相关内容,包括曲线定义、语法、图形示例和图解,在文章最后给出了两个二次贝塞尔曲线的应用实例。对于文章中错误的地方或者有任何问题,欢迎在评论区留言分享!