JavaScript Canvas lineDashOffset 教程
最后修改于 2025 年 4 月 3 日
在本文中,我们探讨了 JavaScript 中的 Canvas lineDashOffset 属性。此属性允许创建动画虚线并控制虚线模式。掌握 lineDashOffset 对于创建动态视觉效果至关重要。
基本定义
lineDashOffset 属性指定从何处开始绘制线的虚线模式。它接受一个浮点数值,表示以像素为单位的偏移距离。正值会向前移动模式,负值会向后移动模式。
当与 setLineDash 结合使用时,lineDashOffset 通过随时间改变偏移量来实现动画效果。这会在虚线和边框中产生运动的错觉。该属性适用于所有描边操作。
基本 lineDashOffset 用法
本示例演示了如何创建带有偏移量的简单虚线。
<!DOCTYPE html> <html> <head> <title>Basic lineDashOffset</title> </head> <body> <canvas id="myCanvas" width="300" height="200"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); ctx.setLineDash([10, 5]); ctx.lineDashOffset = 5; ctx.strokeStyle = 'blue'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(50, 100); ctx.lineTo(250, 100); ctx.stroke(); </script> </body> </html>
在这个基本示例中,我们创建了一个 canvas 元素并获取了它的 2D 上下文。我们使用 setLineDash 设置了 10px 虚线和 5px 间隙的虚线模式。
5px 的 lineDashOffset 将模式偏移到第一个虚线的一半处。这说明了偏移量如何影响虚线模式在线上的起始位置。
动画虚线
本示例展示了如何使用 lineDashOffset 动画化虚线。
<!DOCTYPE html> <html> <head> <title>Animated Dashed Line</title> </head> <body> <canvas id="myCanvas" width="300" height="200"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); let offset = 0; function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.setLineDash([15, 5]); ctx.lineDashOffset = -offset; ctx.strokeStyle = 'red'; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(50, 100); ctx.lineTo(250, 100); ctx.stroke(); offset++; if (offset > 20) offset = 0; requestAnimationFrame(animate); } animate(); </script> </body> </html>
此示例创建了一个动画,其中虚线似乎在移动。我们使用 requestAnimationFrame 来创建平滑的动画循环。
offset 变量在每一帧都会递增,并且我们将其负值应用于 lineDashOffset。当 offset 超过 20 时,它会重置为 0,从而创建一个无缝循环。该线似乎连续向右滚动。
虚线圆动画
本示例演示了如何使用 lineDashOffset 动画化虚线圆。
<!DOCTYPE html> <html> <head> <title>Dashed Circle Animation</title> </head> <body> <canvas id="myCanvas" width="300" height="300"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); let offset = 0; function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.setLineDash([10, 5]); ctx.lineDashOffset = offset; ctx.strokeStyle = 'green'; ctx.lineWidth = 5; ctx.beginPath(); ctx.arc(150, 150, 100, 0, Math.PI * 2); ctx.stroke(); offset += 0.5; if (offset > 15) offset = 0; requestAnimationFrame(animate); } animate(); </script> </body> </html>
在这里,我们动画化一个虚线圆以创建加载旋转器效果。lineDashOffset 以较慢的速度(每帧 0.5)递增,以实现平滑的运动。
随着虚线模式沿着圆周移动,圆似乎在旋转。此技术常用于加载指示器和进度动画。
多条动画线
本示例展示了多条具有不同虚线模式和偏移量的线。
<!DOCTYPE html> <html> <head> <title>Multiple Animated Lines</title> </head> <body> <canvas id="myCanvas" width="400" height="300"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); let offset1 = 0; let offset2 = 0; let offset3 = 0; function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); // First line ctx.setLineDash([20, 10]); ctx.lineDashOffset = offset1; ctx.strokeStyle = 'blue'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(350, 50); ctx.stroke(); // Second line ctx.setLineDash([10, 5, 5, 5]); ctx.lineDashOffset = offset2; ctx.strokeStyle = 'red'; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(50, 150); ctx.lineTo(350, 150); ctx.stroke(); // Third line ctx.setLineDash([5, 3]); ctx.lineDashOffset = offset3; ctx.strokeStyle = 'green'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(50, 250); ctx.lineTo(350, 250); ctx.stroke(); offset1 += 1; offset2 += 2; offset3 += 3; if (offset1 > 30) offset1 = 0; if (offset2 > 20) offset2 = 0; if (offset3 > 8) offset3 = 0; requestAnimationFrame(animate); } animate(); </script> </body> </html>
此示例创建了三条具有不同虚线模式的水平线。每条线都有自己的 offset 变量,以不同的速率递增。
第一条线使用了简单的虚线模式,第二条使用了更复杂的模式,第三条使用了非常短的模式。不同的动画速度创造了有趣的视觉效果。
交互式 lineDashOffset
本示例演示了通过鼠标与 lineDashOffset 进行交互控制。
<!DOCTYPE html> <html> <head> <title>Interactive lineDashOffset</title> </head> <body> <canvas id="myCanvas" width="400" height="300"></canvas> <p>Move mouse horizontally to change dash offset</p> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); canvas.addEventListener('mousemove', (e) => { const rect = canvas.getBoundingClientRect(); const x = e.clientX - rect.left; const offset = x / 2; ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.setLineDash([15, 10, 5, 10]); ctx.lineDashOffset = offset; ctx.strokeStyle = 'purple'; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(50, 150); ctx.lineTo(350, 150); ctx.stroke(); // Display current offset ctx.fillStyle = 'black'; ctx.font = '16px Arial'; ctx.fillText(`Offset: ${offset.toFixed(1)}`, 50, 50); }); // Initial draw ctx.setLineDash([15, 10, 5, 10]); ctx.lineDashOffset = 0; ctx.strokeStyle = 'purple'; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(50, 150); ctx.lineTo(350, 150); ctx.stroke(); </script> </body> </html>
此示例通过将 lineDashOffset 与鼠标位置绑定,使其具有交互性。水平移动鼠标可以实时更改 offset 值。
当前的 offset 值以文本形式显示。这说明了 lineDashOffset 如何用于交互式图形和视觉反馈。
来源
在本文中,我们探讨了使用 lineDashOffset 创建动画和交互式虚线的各种技术。这个强大的属性为动态 canvas 图形提供了许多可能性。
作者
列出 所有 JS Canvas 教程。