線條屬性
1. 前言
線條的屬性有五個,我們前面小節(jié)已經(jīng)學(xué)習(xí)了兩個屬性,分別是表示路徑顏色的 strokeStyle
和表示路徑寬度的 lineWidth
,今天我們繼續(xù)學(xué)習(xí)剩下的三個屬性,lineCap
屬性、lineJoin
屬性和 miterLimit
屬性。
2. 線條屬性匯總
canvas 中和線條有關(guān)的屬性有五個:
-
lineWidth 線條寬度屬性
lineWidth 定義線的寬度(默認(rèn)值為1.0)。 -
strokeStyle 線條描邊屬性
strokeStyle 定義線和形狀邊框的顏色和樣式。 -
lineCap 線條帽子屬性
lineCap 定義上下文中線的端點(diǎn),可以有以下3個值,butt、round 和 square。
-
lineJoin 線條拐角屬性
lineJoin 定義兩條線相交產(chǎn)生的拐角,可將其稱為連接,默認(rèn)在拐角處創(chuàng)建一個填充的三角形,lineJoin 有三個值:miter、bevel 和 round。
-
miterLimit 線條斜接長度限制屬性
miterLimit 屬性需要和 lineJoin 屬性配合使用,而且只有當(dāng)lineJoin=miter
時 miterLimit 才生效。
lineWidth
和 strokeStyle
我們就不展開說明,本小節(jié)我們主要講解后三個屬性。
2.1 lineCap 線條帽子屬性
我們先看一個案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>慕課網(wǎng)Wiki</title>
<style>
#imooc{
border:1px solid #ccc;
}
</style>
</head>
<body>
<canvas id="imooc">您的瀏覽器不支持 HTML5 canvas 標(biāo)簽</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"; // 設(shè)置了lineCap屬性值為 butt
ctx.stroke();
ctx.beginPath();
ctx.moveTo(30,80);
ctx.lineTo(200,80);
ctx.lineCap = "round"; // 設(shè)置了lineCap屬性值為 round
ctx.stroke();
ctx.beginPath();
ctx.moveTo(30,130);
ctx.lineTo(200,130);
ctx.lineCap = "square"; // 設(shè)置了lineCap屬性值為 square
ctx.stroke();
//下面畫兩個基準(zhǔn)線方便觀察
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>
運(yùn)行結(jié)果:

根據(jù)我們兩邊的參考線,我們可以很清楚地看到 lineCap
的三個值的區(qū)別。
- butt:線段的端點(diǎn)是垂直于線段邊緣的平直邊緣。
- round:線段的端點(diǎn)是在線段邊緣處多了一個以線寬為直徑的半圓。
- square:線段的端點(diǎn)是在線段邊緣處多了一個以線寬為長、以一半線寬為寬的矩形。
在使用 lineCap
屬性的時候,我們需要知道一點(diǎn),lineCap 只作用于同一條路徑的兩端,比如一個折線,也只有在折線的兩端才會生效。
內(nèi)容回顧
還記得我們在學(xué)習(xí)【用線條繪制圖形】那一小節(jié)中,列舉了一個在firefox瀏覽器下終點(diǎn)和起點(diǎn)沒有閉合的案例嗎?本小節(jié)我們再用那個案例來說明一下 lineCap
屬性的應(yīng)用。
案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>慕課網(wǎng)Wiki</title>
<style>
#imooc{
border:1px solid #ccc;
}
</style>
</head>
<body>
<canvas id="imooc">您的瀏覽器不支持 HTML5 canvas 標(biāo)簽</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" // 設(shè)置了lineCap屬性值為 square
ctx.stroke();
</script>
</body>
</html>
firefox運(yùn)行結(jié)果:

我們可以看到左上角的缺口已經(jīng)不存在了。
2.2 lineJoin 線條拐角屬性
我們先看一個案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>慕課網(wǎng)Wiki</title>
<style>
#imooc{
border:1px solid #ccc;
}
</style>
</head>
<body>
<canvas id="imooc">您的瀏覽器不支持 HTML5 canvas 標(biāo)簽</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>
運(yùn)行結(jié)果:

根據(jù)上面的運(yùn)行結(jié)果,我們可以很清楚地看到 lineJoin
的三個值的區(qū)別。
- miter:默認(rèn)值,連接處創(chuàng)建一個尖角。
- bevel:連接處創(chuàng)建對角線斜角。
- round:連接處創(chuàng)建一個圓角。
2.3 miterLimit 線條斜接長度限制屬性
想要知道斜接長度限制就得先弄懂什么是斜接長度?斜接長度指的是在兩條線交匯處內(nèi)角和外角之間的距離。我們來看一張圖,下圖中的三個案例中兩條豎線中間的距離表示的就是斜接長度。

我們明白了什么是斜接長度,接下來就開始了解什么是斜接長度限制 miterLimit 了。我們借用預(yù)兆ZeD的一張圖來看一下:

miterLimit = 斜接長度 / 線條寬度(lineWidth) = 1 / sin ( min θ / 2 )。
miterLimit 的默認(rèn)值是10.0,所有的夾角小于 11 度的拐角都會超出這個限制。
如果斜接長度超過 miterLimit 的值,拐角就會以 lineJoin 的 “bevel” 值來顯示。
miterLimit 最小值為1,如果設(shè)定小于1的值則會被忽略。
我們看一個案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>慕課網(wǎng)Wiki</title>
<style>
#imooc{
border:1px solid #ccc;
}
</style>
</head>
<body>
<canvas id="imooc">您的瀏覽器不支持 HTML5 canvas 標(biāo)簽</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"; // 設(shè)置了拐角屬性為尖角
ctx.miterLimit=1.6; // 設(shè)置了斜接長度最大為1.6
ctx.stroke();
</script>
</body>
</html>
運(yùn)行結(jié)果:

miterLimit 的主要目的是防止夾角過小導(dǎo)致繪圖的尖角過長的問題。
3. 總結(jié)
本小節(jié)我們主要總結(jié)了和線條相關(guān)的屬性。