触发鼠标悬停事件取决于窗口大小

wui*_*wui 18 html javascript google-chrome mouseout jsfiddle

我想在 3D 转换的画布上绘图,但 Chrome 中的 mouseout 事件遇到一些奇怪的问题。

当我将 JSFiddle 窗口大小设置为 2100px 时,mouseout 事件会正常工作。

在此输入图像描述

但是,当我将窗口大小设置为 1900px 时,鼠标事件大约在红线处触发。

在此输入图像描述

这真的很奇怪,因为 JSFiddle 窗口大小决定了鼠标移出事件是否被正确触发。

到目前为止,鼠标移出事件在 Firefox 和 Edge 中可以正确触发,但在 Chrome 中无法正常工作!此外,我们在使用滚动位置(例如,通过添加一些<br>' 并滚动影响鼠标移出事件位置)、窗口大小(参见上图)或画布宽度(例如,设置画布)时看到了一些奇怪的行为width 为 200 可以正确触发鼠标移出事件)。

有谁可以帮助我解决这个错误,以便浏览器正确地触发 mouseout 事件,而与窗口大小或滚动位置无关?

代码:JSFiddle

演示:YouTube

小提琴中的代码片段:

$(".dynamic-drawing-canvas").on("mouseout", function(e) {
  console.log(e.clientX, e.clientY)
})
Run Code Online (Sandbox Code Playgroud)
#container {
  pointer-events: none;
  margin-left: 400px;
}

.dynamic-drawing-canvas {
  pointer-events: auto;
  background-color: blue;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
  <canvas class="dynamic-drawing-canvas" width="1200" height="300" style="
    transform: matrix3d(1.0303, 0.00317459, 0, 2.13211e-05, -0.68458, -0.165542, 0, -0.00111181, 0, 0, 1, 0, -34.7412, 264.118, 0, 1);
    transform-origin: left top;
"></canvas>
</div>
Run Code Online (Sandbox Code Playgroud)

Mar*_*iss 1

看起来您遇到了画布容器的问题。

关于所发生情况的一些注释:使用标记中的属性以 1200px 和 300px 的宽度/高度生成画布:width="1200" height="300"您可以直接在标签中或使用 JavaScript 覆盖它<canvas>。为什么 CSS 调整大小会出现问题:CSS 的作用是将现有画布的大小调整为新的大小。当调整典型/大多数 HTML 组件的大小时,浏览器可以很好地处理此问题。区别在于<canvas>像素的集合。当您使用 CSS 进行更改时,这些像素会发生改变(拉伸或缩小),并且画布上的图像会呈现不同的外观。另请注意,空白画布也会被拉伸,因此在其上绘图会遇到挑战,并且可能/无法按预期工作。

在这里,我使用 JavaScript 在这些属性上调整画布以适合容器,但实际上仅作为示例 - 您的尺寸会有所不同。

我添加了一些边框,这样你就可以看到东西 - 我放置了一些日志来显示它的变化和火灾,mouseout因为它现在适合容器内 - 我缩放它以适应使用1.1并将样式移动到 CSS,以便我可以添加从之前到之后的评论。

console.clear();
let canvas = document.getElementById("c");

let width = canvas.width;
let height = canvas.height;
console.log("CW:", width, "CH:", height);
let rect = canvas.parentNode.getBoundingClientRect();
canvas.width = rect.width;
canvas.height = rect.height;

width = canvas.width;
height = canvas.height;
let r = canvas.getBoundingClientRect();
let ctop = r.top;
let cleft = r.left;
console.log("T:", ctop, "L:", cleft, "W:", width, "H:", height);
$(".dynamic-drawing-canvas")
  .on("mouseout", function(e) {
    // console.log(e.clientX, e.clientY);
    console.log("Screen X/Y:", e.screenX, e.screenY, "Client X/Y:", e.clientX, e.clientY);
    console.log("X:", e.screenX - e.clientX);
    console.log("Y:", e.screenY - e.clientY);
  });
Run Code Online (Sandbox Code Playgroud)
#container {
  pointer-events: none;
  position: absolute;
  top: 0;
  left: 0;
  margin-left: 0px;
  width: 90%;
  height: 100%;
  border: solid red 3px;
}

.dynamic-drawing-canvas {
  pointer-events: auto;
  background-color: blue;
  object-fit: none;
  object-position: top left;
  transform-origin: left top;
  /* pulled out of markup, alter for 2.13211e-5 */
  /*
  transform: matrix3d(
  1.0303, 0.00317459, 0, 0.0000213211,
  -0.68458, -0.165542, 0, -0.00111181,
  0, 0, 1, 0,
  -34.7412, 264.118, 0, 1
  ); 
  THEN adjusted the 
      following transformations:
         0, 30, 0, 1.1
        Translates every X point by 0px
        Translates every Y point by 30px
        Translates every Z point by 0
        Scales down by 10%
*/
  transform: matrix3d(1.0303, 0.00317459, 0, 0.0000213211, 0.68458, 0.165542, 0, 0.00111181, 0, 0, 1, 0, 0, 30, 0, 1.1);
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
  <canvas id="c" class="dynamic-drawing-canvas" width="1200" height="300"></canvas>
</div>
Run Code Online (Sandbox Code Playgroud)