Canvas绘制六边形地图河流线条不显示问题求助
问题:六边形地图河流线条无法绘制,
ctx.stroke()无效果 我正在开发一个基于六边形的地图生成器,需要在客户端绘制穿过服务器计算出的河流六边形中心的“河流”线条。相关变量通过Django从服务器注入(已验证可正常获取值):
// The optional populators const rivers = {{ rivers |safe}}; const cities = {{ cities |safe}}; const roads = {{roads |safe}}; // Constants for our angles and scales, starting with scale 5 const a = Math.PI/3; var r = 5;
绘制河流的函数如下:
// Function that draws Rivers function DrawRivers(){ // For each river in the rivers for (var river of rivers) { // Set up point tracking let x_coord = r + river[0][0] * (r + (r * Math.cos(a))); let y_coord = r + river[0][1] * (r + (r*Math.sin(a))); if (river[0][0] % 2 == 1) { y_off = y_coord; } else { // If it's an even number of tiles in the row it'll be the lower part y_off = y_coord + r * Math.sin(a); } ctx.beginPath(); ctx.lineWidth = r; ctx.strokeStyle = "#000000"; ctx.moveTo(x_coord, Math.round(y_off)) // For each point in the river for (var river_hex of river){ let x_coord = r + river[0][0] * (r + (r * Math.cos(a))); let y_coord = r + river[0][1] * (r + (r*Math.sin(a))); if (river[0][0] % 2 == 1) { y_off = y_coord; } else { // If it's an even number of tiles in the row it'll be the lower part y_off = y_coord + r * Math.sin(a); } ctx.lineTo(x_coord, Math.round(y_off)) } ctx.closePath(); ctx.stroke(); } }
运行代码后线条未绘制,已排查变量均正常,仅ctx.stroke()调用后无实际线条显示,恳请帮忙找出问题所在。
回答
核心错误:循环中重复使用
river[0]而非当前river_hex
你在遍历河流的每个六边形点时,始终用river[0][0]和river[0][1]计算坐标,导致所有lineTo都指向同一个点,线条长度为0,自然看不到绘制效果。修正后的代码
修改内层循环中的坐标计算逻辑,替换river[0]为当前迭代的river_hex:
// Function that draws Rivers function DrawRivers(){ // For each river in the rivers for (var river of rivers) { // Set up point tracking - 使用第一个点初始化起点 let firstHex = river[0]; let x_coord = r + firstHex[0] * (r + (r * Math.cos(a))); let y_coord = r + firstHex[1] * (r + (r*Math.sin(a))); let y_off = firstHex[0] % 2 === 1 ? y_coord : y_coord + r * Math.sin(a); ctx.beginPath(); ctx.lineWidth = r; ctx.strokeStyle = "#000000"; ctx.moveTo(x_coord, Math.round(y_off)); // 遍历河流的后续点(从第二个开始,避免重复绘制起点) for (var i = 1; i < river.length; i++) { let river_hex = river[i]; x_coord = r + river_hex[0] * (r + (r * Math.cos(a))); y_coord = r + river_hex[1] * (r + (r*Math.sin(a))); y_off = river_hex[0] % 2 === 1 ? y_coord : y_coord + r * Math.sin(a); ctx.lineTo(x_coord, Math.round(y_off)); } // 不需要closePath(),河流是连续线条而非闭合图形,否则会自动连接首尾 ctx.stroke(); } }
- 额外优化点
- 内层循环从索引1开始,避免重复绘制起点到起点的无效线条
- 移除
ctx.closePath(),因为河流是开放线条,闭合会强制连接首尾,不符合河流的视觉逻辑 - 使用三元运算符简化
y_off的判断,代码更简洁 - 变量
y_off添加let声明,避免全局变量污染
内容的提问来源于stack exchange,提问作者Sans the Medic
相关产品推荐
相关产品推荐

