在 Canvas 中,调用 2d context 对象的 beginPath() 函数就会开始一个路径绘制,调用 closePath() 函数结束一个路径绘制。连接路径内的两个点的路径称为子路径。如果终点与起点相连,子路径就称为封闭路径。
我们需要绘制的线段代码,就包含在这两个函数之间。
1 简单直线线段
context.strokeStyle = "black";
context.lineWidth = 10;
context.lineCap = 'square';
context.beginPath();
context.moveTo(200, 100);
context.lineTo(300, 100);
context.stroke();
context.closePath();
运行结果:
首先利用 strokeStyle 属性定义线段颜色,lineWidth 属性定义了线段宽度。然后定义端点类型,即 lineCap 属性。
(1) lineCap 属性
lineCap 属性可定义线的端点类型,有三种端点类型:
值 | 说明 |
---|---|
butt | 默认值,端点是垂直于线段边缘的平直边缘 。 |
round | 在线段边缘处以线宽为直径的半圆。 |
square | 在选段边缘处以线宽为长 、 以一半线宽为宽的矩形。 |
效果如下:
(2)moveTo 方法
moveTo 方法用于指定一条路径开始坐标位置,语法为 context.moveTo(x,y);
。
参数 | 描述 |
---|---|
x | 路径的目标位置的 x 坐标 |
y | 路径的目标位置的 y 坐标 |
(3)lineTo 方法
lineTo 方法用于表示路径按线的方式,移动到指定坐标位置,语法为 context.lineTo(x,y);
,入参与 moveTo 方法相同。
接着调用 context.stroke();
开始绘制路径,最后记得调用 closePath() 关闭该路径。
2 lineJoin 属性
两条线相交时,Canvas会在连接处创建一个填充形状,我们可以使用 lineJoin 来设置这个形状的属性。
值 | 说明 |
---|---|
miter | 默认值,在连接处边缘延长相接 。 |
bevel | 连接处是对角线斜角。 |
round | 连接处是圆。 |
/**
* 绘制路径
* @param context
* @param lineJoin 连接类型
* @param x x 坐标
* @param y y 坐标
*/
function drawPath(context, lineJoin,x, y) {
context.lineWidth = 20;
context.lineJoin = lineJoin;
context.beginPath();
context.moveTo(x, y);
context.lineTo(x * 3, y);
context.lineTo(x * 3, y * 1.5);
context.stroke();
context.closePath();
}
drawPath(context, 'miter',30, 50);
drawPath(context, 'bevel',30, 150);
drawPath(context, 'round',30, 300);
运行结果:
3 左上角怪相
Steve Fulton 举了一个这样的示例:
//圆形端点,斜角连接,在画布左上角
context.strokeStyle = "black";
context.lineWidth = 15;
context.lineJoin = 'bevel';
context.lineCap = 'round';
context.beginPath();
context.moveTo(0, 0);
context.lineTo(25, 0);
context.lineTo(25, 25);
context.stroke();
context.closePath();
//圆形端点,斜角连接,不在画布左上角
context.beginPath();
context.moveTo(10, 50);
context.lineTo(35, 50);
context.lineTo(35, 75);
context.stroke();
context.closePath();
运行结果:
代码中,首先从画布左上角(0,0) 开始绘制,结果发生了一个奇怪的现象 。Canvas 路径在 x 轴和 y 轴方向上都绘制到了起点的外侧,导致第一条线看起来比设置值更细一些。左上角水平部分中,无法看到圆形端点;无法看到对角线斜角,因为它们都被绘制到了屏幕之外的负值坐标区域。
离开画布左上角再进行绘制,就可以解决这个问题。