上一篇文章说矩形是 HTML5 Canvas 提供的唯一原生图形绘制方法,这种说法不完全对,因为 Google 浏览器提供了绘制椭圆形的方法。

绘制椭圆形

绘制方法:

// 绘制椭圆形
// x:椭圆圆心的 x 轴坐标。
// y:椭圆圆心的 y 轴坐标。
// radiusX:椭圆长轴的半径。
// radiusY:椭圆短轴的半径。
// rotation:椭圆的旋转角度,以弧度表示(非角度度数)。
// startAngle:将要绘制的起始点角度,从 x 轴测量,以弧度表示(非角度度数)。
// endAngle:椭圆将要绘制的结束点角度,以弧度表示(非角度度数)。
// anticlockwise:可选,如果为 true,逆时针方向绘制椭圆 (逆时针), 反之顺时针方向绘制。
context.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);

所有的图形都需要通过路径绘制,而 HTML5 Canvas 支持一种原生的图形绘制 — 矩形,并且只支持这一种。

关于绘制矩形的方法:

// 创建矩形
// x:矩形左上角的 x 坐标
// y:矩形左上角的 y 坐标
// width:矩形的宽度,以像素计
// height:矩形的高度,以像素计
context.rect(x, y, width, height)

// 绘制一个已填充的矩形
// x:矩形左上角的 x 坐标
// y:矩形左上角的 y 坐标
// width:矩形的宽度,以像素计
// height:矩形的高度,以像素计
context.fillRect(x, y, width, height)

// 绘制一个矩形的边框
// x:矩形左上角的 x 坐标
// y:矩形左上角的 y 坐标
// width:矩形的宽度,以像素计
// height:矩形的高度,以像素计
context.strokeRect(x, y, width, height)

// 清除指定的矩形区域,然后这块区域会变的完全透明。
// x:矩形左上角的 x 坐标
// y:矩形左上角的 y 坐标
// width:矩形的宽度,以像素计
// height:矩形的高度,以像素计
context.clearRect(x, y, width, height);

关于图形的理解

一条或者多条路径相交产生闭环时就会形成一个图形。所以,图形的基础元素是路径,而在 canvas 中画出图形就是将路径闭合,然后通过描边或填充路径区域来渲染图形。

闭合路径

闭合方法:

// 创建从当前点到开始点的路径
context.closePath();

闭合路径就是创建当前路径中的结束点与开始点的路径。使用路径中的一个例子来做闭合测试...

什么是贝塞尔曲线?

贝塞尔曲线就是这样的一条曲线,它是依据四个位置任意的点坐标绘制出的一条光滑曲线。在历史上,研究贝塞尔曲线的人最初是按照已知曲线参数方程来确定四个点的思路设计出这种矢量曲线绘制法。

贝塞尔曲线的有趣之处更在于它的“皮筋效应”,也就是说,随着点有规律地移动,曲线将产生皮筋伸引一样的变换,带来视觉上的冲击。

1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名是为贝塞尔曲线。

关于路径的理解

在二维世界中,一个移动的点会形成一条线,而这个点移动的过程就是路径,路径可以是笔直的,也可以是弯曲的。在 canvas 中画出路径的过程大致如下:

1.创建一个路径起点
2.创建从起点到指定点的路径
3.通过笔触将路径渲染出来

使用到的方法:

// 起始一条路径,或重置当前路径
context.beginPath()

// 把路径移动到画布中的指定点 (x,y) ,不创建线条
context.moveTo(x, y)

// 添加一个新点,然后在画布中创建从该点到最后指定点的线条
context.lineTo(x, y)

// 创建弧/曲线
// x:圆的中心的 x 坐标。
// y:圆的中心的 y 坐标。
// r:圆的半径。
// sAngle:起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)。
// eAngle:结束角,以弧度计。
// counterclockwise:可选。规定应该逆时针还是顺时针绘图。false = 顺时针,true = 逆时针。
context.arc(x, y, r, sAngle, eAngle, counterclockwise);

// 创建两切线之间的弧/曲线
// x1:弧的起点的 x 坐标
// y1:弧的起点的 y 坐标
// x2:弧的终点的 x 坐标
// y2:弧的终点的 y 坐标
// r:弧的半径
context.arcTo(x1, y1, x2, y2, radius)

// 绘制已定义的路径
context.stroke()