六边形显示为方块且网格排列不紧凑的技术问题求助
问题解决步骤
1. 修正六边形图片的绘制尺寸(解决显示成方块的问题)
你当前的drawImage宽高计算错误,导致六边形被横向拉伸变形,看起来像方块。标准正六边形的宽高比为2 : √3(边长为s时,宽=2s,高=√3 s≈1.732s)。修改drawHexagon函数的尺寸参数,确保图片不被拉伸:
function drawHexagon(x, y, scale) { const c = document.getElementById("hexagonCanvas"); const ctx = c.getContext("2d"); const img = document.getElementById("whex"); // 标准正六边形尺寸:宽为2倍边长,高为√3倍边长 const hexWidth = 2 * scale; const hexHeight = scale * Math.sqrt(3); ctx.drawImage(img, x, y, hexWidth, hexHeight); }
如果你的PNG图片本身宽高不是标准正六边形比例,建议先调整图片画布大小,让它刚好适配六边形(去掉多余透明区域),避免绘制时出现不必要的空白。
2. 调整六边形网格的坐标计算(实现紧凑排列)
当前坐标公式会导致六边形间空隙过大,修改createCanvas里的x、y计算逻辑,让六边形紧凑排列:
function createCanvas() { let n = 15; // 先设小值测试,根据画布大小调整数量 let scale = 60; const hexHeight = scale * Math.sqrt(3); const hexWidth = 2 * scale; const halfHexWidth = hexWidth / 2; let hex = new Array(n); for (let i = 0; i < n; i++) { hex[i] = new Array(n); for (let j = 0; j < n; j++) { hex[i][j] = false; // 纵向紧凑间距为六边形高度的3/4 let y = i * hexHeight * 0.75; let x = j * hexWidth; // 奇数行横向偏移半个六边形宽度,实现交错排列 if (i % 2 === 1) { x += halfHexWidth; } // 确保绘制内容不超出画布范围 if (x + hexWidth < 2000 && y + hexHeight < 2000) { drawHexagon(x, y, scale); } } } }
3. 可选:用路径遮罩强制只显示六边形区域
如果PNG图片有多余透明空白,或想确保只显示六边形形状,可在绘制前添加裁剪路径:
function drawHexagon(x, y, scale) { const c = document.getElementById("hexagonCanvas"); const ctx = c.getContext("2d"); const img = document.getElementById("whex"); const hexWidth = 2 * scale; const hexHeight = scale * Math.sqrt(3); // 保存当前画布状态,后续恢复 ctx.save(); // 绘制正六边形裁剪路径 ctx.beginPath(); const centerX = x + hexWidth / 2; const centerY = y + hexHeight / 2; for (let k = 0; k < 6; k++) { const angle = (Math.PI / 3) * k; const px = centerX + scale * Math.cos(angle); const py = centerY + scale * Math.sin(angle); k === 0 ? ctx.moveTo(px, py) : ctx.lineTo(px, py); } ctx.closePath(); ctx.clip(); // 裁剪到六边形路径 // 绘制图片,仅显示裁剪范围内的内容 ctx.drawImage(img, x, y, hexWidth, hexHeight); ctx.restore(); // 恢复画布原始状态 }
调整后的完整代码
HTML代码
<img src="你的本地PNG路径" id="whex" style="display:none;"> <!-- 隐藏原图,避免页面额外显示 --> <canvas id="hexagonCanvas" width="2000" height="2000" style="border:1px solid grey;"></canvas> <button id="Button1">生成六边形网格</button> <script src="hexGame.js"></script>
JavaScript代码
document.getElementById("Button1").addEventListener("click", myFunction); function myFunction() { const canvas = document.getElementById("hexagonCanvas"); const ctx = canvas.getContext("2d"); ctx.clearRect(0, 0, canvas.width, canvas.height); // 每次点击先清空画布 createCanvas(); } function drawHexagon(x, y, scale) { const c = document.getElementById("hexagonCanvas"); const ctx = c.getContext("2d"); const img = document.getElementById("whex"); const hexWidth = 2 * scale; const hexHeight = scale * Math.sqrt(3); ctx.save(); ctx.beginPath(); const centerX = x + hexWidth / 2; const centerY = y + hexHeight / 2; for (let k = 0; k < 6; k++) { const angle = (Math.PI / 3) * k; const px = centerX + scale * Math.cos(angle); const py = centerY + scale * Math.sin(angle); k === 0 ? ctx.moveTo(px, py) : ctx.lineTo(px, py); } ctx.closePath(); ctx.clip(); ctx.drawImage(img, x, y, hexWidth, hexHeight); ctx.restore(); } function createCanvas() { let n = 15; let scale = 60; const hexHeight = scale * Math.sqrt(3); const hexWidth = 2 * scale; const halfHexWidth = hexWidth / 2; let hex = new Array(n); for (let i = 0; i < n; i++) { hex[i] = new Array(n); for (let j = 0; j < n; j++) { hex[i][j] = false; let y = i * hexHeight * 0.75; let x = j * hexWidth; if (i % 2 === 1) { x += halfHexWidth; } if (x + hexWidth < 2000 && y + hexHeight < 2000) { drawHexagon(x, y, scale); } } } }
内容的提问来源于stack exchange,提问作者someguy
相关产品推荐
相关产品推荐

