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

时间:2016-11-30 02:17:11

标签: 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>

加载页面时,您会在页面左上角看到画布为蓝色矩形。将鼠标移到它上面,画布中的文本会发生变化,将鼠标位置显示为两个整数,分别为X和Y各一个。

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

#myCanvas {
  background-color: cornflowerblue;
  margin-left: 30px;
  margin-top: 30px;
} 

当我现在渲染页面时,画布的蓝色矩形偏离页面的顶部和左侧,如我所料。但是将鼠标移到画布上现在有了X和Y鼠标坐标,这些坐标在画布中显示为具有许多小数位的浮点数。稍微跟踪代码,似乎getBoundingClientRect()返回一个矩形,其中值的顶部和左侧是浮点数。

我认为我可以做一些事情,比如截断或舍入getBoundingClientRect()返回的值,但这感觉就像是错误的方式去找我。

我是否错误地使用了getBoundingClientRect(),或者它是否应该返回浮点值?

在收听各种鼠标事件时,是否有明确的方法可以在画布上获得鼠标的精确X和Y坐标?

1 个答案:

答案 0 :(得分:5)

tldr;你在浏览器中进行了缩放/取消缩放。

问题

margin-left: 30px;

在这个jsfiddle模仿你的问题时它不像你在导航器缩放设置为100%(正常)时在电脑上说的那样有效。但如果你在浏览器中放大,你会发现这种行为。

margin-left: 11%;

相反,如果您在此jsfiddle中使用%保证金,您会发现它确实会返回浮动鼠标位置,是否打开了缩放。

答案

事情是鼠标位置是在屏幕上显示时计算的:它可能只有整个位置坐标,因为它是基于像素的。

然而,getBoundingClientRect在应用边距,缩放和其他修改器但在告诉GPU渲染之前,返回浏览器计算为“边界客户端矩形元素”。简而言之,它返回元素的实际位置,该元素稍后由GPU近似以在像素矩阵内呈现。如果使用像素边距/尺寸/填充/等,则元素位置保持整数,但如果缩放或使用em /%定位值,则可能导致浮动位置。

解决方案

  1. round bounds
  2. 假设它确实是一个浮动位置,只是GPU需要围绕它以使其适合屏幕
  3. 编辑:遗忘的解决方案