使用 css 缩放和 contain:fit 获取 canvas 点击坐标

Get canvas click coordinates with css scaling and contain:fit

对于我的像素艺术网站,我有一个相对于视口固定的 canvas,使用 css 缩放,并且有 object-fit:contain;使其保持 div 的大小,无论内部绘制或调整大小。 我需要获取鼠标点击坐标 而无需缩放 。 e.y/e.x 收集的缩放坐标不会有用,因为 object-fit:contain;会改变纵横比。

这里有一些虚拟代码可以更好地解释我的问题:

var c = document.getElementById("scaledCanvas");
var ctx = c.getContext('2d');

c.height = 16; // varaible height
c.width = 16; // varaible width

for (var x = 0; x < c.width; x++) {
  for (var y = 0; y < c.height; y++) {
    ctx.fillStyle = "#" + Math.floor(Math.random() * 16777215).toString(16); // pick random color
    ctx.fillRect(x, y, 1, 1); // draw pixel on canvas
  }
}


c.addEventListener('click', function(e) {
  //this is what i need help with, clickX and clickY need to give the pixel coordinates of the canvas, not the screen
  let clickX = e.x - this.offsetLeft;
  let clickY = e.y - this.offsetTop;

  console.log(clickX + ", " + clickY);
}, false);
#scaledCanvas {
  width: 50vw;
  height: 50vh;
  image-rendering: pixelated;
  object-fit: contain;
  background-color: black;
}
<!DOCTYPE html>
<html>

<body>
  <canvas id="scaledCanvas" width="16" height="16">Canvas Not Supported</canvas>
</body>

</html>

应该是这样的吗?我采用“像素”单元格坐标。

var c = document.getElementById("scaledCanvas");
var ctx = c.getContext('2d');

c.height = 16; // varaible height
c.width = 16; // varaible width

for (var x = 0; x < c.width; x++) {
  for (var y = 0; y < c.height; y++) {
    ctx.fillStyle = "#" + Math.floor(Math.random() * 16777215).toString(16); // pick random color
    ctx.fillRect(x, y, 1, 1); // draw pixel on canvas
  }
}


c.addEventListener('click', function(e) {

  let realWidth = c.getBoundingClientRect().width;
  let realHeight = c.getBoundingClientRect().height;

  let cellSize = (realWidth < realHeight) ? realWidth/16 : realHeight/16;

  let clickX = Math.floor((e.x - this.offsetLeft - (realWidth - cellSize*16)/2)/cellSize);
  let clickY = Math.floor((e.y - this.offsetTop - (realHeight - cellSize*16)/2)/cellSize);

  console.log(clickX + ", " + clickY);
}, false);
#scaledCanvas {
  width: 50vw;
  height: 50vh;
  image-rendering: pixelated;
  object-fit: contain;
  background-color: black;
}
<canvas id="scaledCanvas" width="16" height="16">Canvas Not Supported</canvas>