【问题标题】:Get canvas click coordinates with css scaling and contain:fit使用 css 缩放获取画布点击坐标并包含:fit
【发布时间】:2021-08-30 18:28:17
【问题描述】:

对于我的像素艺术网站,我有一个相对于视口固定的画布,使用 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>

【问题讨论】:

    标签: javascript html onclick html5-canvas


    【解决方案1】:

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

    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;
    }
    &lt;canvas id="scaledCanvas" width="16" height="16"&gt;Canvas Not Supported&lt;/canvas&gt;

    【讨论】:

    • 我不测试结果,以防像素超出真实画布。您应该添加一些测试: if x 15,或 y 15 则点击超出实际画布。
    • 是的,这行得通!非常感谢,我不知道 getBoundingClientRect,这有很大帮助!至于点击关闭像素,这不是问题。
    • 主要思想是在 16 个部分上划分较小的尺寸(宽度或高度),并取最长尺寸其余部分的一半。只有这样我们才能找到正确的点击位置。
    • 如果我是正确的,你还需要考虑填充吗?
    • 当然,事实上我什至不知道getBoundingClientRect() 是什么)))只是寻找任何选项来获取 HTML 元素的宽度。正如我之前所说:案例是将该区域表示为一个 16*16 的单元格字段。还要切断“容器”的其余部分。
    猜你喜欢
    • 2021-11-18
    • 2014-08-27
    • 2014-12-11
    • 2014-03-10
    • 2016-01-01
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多