You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HTML Canvas与JavaScript绘制六边形网格偶数尺寸错位问题

问题原因

偶数尺寸下网格错位的核心问题是drawGrid函数的变量作用域逻辑错误:内层绘制单个六边形的循环直接修改了外层控制行位置的y变量。
当一行绘制的六边形数量为偶数时,内层循环结束后y值的累计偏移没有归零,外层循环进入下一行时,会在这个错误的y值基础上累加行高,直接导致后续所有行的起始位置偏移,出现排列错位。奇数尺寸下刚好偏移量抵消,所以看起来表现正常,但逻辑本身存在隐患。

修复方案

调整drawGrid的坐标计算逻辑,每一行的基准坐标单独计算存储,内层循环只读取基准值计算单个六边形位置,不修改外层的行坐标变量,从根源上避免坐标污染。
修复后的完整JS代码如下:

const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');

const shapeType = 6;
const angle = 2 * Math.PI / shapeType;
const radius = 20;

function init() {
    drawGrid(6); // 传入偶数测试也不会错位
}

init();

function drawGrid(size) {
    // 预计算六边形固定尺寸参数
    const hexHalfHeight = radius * Math.sin(angle);
    const hexRowHeight = 2 * hexHalfHeight;
    const hexHorizontalStep = radius * (1 + Math.cos(angle));
    const oddRowXOffset = radius + radius * Math.cos(angle);

    for (let i = 0; i < size; i++) {
        // 固定当前行的基准坐标,内层循环不修改这两个值
        const currentRowY = radius + i * hexRowHeight;
        const currentRowBaseX = radius + (i % 2 === 1 ? oddRowXOffset : 0);
        
        for (let j = 0; j < size; j++) {
            const x = currentRowBaseX + j * hexHorizontalStep;
            drawHexagon(x, currentRowY);
        }
    }
}

function drawHexagon(x, y) {
    context.beginPath();
    for (let i = 0; i < shapeType; i++) {
        let xx = x + radius * Math.cos(angle * i);
        let yy = y + radius * Math.sin(angle * i);
        context.lineTo(xx, yy);
    }
    context.closePath();
    context.stroke();
}

对应的HTML部分不需要做任何修改,保持原有代码即可。

修改点说明

  • 提前预计算六边形的半高、行高、水平间距、奇数行水平偏移量这些固定值,避免循环内重复计算
  • 外层循环每进入新行,先计算好当前行固定的Y坐标和起始X坐标,两个值不会在内层循环中被修改
  • 奇偶行的交错偏移通过行起始X坐标实现,不需要在绘制列的时候反复修改Y值
  • 内层循环只根据行列索引计算单个六边形的坐标,没有跨作用域的变量修改,不会产生坐标污染

修复后无论传入的size参数是奇数还是偶数,都能绘制出排列整齐的正方形六边形网格,不会出现错位问题。


内容的提问来源于stack exchange,提问作者Youcef LAIDANI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 09:48:15