HTML Canvas的setLineDash函数失效问题求助
Canvas中
ctx.setLineDash设置道路虚线不显示问题 问题描述
我在学习Free Code Camp的JavaScript自动驾驶课程(进度约41分50秒)时遇到了问题:尝试用ctx.setLineDash([20,20])绘制道路内部的虚线,但添加该语句后线条完全不显示。原本绘制实线一切正常,我也试过把这条语句放在beginPath()之后等不同位置,都没有效果。
现有代码
Road.js
class Road { constructor(x, width, laneCount = 3) { this.x = x; this.width = width; this.laneCount = laneCount; this.left = x - width / 2; this.right = x + width / 2; const infinity = 1000000000; this.top = -infinity; this.bottom = infinity; } draw(ctx) { ctx.lineWidth = 5; ctx.strokeStyle = "white"; for (let i = 0; i <= this.laneCount; i++) { const x = lerp( this.left, this.right, i/this.laneCount ) if (i > 0 && i < this.laneCount) { ctx.setLineDash([20,20]); } else { ctx.setLineDash([]) } ctx.beginPath(); ctx.moveTo(x, this.top); ctx.lineTo(x, this.bottom); ctx.stroke(); } } } function lerp(A, B, t) { return A + (B-A)*t; }
main.js
const canvas = document.getElementById("myCanvas"); canvas.height = window.innerHeight; canvas.width = 200; const ctx = canvas.getContext("2d"); const road = new Road(canvas.width / 2, canvas.width * 0.9, 4); animate(); function animate() { canvas.height = window.innerHeight; road.draw(ctx); requestAnimationFrame(animate); }
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="style.css"> <title>Self-Driving Car</title> </head> <body> <canvas id="myCanvas"></canvas> <script src="road.js"></script> <script src="main.js"></script> </body> </html>
CSS
body { margin: 0; background: darkgrey; overflow: hidden; text-align: center; } #myCanvas { background: lightgray; }
解决方案
问题根源是你设置的top和bottom值过大(10亿像素),虚线的循环周期(20像素实线+20像素空白)会导致当前画布可见区域刚好落在虚线的空白段,因此看不到线条。
修复方法
选择以下任意一种即可:
缩小道路上下边界范围:不要用无限大的值,基于画布高度设置足够覆盖可见区域的范围。修改Road类构造函数:
constructor(x, width, laneCount = 3) { this.x = x; this.width = width; this.laneCount = laneCount; this.left = x - width / 2; this.right = x + width / 2; // 用画布高度的倍数替代无限大值 const extendHeight = window.innerHeight * 2; this.top = -extendHeight; this.bottom = extendHeight; }调整虚线偏移量:强制让虚线从可见区域开始绘制,在设置
setLineDash后添加偏移控制:if (i > 0 && i < this.laneCount) { ctx.setLineDash([20,20]); ctx.lineDashOffset = -window.scrollY; // 动态匹配滚动位置,或设为0固定偏移 } else { ctx.setLineDash([]); }
另外,建议将setLineDash放在beginPath之后,更符合Canvas绘制逻辑:
ctx.beginPath(); if (i > 0 && i < this.laneCount) { ctx.setLineDash([20,20]); } else { ctx.setLineDash([]); } ctx.moveTo(x, this.top); ctx.lineTo(x, this.bottom); ctx.stroke();
修改后即可正常显示虚线。
内容的提问来源于stack exchange,提问作者ResistingGuide4
相关产品推荐
相关产品推荐

