javascript - 如何将 Canvas 鼠标坐标转换为自定义 XY 值并标记单元格

标签 javascript html5-canvas

我有一个带有覆盖网格的 Canvas 元素,并通过单击事件将鼠标坐标存储在字段中。

但现在我需要自定义轴值中的自定义转换并标记单击的单元格。 (示例单元格 D4)

enter image description here

HTML:

<canvas id="canvas" width="480" height="400" style="background: url(''); background-size: cover;" onclick="storeGuess(event)"></canvas>

<input id="coords_c" name="coords_c" class="form-control" type="text" placeholder="" value="<?php echo htmlspecialchars($position->coords_c, ENT_QUOTES, 'UTF-8'); ?>">

Javascript:

    var bw = 480;
    var bh = 400;
    var p = 0;
    var cw = bw + (p*2) + 0;
    var ch = bh + (p*2) + 1;

    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");

    function drawBoard(){
    for (var x = 0; x <= bw; x += 40) {
        context.moveTo(0.5 + x + p, p);
        context.lineTo(0.5 + x + p, bh + p);
    }

    for (var x = 0; x <= bh; x += 20) {
        context.moveTo(p, 0.5 + x + p);
        context.lineTo(bw + p, 0.5 + x + p);
    }

    context.strokeStyle = "black";
    context.stroke();
    }

    drawBoard();

    var canvasSetup = document.getElementById("canvas");
    var ctx = canvasSetup.getContext("2d");
    guessX = 0; 
    guessY = 0; 
    function storeGuess(event) {
        var x = event.offsetX;
        var y = event.offsetY;
        guessX = x;
        guessY = y;

        var tipWidth=35;
            var tipHeight=22;
            var tipRow;
            var tipCol;

        $('#coords_c').val( + guessX + "/" + guessY);
        console.log("x coords: " + guessX + ", y coords: " + guessY);
    }

最佳答案

这就是我的做法:我将所有单元格保存到单元格数组中。然后单击时,我检测到发生单击事件的单元格。我把这个单元格漆成红色。在这里,您可以决定将单击的单元格索引(pos)保存在其他数组中。

请阅读代码中的注释。

// the width and the height of the canvas
const cw = canvas.width =  480;
const ch = canvas.height = 400;
// the width and the height of every cell
let rw = 40;
let rh = 20;
// the number of cells per row
let w = cw / rw;
// the number of cells per column
let h = ch / rh;
// the mouse position
let m = {};
// the array of cells
let cells = [];

// the canvas context
const context = canvas.getContext("2d");


// a function to draw a cell
function drawCell(o,fill){
  let fillcolor = fill ? fill : "white";
  context.fillStyle = fillcolor;
  context.beginPath();
  context.moveTo(o.x,o.y);
  context.lineTo(o.x+rw, o.y);
  context.lineTo(o.x+rw, o.y+rh);
  context.lineTo(o.x, o.y+rh);
  context.lineTo(o.x, o.y);
  context.closePath()
  context.fill();
  context.stroke();
}


// a function to draw the board
function drawBoard(){
  for (var y = 0; y < ch; y += rh) {
    for (var x = 0; x < cw; x += rw) {
      let o = {x:x,y:y}
      //draw the cell and pust the coords of the cell onto the cells array
      drawCell(o);
      cells.push(o)
    }
  }
}

drawBoard();


canvas.addEventListener("click",(evt)=>{
  // get the mouse position
  m = oMousePos(canvas, evt);
  // get the index of the clicked cell
  let pos = (~~(m.y / rh))* w + ~~(m.x / rw);
  // fill the clicked cell
  drawCell(cells[pos],"red")
  // here you can store the guess in an aray if this is what you need
})


    
// a function to get the mouse position    
function oMousePos(canvas, evt) {
  var ClientRect = canvas.getBoundingClientRect();
	return { 
	x: Math.round(evt.clientX - ClientRect.left),
	y: Math.round(evt.clientY - ClientRect.top)
}
}
canvas{border:1px solid}
<canvas id="canvas"></canvas>

更新

OP 正在评论:

Do you have any idea how to clear all the already marked cells before select another one but still keep the dashboard? So that only one cell is marked every time.

在这种情况下,您需要清除上下文,并在填充单击的单元格之前重新绘制网格:

// the width and the height of the canvas
const cw = canvas.width =  480;
const ch = canvas.height = 400;
// the width and the height of every cell
let rw = 40;
let rh = 20;
// the number of cells per row
let w = cw / rw;
// the number of cells per column
let h = ch / rh;
// the mouse position
let m = {};
// the array of cells
let cells = [];

// the canvas context
const context = canvas.getContext("2d");


// a function to draw a cell
function drawCell(o,fill){
  let fillcolor = fill ? fill : "white";
  context.fillStyle = fillcolor;
  context.beginPath();
  context.moveTo(o.x,o.y);
  context.lineTo(o.x+rw, o.y);
  context.lineTo(o.x+rw, o.y+rh);
  context.lineTo(o.x, o.y+rh);
  context.lineTo(o.x, o.y);
  context.closePath()
  context.fill();
  context.stroke();
}


// a function to draw the board
function drawBoard(){
  for (var y = 0; y < ch; y += rh) {
    for (var x = 0; x < cw; x += rw) {
      let o = {x:x,y:y}
      //draw the cell and pust the coords of the cell onto the cells array
      drawCell(o);
      cells.push(o)
    }
  }
}

drawBoard();


canvas.addEventListener("click",(evt)=>{
  // get the mouse position
  m = oMousePos(canvas, evt);
  // get the index of the clicked cell
  let pos = (~~(m.y / rh))* w + ~~(m.x / rw);
  // clear the context
  context.clearRect(0,0,cw,ch);
  // draw the board
  drawBoard()
  // fill the clicked cell
  drawCell(cells[pos],"red")
  // here you can store the guess in an aray if this is what you need
})


    
// a function to get the mouse position    
function oMousePos(canvas, evt) {
  var ClientRect = canvas.getBoundingClientRect();
	return { 
	x: Math.round(evt.clientX - ClientRect.left),
	y: Math.round(evt.clientY - ClientRect.top)
}
}
canvas{border:1px solid}
<canvas id="canvas"></canvas>

关于javascript - 如何将 Canvas 鼠标坐标转换为自定义 XY 值并标记单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54869972/

相关文章:

javascript - NeDB 查询存在投影语法错误

javascript - 为什么 switch case 语句中的 const 是非法的?

javascript - 如何在 html 5 Canvas 上使用 FontAwesome 图标

css - 将 Canvas Cursor css 属性与 uri 一起使用?

javascript - 更改 jquery ajax 表中一行的字体颜色

javascript - 外部 javascript 不工作?

javascript - 如何在 jquery 中对未命名函数调用 .call()?

javascript - 如果使用 Canvas 找不到图像,则显示名称头像(回退)

javascript - 具有彩虹渐变的复杂形状

javascript - 如何使用 canvas.toDataURL() 在 Adob​​e AIR 中获取图像的 base64?