Canvas虚线由setLineDash()控制节奏,数组元素交替表示实线与空白长度,奇数长度自动补全,需适配设备像素比并用lineDashOffset调节起始偏移。

Canvas 绘制虚线靠的是 setLineDash() 这个方法,它不控制颜色或粗细,只管“实一段、空一段”的节奏。样式和间距效果好不好,关键在数组怎么写、什么时候设、以及是否适配设备。
虚线节奏由数组决定
传给 setLineDash() 的是一个数字数组,元素按顺序交替解释为「实线长度」和「空白长度」:
-
[6, 4]:画 6 像素实线 → 跳 4 像素 → 再画 6 像素 → ……循环下去 -
[10, 2, 2, 2]:10px 实线 → 2px 空白 → 2px 实线 → 2px 空白,四段一循环 - 数组长度为奇数(如
[5, 3, 2])时,Canvas 自动复制成偶数长度:[5, 3, 2, 5, 3, 2] - 想恢复实线?用
ctx.setLineDash([])或ctx.setLineDash([0]),别传null或undefined——会报错或静默失败
点线要稳,不能只靠小数值
想画点状效果,[1, 8] 看似合理,但实际容易糊或消失,尤其在高 DPI 屏幕或非整数坐标下:
- 更可靠的做法是用
[0, 8]配合ctx.lineCap = 'round' - 把起点和终点坐标取整(
Math.round(x)),避免抗锯齿拉伸 - 数值低于 0.5 像素可能被渲染引擎忽略,建议最小实线段用
2,比如[2, 2]
间距不是绝对值,得看设备像素比
CSS 缩放或 Retina 屏会让虚线变密、模糊甚至错位,因为 setLineDash 的单位是 CSS 像素,不是物理像素:
- 获取设备像素比:
const dpr = window.devicePixelRatio || 1 - 把 dash 数组每个值乘以
dpr后再传入:ctx.setLineDash([6 * dpr, 4 * dpr]) - 用
transform: scale()缩放 canvas 时,虚线会随路径一起缩放,反而更可控
偏移量控制起始位置
lineDashOffset 不是让某一段移动,而是整个虚线图案沿路径方向整体滑动:
-
ctx.lineDashOffset = 3:图案向终点方向平移 3 像素,常用来消除“开头断掉”的视觉突兀感 - 动画中实现流动效果:每帧递增 offset,再对总周期取模,例如
offset = (offset + 0.3) % 10 - 偏移量不会自动重置,每次绘制前需显式赋值;旧版 Safari 对小数偏移支持不稳定,生产环境建议取整


















