Javascript - Mouse Location

A variety of applications depend on determining the mouse location. Many of the references on the web provide WRONG methods. Part of this is that a specific method works in one browser, but not in others. Some work in specific versions.

This is a complete mess which this page hopes to clarify.

Background | Test region | Getting data from Images | Suggested code (that fails) | Working Code


Background

I currently have 2 general applications where I need to know the xy-position of the mouse with respect to a canvas. In the future, I will also need to locate lines on a graph.

Unfortunately, javascript security prevents the code from determining the color of pixels in an image. If this was not the case, then it would be possible for code to disable the image captchas used to verify that you are a person and not a program. There are a couple of ways around that, but


Test region

These are 2 canvases - at slightly different xy-locations - are used to test the code. Each canvas is 200x200 with a target located at (100,100). As you move the mouse, various values will be displayed in the table to the right. The lower table contains values from various browsers with the cursor centered (as close as I can) on the target at 100,100. The canvas.offsetTop values depend on the window width and how the table to the right of the canvases is formatted (how many lines it requires).

For the browsers that support it, clientXY and XY are the same. However, Firefox does not support XY.

I don't understand how subtracting one integer from another produces a non-integer result.


Getting data from Images

When creating a color picker, both this article and mozilla.org suggest using an image (a png file) and reading the color (a pixel) from that. Unfortunately, this technique produces a security error.

As mentioned above, this is a reasonable security measure. Without it, malicious code would be able to read images and do bad stuff. I found a work around, but it requires a server modification and is "browser dependent". Since

that "fix" is not acceptable.

To be clear - when the javascript file and image are both stored in the same directory on a local machine, Chrome produces the security error. As a result, for me, this is a show stopper.

Also, neither of these references even mentions this "problem".


Suggested code (that fails)

Both references mentioned above suggest code to get the color from an image pixel under the mouse cursor. To be clear - both methods FAIL!

By comparing the examples below and the tables above, it should be obvious that both sources are clueless. The numbers are from a debug session using Chrome 49 on Windows XP.

The (very poorly documented) problem with the first suggestion is that canvas.offsetLeft and canvas.offsetTop refer to the canvas position relative to the object that contains it unless it is placed directly in the page body. In that case, they are referenced to the viewport and there is no problem. However, when the canvas is placed in a table (which I usually do), then the offsets are with respect to the top left corner of the table! On the other hand, e.clientX and e.clientY are always referenced to the viewport . Using the images above, when you scroll the page the e.clientY value for the target changes. The solution (shown in the next section) is to use getBoundingClientRect() to get the canvas location relative to the viewport ... and not the table or some other UI component. (Note - the viewport is the visible part of the window.)

w3schools.com documents these mouse event properties (only the X-versions are shown)

but has no information on layerX. Apparently (back in 2000), some browsers (Firefox) supported layerX and others (Opera) supported offsetX. The following code (from the 2011 reference) might provide a solution (work around). According to Cross-browser mouse positioning (2012), "only clientX, clientY, screenX, and screenY are part of the W3C Spec".

At any rate, in Chrome 55 on Windows 10, layerX is OK, but layerY provides the wrong value (-1841). In fact, offsetX and offsetY appear to contain the "correct" values. (Since they aren't in the spec, I did not bother to test them.)

This browser incompatibility problem is simply a nightmare!


Working Code

The solution is to use getBoundingClientRect() to get the canvas location relative to the viewport ... the visible part of the window.

This is the code I used with GHCN_Temperature_Plotter.html

This is similar to the code used above to get usable, browser independent, values.


Author: Robert Clemenzi
URL: http:// mc-computing.com / Languages / Javascript / MouseLocation.html