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(); } }
问题示意图

错误分析
- 无效存储绘图结果:
strokeRect、arc这类Canvas绘图方法返回undefined,把它们存入tabtab数组完全没用,没法用来定位方块。 - 定位逻辑错误:直接用鼠标偏移坐标画圆,没计算坐标属于哪个网格方块,导致圆的位置不对应方块中心;
tabC的遍历和添加逻辑错了,每次点击都往数组末尾加元素,不是标记对应位置的方块。 - 缺失网格位置数据:没记录每个网格方块的坐标范围,没法判断点击落在哪个方块里。
修正后的代码
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
相关产品推荐
相关产品推荐

