【问题标题】:border offset with getting mouse coordinates on a canvas在画布上获取鼠标坐标的边框偏移
【发布时间】:2015-12-05 06:06:43
【问题描述】:

我尝试在具有 CSS 定义的边框的画布上获取鼠标坐标。首先,我使用了在this link 上找到的解决方案来获取鼠标在画布上的坐标:

 function getPosition(event)
      {
        var x = new Number();
        var y = new Number();
        var canvas = document.getElementById("canvas");

        if (event.x != undefined && event.y != undefined)
        {
          x = event.x;
          y = event.y;
        }
        else // Firefox method to get the position
        {
          x = event.clientX + document.body.scrollLeft +
              document.documentElement.scrollLeft;
          y = event.clientY + document.body.scrollTop +
              document.documentElement.scrollTop;
        }

        x -= canvas.offsetLeft;
        y -= canvas.offsetTop;

      }

solution 1这个方法的结果。可以看到坐标有 10 个像素的偏移,即画布边框的宽度。

为了解决边框宽度的问题,我修改如下:

   var computedStyle = window.getComputedStyle(canvas,null);
var topBorder = parseInt(computedStyle.getPropertyValue("border-top-width"),10);
var leftBorder = parseInt(computedStyle.getPropertyValue("border-left-width"),10);

// (x,y) coordinates
x -= canvas.offsetLeft + leftBorder;
y -= canvas.offsetTop + topBorder;

但这不是很好用:我在角落有一个灯光偏移(1 或 2 像素偏移);你可以在solution 2看到这个修改的结果

我也尝试过:

function getPosition(event) {

    var x, y;
    var rect = canvas.getBoundingClientRect();
    var computedStyle = window.getComputedStyle(canvas,null);
    var topBorder = parseInt(computedStyle.getPropertyValue("border-top-width"),10);
    var leftBorder = parseInt(computedStyle.getPropertyValue("border-left-width"),10);

    var x = event.clientX - rect.left - leftBorder;
    var y = event.clientY - rect.top - topBorder;

    // Display coordinates
    xspan.innerHTML = x;
    yspan.innerHTML = y;

  }

结果显示在solution 3 上,板的内角仍有 1、2 个像素的光偏移。

我想把(0,480)鼠标坐标放在画布的左下角,(0,0)放在左上角,(480,0)放在右上角,(480,480)放在右边底角。

如何处理边框宽度的“10 像素”(参见 CSS)?

我让你注意到,在调用 getPosition 之前,我已将 0.5px 添加到所有画布坐标,因为例如,在 i=1 处绘制的边框宽度等于 1 的线必须在 x = 处绘制0.5.

如果有人可以建议我在考虑边框宽度的情况下在此画布上获取有效坐标。

谢谢

【问题讨论】:

  • 如何将画布包裹在 div 中并在 div 上应用边框——然后不需要调整画布?

标签: javascript jquery css canvas


【解决方案1】:

边框

按照@markE 说的做,将你的<canvas> 元素包装在一个div 中:

<div id="game-wrapper">
  <canvas id="game" width="481" height="481">
</canvas>

game-wrapper div 设置边框。还要将game-wrapper 设为display: inline-block;,以便边框在画布周围正确布局。

那么你的整个坐标脚本可能是这样的:

function getPosition(event) {
  var x = event.layerX;
  var y = event.layerY;
}

光标

除此之外,我认为您真正的问题是光标的轴心点不在光标的尖端,而是在距离它几个像素的地方(至少在 OSX 中)。您可以通过将光标更改为十字准线来观察这一点:

cursor: crosshair;

坐标系

您还询问了进行坐标系转换的有效方法。我发现拥有一些将“游戏内”坐标转换为实际画布坐标并返回的功能是件好事。在您的情况下,您绘制的 0.5px 线:

function Vector2(x,y) {
  this.x = x;
  this.y = y;
}

Vector2.prototype.toGameCoordinates() {
  return new Vector2(
    this.x - 0.5,
    this.y - 0.5
  );
}

Vector2.prototype.toCanvasCoordinates() {
  return new Vector2(
    this.x + 0.5,
    this.y + 0.5
  );
}

【讨论】:

    猜你喜欢
    • 2017-05-28
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多