线条属性

1. 前言

线条的属性有五个,我们前面小节已经学习了两个属性,分别是表示路径颜色的 strokeStyle 和表示路径宽度的 lineWidth,今天我们继续学习剩下的三个属性,lineCap 属性、lineJoin 属性和 miterLimit 属性。

2. 线条属性汇总

canvas 中和线条有关的属性有五个:

  1. lineWidth 线条宽度属性
    lineWidth 定义线的宽度(默认值为1.0)。

  2. strokeStyle 线条描边属性
    strokeStyle 定义线和形状边框的颜色和样式。

  3. lineCap 线条帽子属性

    lineCap 定义上下文中线的端点,可以有以下3个值,butt、round 和 square。

  4. lineJoin 线条拐角属性

    lineJoin 定义两条线相交产生的拐角,可将其称为连接,默认在拐角处创建一个填充的三角形,lineJoin 有三个值:miter、bevel 和 round。

  5. miterLimit 线条斜接长度限制属性
    miterLimit 属性需要和 lineJoin 属性配合使用,而且只有当 lineJoin=miter 时 miterLimit 才生效。

lineWidthstrokeStyle 我们就不展开说明,本小节我们主要讲解后三个属性。

2.1 lineCap 线条帽子属性

我们先看一个案例:

实例演示
预览 复制
复制成功!
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>慕课网Wiki</title>
    <style>
        #imooc{
            border:1px solid #ccc;
        }
    </style>
</head>
<body>
	
	<canvas id="imooc">您的浏览器不支持 HTML5 canvas 标签</canvas>
	
	<script>
		const canvas = document.getElementById('imooc');
		const ctx = canvas.getContext('2d');
		
		ctx.lineWidth = 20;
		ctx.strokeStyle = "#456795"
		
		ctx.beginPath();
		ctx.moveTo(30,30);
		ctx.lineTo(200,30);
		ctx.lineCap = "butt";  // 设置了lineCap属性值为 butt
		ctx.stroke();
		
		ctx.beginPath();
		ctx.moveTo(30,80);
		ctx.lineTo(200,80);
		ctx.lineCap = "round";  // 设置了lineCap属性值为 round
		ctx.stroke();
		
		ctx.beginPath();
		ctx.moveTo(30,130);
		ctx.lineTo(200,130);
		ctx.lineCap = "square";  // 设置了lineCap属性值为 square
		ctx.stroke();
		
		//下面画两个基准线方便观察
		ctx.lineWidth = 1;
		ctx.strokeStyle = "red";
		
		ctx.beginPath();
		ctx.moveTo(30,0);
		ctx.lineTo(30,180);
		ctx.moveTo(200,0);
		ctx.lineTo(200,180);
		ctx.stroke();
		
	</script>
</body>
运行案例 点击 "运行案例" 可查看在线运行效果

运行结果:

根据我们两边的参考线,我们可以很清楚地看到 lineCap 的三个值的区别。

  • butt:线段的端点是垂直于线段边缘的平直边缘。
  • round:线段的端点是在线段边缘处多了一个以线宽为直径的半圆。
  • square:线段的端点是在线段边缘处多了一个以线宽为长、以一半线宽为宽的矩形。

在使用 lineCap 属性的时候,我们需要知道一点,lineCap 只作用于同一条路径的两端,比如一个折线,也只有在折线的两端才会生效。

内容回顾

还记得我们在学习【用线条绘制图形】那一小节中,列举了一个在firefox浏览器下终点和起点没有闭合的案例吗?本小节我们再用那个案例来说明一下 lineCap 属性的应用。

案例:

实例演示
预览 复制
复制成功!
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>慕课网Wiki</title>
    <style>
        #imooc{
            border:1px solid #ccc;
        }
    </style>
</head>
<body>
	
	<canvas id="imooc">您的浏览器不支持 HTML5 canvas 标签</canvas>
	
	<script>
		const canvas = document.getElementById('imooc');
		const ctx = canvas.getContext('2d');
		
		ctx.moveTo(10,10);
		ctx.lineTo(10,100);
		ctx.lineTo(200,100);
		ctx.lineTo(200,10);
		ctx.lineTo(10,10);
		ctx.strokeStyle="blue"
		ctx.lineWidth=8
		
		ctx.lineCap="square"  // 设置了lineCap属性值为 square
		
		ctx.stroke();
	</script>
</body>
</html>
运行案例 点击 "运行案例" 可查看在线运行效果

firefox运行结果:

我们可以看到左上角的缺口已经不存在了。

2.2 lineJoin 线条拐角属性

我们先看一个案例:

实例演示
预览 复制
复制成功!
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>慕课网Wiki</title>
    <style>
        #imooc{
            border:1px solid #ccc;
        }
    </style>
</head>
<body>
	
	<canvas id="imooc">您的浏览器不支持 HTML5 canvas 标签</canvas>
	
	<script>
		const canvas = document.getElementById('imooc');
		const ctx = canvas.getContext('2d');
		
		
		ctx.strokeStyle="#456795";
		ctx.lineWidth=18;
		
		//绘制第一条折线
		ctx.beginPath()       
		ctx.moveTo(30,20);
		ctx.lineTo(100,75);
		ctx.lineTo(30,130);
		ctx.lineJoin="miter";
		ctx.stroke();
		
		//绘制第二条折线
		ctx.beginPath()       
		ctx.moveTo(80,20);
		ctx.lineTo(150,75);
		ctx.lineTo(80,130);
		ctx.lineJoin="bevel";
		ctx.stroke();
		
		//绘制第三条折线
		ctx.beginPath()     
		ctx.moveTo(130,20);
		ctx.lineTo(200,75);
		ctx.lineTo(130,130);
		ctx.lineJoin="round";
		ctx.stroke();
		
	</script>
</body>
</html>
运行案例 点击 "运行案例" 可查看在线运行效果

运行结果:

根据上面的运行结果,我们可以很清楚地看到 lineJoin 的三个值的区别。

  • miter:默认值,连接处创建一个尖角。
  • bevel:连接处创建对角线斜角。
  • round:连接处创建一个圆角。

2.3 miterLimit 线条斜接长度限制属性

想要知道斜接长度限制就得先弄懂什么是斜接长度?斜接长度指的是在两条线交汇处内角和外角之间的距离。我们来看一张图,下图中的三个案例中两条竖线中间的距离表示的就是斜接长度。

我们明白了什么是斜接长度,接下来就开始了解什么是斜接长度限制 miterLimit 了。我们借用预兆ZeD的一张图来看一下:

miterLimit = 斜接长度 / 线条宽度(lineWidth) = 1 / sin ( min θ / 2 )。
miterLimit 的默认值是10.0,所有的夹角小于 11 度的拐角都会超出这个限制。
如果斜接长度超过 miterLimit 的值,拐角就会以 lineJoin 的 “bevel” 值来显示。
miterLimit 最小值为1,如果设定小于1的值则会被忽略。

我们看一个案例:

实例演示
预览 复制
复制成功!
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>慕课网Wiki</title>
    <style>
        #imooc{
            border:1px solid #ccc;
        }
    </style>
</head>
<body>
	
	<canvas id="imooc">您的浏览器不支持 HTML5 canvas 标签</canvas>
	
	<script>
		const canvas = document.getElementById('imooc');
		const ctx = canvas.getContext('2d');
		
		
		ctx.strokeStyle="#456795";
		ctx.lineWidth=18;
		
		ctx.beginPath()       
		ctx.moveTo(30,20);
		ctx.lineTo(100,75);
		ctx.lineTo(30,130);
		
		ctx.lineJoin="miter";  // 设置了拐角属性为尖角
		ctx.miterLimit=1.6;    // 设置了斜接长度最大为1.6
		
		ctx.stroke();
		
	</script>
</body>
</html>
运行案例 点击 "运行案例" 可查看在线运行效果

运行结果:

miterLimit 的主要目的是防止夹角过小导致绘图的尖角过长的问题。

3. 总结

本小节我们主要总结了和线条相关的属性。