在Javascript中,为什么getBoundingClientRect()有时返回浮点值?

vfs*_*s23 3 javascript css html5 canvas

我正在尝试使用HTML5 canvas元素。我要尝试做的一件事是设置mousemove事件以在画布上跟踪鼠标以进行绘图和其他用途。我还无法找到有关如何获得鼠标悬停在画布上像素的确切坐标的明确答案。我在网上找到了一个使用此html的教程(我在画布上添加了背景色,以使其在渲染的页面上显而易见):

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      body {
        margin: 0px;
        padding: 0px;
      }

      #myCanvas {
        background-color: cornflowerblue;
      }
    </style>
  </head>
  <body>
    <canvas id="myCanvas" width="578" height="200"></canvas>
    <script>
      function writeMessage(canvas, message) {
        var context = canvas.getContext('2d');
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.font = '18pt Calibri';
        context.fillStyle = 'black';
        context.fillText(message, 10, 25);
      }
      function getMousePos(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        return {
          x: evt.clientX - rect.left,
          y: evt.clientY - rect.top
        };
      }
      var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');

      canvas.addEventListener('mousemove', function(evt) {
        var mousePos = getMousePos(canvas, evt);
        var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
        writeMessage(canvas, message);
      }, false);
    </script>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

加载页面后,您会在页面的左上角看到画布为蓝色矩形。将鼠标移到其上,画布上的文本将更改为将鼠标位置显示为两个整数,每个整数用于X和Y。

然后,我通过添加顶部和左侧边距来修改画布样式,并使页面的其余部分保持不变。

#myCanvas {
  background-color: cornflowerblue;
  margin-left: 30px;
  margin-top: 30px;
} 
Run Code Online (Sandbox Code Playgroud)

当我现在渲染页面时,画布的蓝色矩形正按我的预期从页面的顶部和左侧偏移。但是,将鼠标移到画布上时,在画布上显示的X和Y鼠标坐标以浮点数形式出现,并带有许多小数位。仔细检查一下代码,似乎getBoundingClientRect()返回的rect是顶部和左侧的值是浮点型的。

我假设我可以执行类似截断或四舍五入getBoundingClientRect()返回的值的操作,但这对我来说似乎是一种错误的方式。

我是否以某种方式错误地使用了getBoundingClientRect(),或者期望它应该返回浮点值?

当侦听各种鼠标事件时,有没有一种清晰的方法来在画布上获得鼠标的确切X和Y坐标?

Vic*_*uin 6

tldr; 您确实在浏览器中进行过缩放。

问题

margin-left: 30px;
Run Code Online (Sandbox Code Playgroud)

在此jsfiddle中,那是模仿您的问题的,当导航器缩放比例设置为100%(正常)时,它无法像您在我的计算机上所说的那样工作。但是,如果放大浏览器,您会注意到这种行为。

margin-left: 11%;
Run Code Online (Sandbox Code Playgroud)

相反,如果您像本jsfiddle中那样使用%margin,您会注意到无论缩放是否启用,它确实会返回浮动鼠标位置。

答案

关键是鼠标的位置是在屏幕上显示时进行计算的:由于它是基于像素的,因此只能具有整个位置坐标。

但是,在应用边距,缩放和其他修饰符之后,但告诉GPU渲染它之前,getBoundingClientRect返回浏览器计算为“元素的边界客户端Rect”的内容。简而言之,它返回元素的实际位置,该位置随后由GPU近似以渲染在像素矩阵内。如果您使用像素边距/大小/填充/等,则元素位置仍基于整数,但是如果缩放或使用em /%定位值,则可能会导致浮动位置。

解决方案

  1. 圆边界
  2. 假设它确实是一个浮动位置,并且只有GPU需要对其进行舍入以使其适合屏幕显示

编辑:被遗忘的解决方案