ZetCode

JavaScript Canvas lineCap 教程

最后修改于 2025 年 4 月 3 日

在本文中,我们将探讨 JavaScript 中的 Canvas lineCap 属性。此属性控制 HTML Canvas 图形中线条末端的渲染方式。理解 lineCap 对于创建精美的图形至关重要。

基本定义

lineCap 属性决定了绘制线条端点的形状。它会影响使用 stroke()、strokeRect() 和其他描边方法绘制的线条。有三种可能的值:butt、round 和 square。

默认值为 butt,它会创建垂直于线条的平坦边缘。Round 会添加半圆形端点,而 square 会添加超出线条长度的方形端点。

基本的 lineCap 演示

此示例显示了应用于简单线条的所有三种 lineCap 值。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Basic lineCap</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Guide line to show actual length
    ctx.strokeStyle = 'lightgray';
    ctx.lineWidth = 1;
    ctx.beginPath();
    ctx.moveTo(50, 50);
    ctx.lineTo(350, 50);
    ctx.stroke();
    
    // Butt lineCap (default)
    ctx.strokeStyle = 'red';
    ctx.lineWidth = 15;
    ctx.lineCap = 'butt';
    ctx.beginPath();
    ctx.moveTo(50, 50);
    ctx.lineTo(150, 50);
    ctx.stroke();
    
    // Round lineCap
    ctx.strokeStyle = 'blue';
    ctx.lineCap = 'round';
    ctx.beginPath();
    ctx.moveTo(200, 50);
    ctx.lineTo(300, 50);
    ctx.stroke();
    
    // Square lineCap
    ctx.strokeStyle = 'green';
    ctx.lineCap = 'square';
    ctx.beginPath();
    ctx.moveTo(350, 50);
    ctx.lineTo(450, 50);
    ctx.stroke();
</script>

</body>
</html>

此示例绘制了三条具有不同 lineCap 值的水平线。一条浅灰色参考线显示了每个线段的实际长度。

红色线条使用 butt(默认),蓝色使用 round,绿色使用 square。请注意 round 和 square 如何超出线条的端点。

lineCap 与虚线

此示例演示了 lineCap 如何影响虚线。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>lineCap with Dashes</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Set dash pattern
    ctx.setLineDash([20, 10]);
    
    // Butt lineCap
    ctx.strokeStyle = 'red';
    ctx.lineWidth = 10;
    ctx.lineCap = 'butt';
    ctx.beginPath();
    ctx.moveTo(50, 50);
    ctx.lineTo(350, 50);
    ctx.stroke();
    
    // Round lineCap
    ctx.strokeStyle = 'blue';
    ctx.lineCap = 'round';
    ctx.beginPath();
    ctx.moveTo(50, 100);
    ctx.lineTo(350, 100);
    ctx.stroke();
    
    // Square lineCap
    ctx.strokeStyle = 'green';
    ctx.lineCap = 'square';
    ctx.beginPath();
    ctx.moveTo(50, 150);
    ctx.lineTo(350, 150);
    ctx.stroke();
</script>

</body>
</html>

这里我们将相同的虚线模式 ([20,10]) 应用于三条具有不同 lineCap 值的线条。该模式表示 20 像素的实线和 10 像素的间隙。

红色线条(butt)的每个实线端点都是尖锐的。蓝色线条(round)的端点是圆形的,而绿色线条(square)的端点是方形的,超出了实线的长度。

lineCap 与弧线

此示例显示了 lineCap 如何影响开放弧线和圆形。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>lineCap with Arcs</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="300"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Butt lineCap arc
    ctx.strokeStyle = 'red';
    ctx.lineWidth = 15;
    ctx.lineCap = 'butt';
    ctx.beginPath();
    ctx.arc(100, 100, 50, 0, Math.PI * 1.5, false);
    ctx.stroke();
    
    // Round lineCap arc
    ctx.strokeStyle = 'blue';
    ctx.lineCap = 'round';
    ctx.beginPath();
    ctx.arc(200, 100, 50, 0, Math.PI * 1.5, false);
    ctx.stroke();
    
    // Square lineCap arc
    ctx.strokeStyle = 'green';
    ctx.lineCap = 'square';
    ctx.beginPath();
    ctx.arc(300, 100, 50, 0, Math.PI * 1.5, false);
    ctx.stroke();
</script>

</body>
</html>

此示例绘制了三条 270 度弧线,具有不同的 lineCap 值。每条弧线都从右侧(0 弧度)开始,逆时针方向绘制。

红色弧线(butt)的两个端点都是平坦的。蓝色弧线(round)的端点是圆形的,而绿色弧线(square)的端点是方形的,超出了弧线的端点。

lineCap 与复杂路径

此示例演示了 lineCap 在更复杂路径中的行为。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>lineCap with Complex Paths</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="300"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Butt lineCap
    ctx.strokeStyle = 'red';
    ctx.lineWidth = 10;
    ctx.lineCap = 'butt';
    ctx.beginPath();
    ctx.moveTo(50, 50);
    ctx.lineTo(150, 150);
    ctx.lineTo(250, 50);
    ctx.stroke();
    
    // Round lineCap
    ctx.strokeStyle = 'blue';
    ctx.lineCap = 'round';
    ctx.beginPath();
    ctx.moveTo(50, 150);
    ctx.lineTo(150, 250);
    ctx.lineTo(250, 150);
    ctx.stroke();
    
    // Square lineCap
    ctx.strokeStyle = 'green';
    ctx.lineCap = 'square';
    ctx.beginPath();
    ctx.moveTo(50, 250);
    ctx.lineTo(150, 350);
    ctx.lineTo(250, 250);
    ctx.stroke();
</script>

</body>
</html>

此示例绘制了三条锯齿形路径,具有不同的 lineCap 值。每条路径由两个连接的线段组成,形成一个“V”形。

红色路径(butt)在起点和终点处显示平坦的端点。蓝色路径(round)具有圆形的端点,而绿色路径(square)具有方形的端点,超出了路径的端点。

实际应用:自定义箭头

此示例展示了如何使用 lineCap 创建自定义箭头。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Custom Arrowheads</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Draw arrow with round lineCap
    function drawArrow(x, y, length, color) {
        ctx.strokeStyle = color;
        ctx.lineWidth = 8;
        ctx.lineCap = 'round';
        
        // Shaft
        ctx.beginPath();
        ctx.moveTo(x, y);
        ctx.lineTo(x + length - 20, y);
        ctx.stroke();
        
        // Arrowhead
        ctx.beginPath();
        ctx.moveTo(x + length - 30, y - 15);
        ctx.lineTo(x + length, y);
        ctx.lineTo(x + length - 30, y + 15);
        ctx.stroke();
    }
    
    drawArrow(50, 50, 300, 'blue');
    drawArrow(50, 100, 250, 'red');
    drawArrow(50, 150, 200, 'green');
</script>

</body>
</html>

此示例创建了一个可重用的箭头绘制函数,该函数同时为箭头杆和箭头使用了 round lineCap。圆形的端点营造出精美的外观。

该函数绘制箭头杆,然后绘制两个单独路径的箭头。round lineCap 使箭头尖端具有平滑的外观。

来源

MDN Canvas lineCap 文档

在本文中,我们探讨了 lineCap 属性及其对不同类型 Canvas 图形的影响。掌握 lineCap 有助于在 Web 应用程序中创建更精美、更专业的图形。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。

列出 所有 JS Canvas 教程