JavaScript Canvas LineJoin 教程
最后修改于 2025 年 4 月 3 日
在本文中,我们将探讨 JavaScript 中的 Canvas lineJoin 属性。此属性控制两条线在尖锐角度相交时角的渲染方式。掌握 lineJoin 对于创建精美的图形和可视化至关重要。
基本定义
lineJoin 属性指定两条线相交时创建的角的类型。它会影响具有尖锐角度或复杂路径的形状的外观。有三种可能的值:miter(斜接)、round(圆角)和 bevel(斜角)。
默认值为 miter,它创建尖角。Round 创建圆角,而 bevel 创建平角。该属性可用于路径和形状的描边操作。
基本的 LineJoin 用法
本示例在简单的角度路径上演示了三种 lineJoin 类型。
<!DOCTYPE html> <html> <head> <title>Basic LineJoin</title> </head> <body> <canvas id="myCanvas" width="400" height="200"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); // Miter join (default) ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(100, 150); ctx.lineTo(150, 50); ctx.lineJoin = 'miter'; ctx.lineWidth = 10; ctx.stroke(); // Round join ctx.beginPath(); ctx.moveTo(200, 50); ctx.lineTo(250, 150); ctx.lineTo(300, 50); ctx.lineJoin = 'round'; ctx.lineWidth = 10; ctx.stroke(); // Bevel join ctx.beginPath(); ctx.moveTo(350, 50); ctx.lineTo(400, 150); ctx.lineTo(450, 50); ctx.lineJoin = 'bevel'; ctx.lineWidth = 10; ctx.stroke(); </script> </body> </html>
此代码创建了三个具有不同 lineJoin 值的 V 形路径。每条路径都显示了根据 lineJoin 设置,角的渲染方式不同。
miter 连接创建尖锐的尖角,round 创建平滑的圆角,bevel 创建平角。所有路径均使用 10px 的线宽。
带斜接限制的 LineJoin
本示例展示了 miterLimit 如何影响尖锐角度的 miter 连接。
<!DOCTYPE html> <html> <head> <title>Miter Limit</title> </head> <body> <canvas id="myCanvas" width="400" height="300"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); // Default miter limit (10) ctx.beginPath(); ctx.moveTo(50, 100); ctx.lineTo(100, 50); ctx.lineTo(150, 100); ctx.lineJoin = 'miter'; ctx.lineWidth = 10; ctx.strokeStyle = 'blue'; ctx.stroke(); // Low miter limit (2) ctx.beginPath(); ctx.moveTo(200, 100); ctx.lineTo(250, 50); ctx.lineTo(300, 100); ctx.lineJoin = 'miter'; ctx.miterLimit = 2; ctx.lineWidth = 10; ctx.strokeStyle = 'red'; ctx.stroke(); </script> </body> </html>
miterLimit 属性控制 miter 连接可以延伸的距离。在尖锐角度下,miter 连接可能会变得非常长。miterLimit 可防止这种情况发生。
第一条路径使用默认的 miterLimit (10),显示长而尖的角。第二条路径的 miterLimit 为 2,显示当超过限制时,连接如何自动转换为斜角。
复杂路径的 LineJoin
本示例演示了复杂路径的 lineJoin 行为。
<!DOCTYPE html> <html> <head> <title>Complex Path LineJoin</title> </head> <body> <canvas id="myCanvas" width="500" height="300"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); // Star shape with round joins ctx.beginPath(); ctx.moveTo(100, 50); ctx.lineTo(120, 100); ctx.lineTo(170, 100); ctx.lineTo(130, 130); ctx.lineTo(150, 180); ctx.lineTo(100, 150); ctx.lineTo(50, 180); ctx.lineTo(70, 130); ctx.lineTo(30, 100); ctx.lineTo(80, 100); ctx.closePath(); ctx.lineJoin = 'round'; ctx.lineWidth = 8; ctx.strokeStyle = 'purple'; ctx.stroke(); // Zigzag path with bevel joins ctx.beginPath(); ctx.moveTo(200, 50); for (let i = 0; i < 5; i++) { ctx.lineTo(250 + i * 50, i % 2 ? 200 : 50); } ctx.lineJoin = 'bevel'; ctx.lineWidth = 8; ctx.strokeStyle = 'orange'; ctx.stroke(); </script> </body> </html>
此示例创建了两个复杂的路径来演示 lineJoin 行为。第一个是带有圆角的星形,显示平滑的圆角。
第二个是带有斜角的锯齿形路径,在每次角度变化处显示平角。为了清晰可见,两条路径都使用 8px 的线宽。
不同线宽的 LineJoin
本示例显示了 lineJoin 在不同线宽下的外观。
<!DOCTYPE html> <html> <head> <title>Line Width Comparison</title> </head> <body> <canvas id="myCanvas" width="500" height="300"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); const lineWidths = [2, 5, 10, 15]; const joinTypes = ['miter', 'round', 'bevel']; joinTypes.forEach((joinType, j) => { lineWidths.forEach((width, i) => { ctx.beginPath(); ctx.moveTo(50 + j * 150, 50 + i * 60); ctx.lineTo(100 + j * 150, 100 + i * 60); ctx.lineTo(150 + j * 150, 50 + i * 60); ctx.lineJoin = joinType; ctx.lineWidth = width; ctx.strokeStyle = `hsl(${j * 120}, 70%, 50%)`; ctx.stroke(); // Label ctx.fillStyle = 'black'; ctx.font = '12px Arial'; ctx.fillText(`${joinType} ${width}px`, 30 + j * 150, 45 + i * 60); }); }); </script> </body> </html>
此代码创建了一个网格,比较了所有三种连接类型以及四种不同的线宽。每个单元格显示了连接类型在不同比例下的外观。
随着线条变粗,斜接连接会更加明显。圆角连接保持一致的曲率。斜角连接在较大的线宽下显示出更明显的平角。hsl 颜色函数会根据连接类型改变颜色。
实际应用:自定义形状
本示例演示了 lineJoin 在创建自定义形状中的实际应用。
<!DOCTYPE html> <html> <head> <title>Custom Shapes with LineJoin</title> </head> <body> <canvas id="myCanvas" width="500" height="300"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); // Gear with miter joins ctx.beginPath(); drawGear(ctx, 100, 150, 50, 15, 8); ctx.lineJoin = 'miter'; ctx.lineWidth = 4; ctx.strokeStyle = 'teal'; ctx.stroke(); // Gear with round joins ctx.beginPath(); drawGear(ctx, 300, 150, 60, 12, 10); ctx.lineJoin = 'round'; ctx.lineWidth = 6; ctx.strokeStyle = 'brown'; ctx.stroke(); function drawGear(ctx, x, y, radius, teeth, toothLength) { const angleStep = (Math.PI * 2) / teeth; for (let i = 0; i < teeth; i++) { const angle1 = i * angleStep; const angle2 = angle1 + angleStep * 0.3; const angle3 = angle1 + angleStep * 0.7; ctx.moveTo( x + Math.cos(angle1) * radius, y + Math.sin(angle1) * radius ); ctx.lineTo( x + Math.cos(angle2) * (radius + toothLength), y + Math.sin(angle2) * (radius + toothLength) ); ctx.lineTo( x + Math.cos(angle3) * (radius + toothLength), y + Math.sin(angle3) * (radius + toothLength) ); ctx.lineTo( x + Math.cos(angle1 + angleStep) * radius, y + Math.sin(angle1 + angleStep) * radius ); } } </script> </body> </html>
此示例创建了两个具有不同 lineJoin 样式的齿轮形状。drawGear 函数生成具有指定参数的齿轮路径。
第一个齿轮使用斜接连接来创建锋利的齿,而第二个齿轮使用圆角连接来创建更平滑的齿。这表明 lineJoin 在实际应用中如何影响复杂的自定义形状。
来源
在本文中,我们通过各种示例深入探讨了 lineJoin 属性。理解这些技术有助于在 Web 应用程序中创建具有精确角样式的高质量图形。
作者
列出 所有 JS Canvas 教程。