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 教程。