上一集:前端canvas基础(一)
🥞贝塞尔曲线
那么首先我们先来看看维基百科-贝塞尔曲线对贝塞尔曲线的定义是什么样的:
在数学的数值分析领域中,贝塞尔曲线(英语:Bézier curve)是计算机图形学中相当重要的参数曲线。更高维度的广泛化贝塞尔曲线就称作贝兹曲面,其中贝兹三角是一种特殊的实例。
贝塞尔曲线于1962年,由法国工程师皮埃尔·贝兹(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由保尔·德·卡斯特里奥于1959年运用德卡斯特里奥算法开发,以稳定数值的方法求出贝塞尔曲线。
🌭建构贝塞尔曲线
🍪 一、线性曲线
线性贝塞尔曲线函数中的t会经过由P0至P1的B(t)所描述的曲线。例如当t=0.25时,B(t)即一条由点径的四分之一处。就像由0至1的连续t,B(t)描述一条由P0至P1的直线
🍨 二、二次曲线
为建构二次贝塞尔曲线,可以中介点Q0和Q1作为由0至1的t:
由P0至P1的连续点Q0,描述一条线性贝塞尔曲线。
由P1至P2的连续点Q1,描述一条线性贝塞尔曲线。
由Q0至Q1的连续点B(t),描述一条二次贝塞尔曲线
🍯 三、高端曲线
为建构高端曲线,便需要相应更多的中介点。对于三次曲线,可由线性贝塞尔曲线描述的中介点Q0、Q1、Q2,和由二次曲线描述的点R0、R1所建构:
对于四次曲线,可由线性贝塞尔曲线描述的中介点Q0、Q1、Q2、Q3,由二次贝塞尔曲线描述的点R0、R1、R2,和由三次贝塞尔曲线描述的点S0、S1所建构:
五阶贝塞尔曲线
- 看过了维基百科相信你对贝塞尔曲线已经有个大概的认识了,当然,如果还想知道更多一点,你也可以去贝塞尔曲线-百度百科看看。那接下来我们看看在canvas中是怎么应用各种贝塞尔曲线的
canvas应用贝塞尔曲线
主要的API:
- context.quadraticCurveTo(cpx,cpy,x,y) // 创建二次贝塞尔曲线
cpx 贝塞尔控制点的 x 坐标
cpy 贝塞尔控制点的 y 坐标
x 结束点的 x 坐标
y 结束点的 y 坐标 - context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y) // 创建三次贝塞尔曲线
cp1x 第一个贝塞尔控制点的 x 坐标
cp1y 第一个贝塞尔控制点的 y 坐标
cp2x 第二个贝塞尔控制点的 x 坐标
cp2y 第二个贝塞尔控制点的 y 坐标
x 结束点的 x 坐标
y 结束点的 y 坐标
🍧 实例说明
🍦基础
<!DOCTYPE html>
<html>
<head>
<title>贝塞尔基础</title>
<meta charset="utf-8" />
<script type="text/javascript">
function $$(id) {
return document.getElementById(id);
}
window.onload = function () {
var cnv = $$("canvas");
var cxt = cnv.getContext("2d");
//绘制贝塞尔曲线
cxt.moveTo(20, 80);
cxt.quadraticCurveTo(100, 20, 160, 120);//创建二次贝塞尔曲线
cxt.moveTo(200,80)
var cx1 = 200;
var cy1 = 80;
var cx2 = 280;
var cy2 = 150;
var endX = 380;
var endY = 30;
cxt.bezierCurveTo(cx1, cy1, cx2, cy2, endX, endY); //创建三次贝塞尔曲线
cxt.stroke()
}
</script>
</head>
<body>
<canvas id="canvas" width="400" height="150" style="border:1px dashed gray;"></canvas>
</body>
</html>
🍩N叶草
<!DOCTYPE html>
<html>
<head>
<title>N叶草</title>
<meta charset="utf-8" />
<script type="text/javascript">
function $$(id) {
return document.getElementById(id);
}
window.onload = function () {
var cnv = $$("canvas");
var cxt = cnv.getContext("2d");
createLeaf(cxt, 8, cnv.width / 2, cnv.height / 2, 10, 100);
//定义填充颜色为浅绿色
cxt.fillStyle = "#00FF99";
cxt.fill();
}
/*
* createLeaf()用于绘制N叶草
* n:n片
* dx、dy:花朵中心位置的坐标
* size:控制花朵的大小
* length:控制花瓣长度
*/
function createLeaf(cxt, n, dx, dy, size, length) {
cxt.beginPath();
cxt.moveTo(dx, dy + size);
var degree = 2 * Math.PI / n;
for (var i = 1; i < n + 1; i++) {
//计算控制点坐标
var cx1 = Math.sin((i - 1) * degree) * length + dx;
var cy1 = Math.cos((i - 1) * degree) * length + dy;
var cx2 = Math.sin(i * degree) * length + dx;
var cy2 = Math.cos(i * degree) * length + dy;
//计算结束点的坐标
var x = Math.sin(i * degree) * size + dx;
var y = Math.cos(i * degree) * size + dy;
cxt.bezierCurveTo(cx1, cy1, cx2, cy2, x, y);
}
cxt.closePath();
}
</script>
</head>
<body>
<canvas id="canvas" width="200" height="150" style="border:1px dashed gray;"></canvas>
</body>
</html>
- 这里,我们在一条路径中连续定义首尾相连的多段贝塞尔曲线,其中每段三次贝塞尔曲线的起点和终点都落在圆心为(dx,dy)、半径为size的圆弧上,而每段圆弧的两个控制点落在圆心为(dx,dy)、半径为length的圆弧上,于是形成了N叶草的图形。其中,起点、终点和控制点坐标是使用正弦和余弦函数计算出来的。
总的来说,使用二次或三次贝塞尔曲线来绘制一个图形是相当有挑战的,因为这不像在矢量绘图软件Adobe Illustrator(简称AI)里那样有即时的视觉反馈(所见即所得)。所以用它来画复杂图形比较麻烦。但是从理论上来说,任何复杂的图形都可以用贝塞尔曲线绘制出来!这也是贝塞尔曲线强大之处。
🍬最后
关于canvas中贝塞尔曲线的相关信息就先总结到这里,后面有时间会持续更新