Comparing element dimensions (float) with mouse coordinates (int) - javascript

I have a <div> on a webpage with the following dimensions:
Using Javascript/jQuery I get the following position and dimensions of that element:
$elem.offset()
{top: 1434.4791564941406, left: 32.222225189208984}
$elem.outerWidth()
930
$elem.outerHeight()
536.788
It seems to me that a MouseEvent contains clientX and clientY (or pageX, pageY) coordinates in "number" type.
Question: Why is it that a onmouseenter event fires with a clientX value of 31 or 32 (depending on how quickly I move the mouse), both of which should be outside of the element’s border box.
Question: Converting floats to integers probably isn’t a good idea because of rounding. So, how do I go about checking the border box here: convert the mouse coordinates to floats? Meaning, that a (1434, 32) mouse coordinate is just outside whereas (1435, 33) is barely inside of the bounding box?

Related

Simulating Mouse event in Microsoft Edge for d3

I'm writing tests and trying to simulate a "mousemove" event. The method I am using which works in Chrome, Firefox, Safari, and IE 10 & 11 is:
var e = new MouseEvent('mousemove',{
"clientX": 250,
"clientY": 100,
});
myElem.dispatchEvent(e);
But it does not work in Edge. The "mousemove" event fires and is caught by my listener, but the position is incorrect. Instead of using the provided coordinates, it appears to use the window origin, 0,0.
My actual code does runs correctly in Edge, so it appears to solely be an issue with simulating the event. But the added complication is this is for a d3 chart and the mouse position is being read with d3.mouse, so I cannot rule out that there is something different in Edge in the interaction between d3.mouse and a mouse event.
Other approaches I have tried include using a CustomEvent and using a PointerEvent, but both seemed to trigger the eventListener, but not even be readable by d3.mouse.
UPDATE
Originally I thought that the specified coordinates were completely ignored; this is not the case. The reality is even more bizarre. If I use absurdly high numbers, then I can get it to register over my element. But real numbers are considered waaay off screen.
For example, if my element getBoundingClientRect gives me:
left: 100,
top: 10,
width: 500,
height: 300
and I use coordinates such as:
var e = new MouseEvent('mousemove',{
"clientX": 350,
"clientY": 150,
});
which should place my cursor over the element, Edge seems to think my cursor it is way off screen. If instead I put in numbers such as:
var e = new MouseEvent('mousemove',{
"clientX": 100000,
"clientY": 50000,
});
Edge will then consider this to be over my element.
The d3.mouse method returns the x,y coordinates of the mouse event relative to the graph container. The clientX and clientY values you are using to simulate the mouse event provide the x,y coordinates of the mouse event relative to the current window. So, the coordinate sets are not the same. You can manually calculate the same coordinate values as the d3.mouse method via:
d3MouseX = clientX - rect.left
d3MouseY = clientY - rect.top
where rect.left and rect.top are the coordinates of the bounding rectangle for the graph object. You can get these coordinates with the e.target.getBoundingClientRect() method.

How to recalculate x,y coordinates based on screensize

I'm have a heat map application and store I store the x,y coordinates of a click and also the viewport width and height. Real data for 2 clicks:
x, y, width, height
433, 343, 1257, 959
331, 823, 1257, 959
The issue is when I resize the screen on the responsive site, the displayed clicks are now all off. I'm coming up empty on my searches but is there a formula or algorithm to recalculate the x and y coordinates for different resolutions. For example, the first click, if the width goes from 1257 to 990 and the height goes from 959 to 400, how to I recalculate the x and y so they line up in the same spot?
EDIT:
I added 2 fields to the database, width_percentage and height percentage
to store the x percentage of the width and the y percentage of the height. So if x was 433 and the width of the screen was 1257 then x was 35% from the left edge of the screen. I then used the same theory for the height and ran the calculations but it did not scale the click dot to the same spot as I though the percentages would do for scaling resolutions. I testing this by clicking on full resolution 1257 width then reopening at 900 width. See below for code to display click dots at lower resolution.
Ajax PHP
while ($row = mysql_fetch_array($results)) {
if( $_GET['w'] < $row['width'] ) {
$xcorr = $row['width_percentage'] * $_GET['w'];
$ycorr = $row['y'];
}
}
This uses the $_GET variable, passing the width and height of the screen resolution on page load. Then it gets the click dots from the database as $results. Since I only scale the resolution width from 1257 to 900 I did not put in calculation for height and its the same pixel as the initial click. The new width I multiplied by the percentage and set the dot that percentage margin from the left of the screen. Since the percentage is 35%
the new x coordinate becomes 900 *.35 = 315px from the left edge. It did not work and I'm still scratching my head on head to keep click in the same spot for responsive sites.
Have you tried this mathematical formula to change the range of a number?
And also instead of storing this:
x, y, width, height
433, 343, 1257, 959
331, 823, 1257, 959
You could store it normalized between 0 and 1 so it works for any width/height (calculated by dividing each x by its width and each y by its height):
x, y
0.344, 0.357
0.263, 0.858
Then you don't need to know the width/height you used when you stored them, and when you want to translate them to the size of the current screen you just multiply each one by the current width/height
You can acheive this by jquery:
$( window ).resize(function() {
//ur code
});
javascript
window.onresize = resize;
function resize()
{
alert("resize event detected!");
}
if you are working on mobile devices use this one also
$(window).on("orientationchange",function(event){
alert("Orientation is: " + event.orientation);
});
I think you are on the right track with the percentages. Are you including the offset of the map image. I wonder if your algo is working but the visual representation appears wrong because the offset is changing in the viewport.
$(window).resize(function() {
var offset = yourMap.offset();
myLeft = offset.left();
myTop = offset.top();
});
You need to add the offsets every time to get the proper placement.
This is what you should do. Sometimes the resize event fires when the document is being parsed. It is a good idea to put the code inside an onload event function. The orientation change function is taken from #Arun answer.
window.onload = function() {
$(window).on("orientationchange", function(event) {
alert("Orientation is: " + event.orientation);
});
window.onresize = function() {
alert('window resized; recalculate');
};
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
for this you need to do some calculation. Here is the function which will return new x and y potion based on the height and width
function getNewX(xVlaue, oldWidth, newWidth){
return xVlaue * newWidth / oldWidth;
}
newX = getNewX(10, 150, 100); // Use
You can use the common function for height and width calc.
DEMO
The whole question highly depends on the page you want to use this on.
Most pages have a centered block and/or some self-resizing (read "responsive") elements. If the page is not very responsive, e.g. having a fixed width, you have an easier job. If the page is centered, you might want to save the cursor's X-position relative to the center of the page. this way the window width doesn't matter. The same also applies to left- and right aligned pages of course - in this case you would save the X-pos relative to the left or right edge of the window respectively.
The following image shows a center-oriented click position. Note that the x- and y properties of the click don't change here if you resize the window.
Now to the more generic methods
If you save the window dimensions, the cursor position AND the scroll offsets on every click, you will most probably be able to reproduce it alongside the layout, but you'll need to reproduce it for every unique dimensions set. If you used the trick from above you might be able to overlay all layouts and find a common denominator. For example, if your page is centered in the window, has a max-width, and you saved the X-pos relative to the center of the window, you can overlay all clicks that happened in windows that were at least that width.
You could do some trickery however, and save the clicked elements alongside the informations you already do save. If you also save the click position relative to the element, you can evaluate this data to something like "the submit button is rather pressed on the bottom right side" or "people often click on the far end of that drop-down and sometimes mis-click by a few pixels".
Try both of the following:
1. Padding and margins might not scale. Use "* {padding:0;margin:0}" at the end of your stylesheet and check if that fixes it.
2. Ensure outer and inner (that means all) elements scale. Any single element failing to scale will make many other elements fall out of place. This generally happens with text inputs. Use "*{border:solid 2}" at the end of your stylesheet to visually observe the effect of scaling on each element.
I'm sure your problem will be resolved.

Javascript comparing mouse click to xy to that of button

I am trying to get the x and y of an html button to that of a mouseclick by the user, I am doing this as follows:
function buttonPressed(event, id){
var mainEvent = event ? event : window.event;
var mousex=event.clientX;
var mousey=mainEvent.screenY;
var y= $('#'+id).position();
var x= document.getElementById(id).offsetLeft;
console.log(y);
console.log(mousey);
This shows 2 different ways to get these value of both the button and the mouse (event.clientX,mainEvent.screenY,$('#'+id).position()(uses jquery),and offsetLeft).
However none of these techniques seem to work as I would like them to as the values do not line up ie when I click on the top left of the button the values are not the same or even similar. Additionally it seems like the difference changes, for example: if I have a button top left and one top right on the top left the values may differ by 100, whereas the bottom they will differ by -100. How can I acheive what I am wanting (to be able to compare the mousex and the button x)?
client X/Y Mouse pointer X/Y coordinate relative to window
offset X/Y Mouse pointer X/Y coordinate relative to element that fired the event
screen X/Y Relative to the top left of the physical screen/monitor
Thats why you are getting difference here
var mousex=event.clientX;
var mousey=mainEvent.screenY;
Use clientX for both

How to get the coordinates clicked on an HTML5 canvas?

I need to get the x and y coordinates of where I clicked on an HTML5 canvas element. I did the following for the y coordinate:
$("#my_canvas").click(function(event) {
alert(Math.floor(event.clientY-$(this).offset().top));
});
This gives me what appears to be the correct y coordinate. The problem is if you scroll down, clientY gets smaller because it seems to be measuring the y coordinate on the screen, disregarding the scrolling. So the above gives a negative number.
What is the proper way to get the x and y coordinate?
Use pageY instead of clientY, so that both the coordinates you compare are relative to the document :
event.pageY-$(this).offset().top

relative mouse coordinates in a DIV - javascript

I'm moving the mouse over a div and I want to know the mouse coordinates with respect to the div origin. (upper left corner)
I expected the mousemove event to contain the relative (client?) coordinates of the mouse, but apparently it doesn't.
In firefox for instance, none of the event properties* contain relative coordinates
Am I missing something?
*clientX,Y - pageX,Y - screenX, y
You're not missing anything, but you'll need to calculate the relative coordinates yourself.
Something along these lines should do it (substitute jquery with w/e code you want to use to get the position):
var pos = $('div').position();
var relX = event.pageX - pos.left;
var relY = event.pageY - pos.top;
Also see: JS: mouse coordinates relative to an element which covers some of the details on supporting other browsers (though if you're using jquery that may not be needed).

Categories