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

Canvas网格绘制问题:无法在方块内正确定位点击生成的圆形

Canvas网格点击画圆定位错误解决方法

问题描述

我是法国人,英语表达不太流畅。我用JavaScript绘制了6行7列的Canvas网格,想通过点击在对应方块里画圆形,但圆没法正确定位到方块中心。试过用鼠标偏移坐标定位,不行;后来用数组存Canvas元素,还是失败。

问题代码

const canvas = document.getElementById('grille');
const ccc = canvas.getContext('2d');
let i = 0,l = 0;
let x = 10,y = 10;
let tabC = [];
let tabtab = [];
let cnvx = -40,cnvy = 560;
let posiX = 0,posiY = 0;
let test;
// fonction dessine caneva
(function (){
        for (l = 0; l < 6; l++) {
            for (i = 0; i < 7; i++) {
                tabtab.push(ccc.strokeRect(x, y, 100, 100));
                tabC.push('');
                x += 100;
            }
            y += 100;
            x = 10;
        }console.log("tabtab : "+tabtab);
})();

canvas.addEventListener('click', function (e) {
    posiX = e.offsetX;
    posiY = e.offsetY;
    console.log((e.offsetX)+ ' , ' + (e.offsetY));
    for (let j = 0;j<tabC.length;j++){
        if (tabC[j]===''){
            tabC.push('0');
            ccc.beginPath();
            ccc.fillStyle = 'red';
            tabtab.push(ccc.arc(e.offsetX, e.offsetY , 40, 30, 0, 2 * Math.PI));
            ccc.fill();
            ccc.closePath();
        }
    }

问题示意图

Canvas网格点击画圆错误示意图

错误分析

  1. 无效存储绘图结果:strokeRect、arc这类Canvas绘图方法返回undefined,把它们存入tabtab数组完全没用,没法用来定位方块。
  2. 定位逻辑错误:直接用鼠标偏移坐标画圆,没计算坐标属于哪个网格方块,导致圆的位置不对应方块中心;tabC的遍历和添加逻辑错了,每次点击都往数组末尾加元素,不是标记对应位置的方块。
  3. 缺失网格位置数据:没记录每个网格方块的坐标范围,没法判断点击落在哪个方块里。

修正后的代码

const canvas = document.getElementById('grille');
const ccc = canvas.getContext('2d');
// 网格参数:6行7列,每个方块100px,偏移10px
const rows = 6;
const cols = 7;
const cellSize = 100;
const offset = 10;
// 存储每个网格的位置和填充状态
const gridCells = [];

// 初始化绘制网格
(function initGrid() {
    let x = offset;
    let y = offset;
    for (let row = 0; row < rows; row++) {
        for (let col = 0; col < cols; col++) {
            ccc.strokeRect(x, y, cellSize, cellSize);
            // 存入方块的坐标和未填充状态
            gridCells.push({
                x: x,
                y: y,
                filled: false
            });
            x += cellSize;
        }
        y += cellSize;
        x = offset;
    }
})();

canvas.addEventListener('click', function(e) {
    const clickX = e.offsetX;
    const clickY = e.offsetY;

    // 遍历找到点击的方块
    for (let cell of gridCells) {
        // 判断点击坐标是否在当前方块范围内,且未填充
        if (clickX >= cell.x && clickX <= cell.x + cellSize &&
            clickY >= cell.y && clickY <= cell.y + cellSize &&
            !cell.filled) {
            // 计算方块中心坐标
            const centerX = cell.x + cellSize / 2;
            const centerY = cell.y + cellSize / 2;
            // 绘制居中的圆形
            ccc.beginPath();
            ccc.fillStyle = 'red';
            ccc.arc(centerX, centerY, cellSize / 2 - 10, 0, 2 * Math.PI);
            ccc.fill();
            ccc.closePath();
            // 标记该方块已填充
            cell.filled = true;
            break;
        }
    }
});

关键改进点

  • 存储网格数据:用gridCells数组记录每个方块的坐标和填充状态,方便后续判断点击位置。
  • 精准判断点击方块:通过坐标范围确定点击落在哪个方块内,而非直接用鼠标坐标画圆。
  • 圆形居中定位:通过方块起始坐标加半边长,得到中心位置,确保圆在方块内居中显示。
  • 修复状态标记:找到对应方块后标记为已填充,避免重复绘制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 12:45:35