Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firing Mouseout Event depends on Window Size

I want to draw on a 3D-transformed canvas, but have some weird problems with the mouseout event in Chrome.

When I set the JSFiddle window size to 2100px, the mouseout event works as excepted.

enter image description here

However, when I set the window size to 1900px, the mouse event triggers approximately at the red line.

enter image description here

This is really weird, since the JSFiddle window size determines if the mouse out event is triggered correctly.

Until here the mouse out event is triggered correctly in Firefox and Edge, but doesn't work correctly in Chrome! In addition, we saw some weird behaviour when playing around with the scrolling position (e.g. by adding some <br>'s and scrolling affects the mouse out event position), window sizes (see images above) or the width of the canvas (e.g. setting the canvas width to 200 triggers the mouse out event correctly).

Is there anyone who can help me solving this bug, such that the browser fires the mouseout event correctly independent of the window size or scroll position?

Code: JSFiddle

Demo: YouTube

Snippet of code in fiddle:

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

.dynamic-drawing-canvas {
  pointer-events: auto;
  background-color: blue;
}
<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>
like image 248
wuiwuiwui Avatar asked Sep 08 '21 10:09

wuiwuiwui


People also ask

What is Mouseout event?

The mouseout event is fired at an Element when a pointing device (usually a mouse) is used to move the cursor so that it is no longer contained within the element or one of its children.

Which event is triggered when mouse enters a specific region?

The mouseenter event is fired at an Element when a pointing device (usually a mouse) is initially moved so that its hotspot is within the element at which the event was fired.

Which of the following events fires when a user moves the mouse pointer off of an element?

If you depress the mouse button on an element and move your mouse off the element, and then release the mouse button. The only mousedown event fires on the element. Likewise, if you depress the mouse button, and move the mouse over the element, and release the mouse button, the only mouseup event fires on the element.

How can I detect when the mouse leaves the window?

To detect when the mouse leaves the window with JavaScript, we can add the mouseleave event to document . For instance, we can write: document. addEventListener("mouseleave", (event) => { if (event.

What is the use of mouseout event?

The mouseout event is fired at an Element when a pointing device (usually a mouse) is used to move the cursor so that it is no longer contained within the element or one of its children. mouseout is also delivered to an element if the cursor enters a child element, because the child element obscures the visible area of the element.

What is the difference between mouseout and mouseLeave?

The following examples show the use of the mouseout event. The following example illustrates the difference between mouseout and mouseleave events. The mouseleave event is added to the <ul> to color the list purple whenever the mouse exits the <ul>. mouseout is added to the list to color the targeted element orange when the mouse exits it.

When does the resize event fire?

The resize event fires when the document view (window) has been resized. In some earlier browsers it was possible to register resize event handlers on any HTML element. It is still possible to set onresize attributes or use addEventListener () to set a handler on any element.

Is it possible to set OnResize event on a specific element?

It is still possible to set onresize attributes or use addEventListener () to set a handler on any element. However, resize events are only fired on the window object (i.e. returned by document.defaultView ).


1 Answers

It looks like you are running into an issue with the container of the canvas.

Some notes on what is happening: The canvas is generated at 1200px and 300px for width/height using the properties in the markup: width="1200" height="300" You can override this in the <canvas> tag directly or with JavaScript. Why CSS resize has issues: What the CSS does is to resize the existing canvas to a new size. When a typical/most HTML component is resized the browser handles this fine. The difference is <canvas> is a collection of pixels. When you change with CSS these pixels become altered (stretched out or shrink down) and the image on the canvas gets a different look. Note also that the blank canvas is also stretched so drawing to it has challenges and might/does not work as expected.

Here I adjust your canvas to fit the container using JavaScript on these properties but really only for an example - your size will vary.

I added some borders so you can see things - I put some logs in place to show where it changes and the mouseout fires since it now fits inside the container - I scaled it to fit using the 1.1 and moved the style to the CSS so I could add comments from before to after.

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);
  });
#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);
}
<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>
like image 155
Mark Schultheiss Avatar answered Oct 19 '22 03:10

Mark Schultheiss