Jquery pageX and screenX from event is negative on second monitor - javascript

While my function works on my first monitor like it should on my second monitor all coordinates of event are negative. Like its referent point is still on my primary monitor. Event is triggered on drag and drop from html5.
function endDnD(e) {
var parentOff = $(this).parent().offset();
console.log(e);
console.log(e.pageX, e.pageY, parentOff.left, parentOff.top);
var posX = e.screenX - parentOff.left;
var posY = e.pageY - parentOff.top;
$(this).css('left', posX);
$(this).css('top', posY);
}

I think you need to add this into your equation:
window.screen.availLeft
that returns a 0 value if it's the primary screen (left screen by default) or the width of the primary screen as the starting point of the right screen.
look for information and example here:
https://developer.mozilla.org/en-US/docs/Web/API/Screen/availLeft
Note that while this is information on Mozilla's site it should also work for other popular browsers

To get an X coordinate on the current screen you can use:
e.clientX
instead of e.pageX. That will return a x > 0 value.

Related

Mapping mouse click coordinates on heatmap for different resolution & screen sizes in JS/Jquery

I would like to collect mouse click data from a webpage which is accessed on different resolutions & screen size devices and accurately map those click coordinates on an overlay for displaying heatmap. How can I do it in JavaScript/jQuery? Also, considering the case when the page being displayed can be scrolled up/down and browser window resized anytime by the user thus changing the relative positions of the DOM elements at the screen. For example, I have a main div wrapper as container of the documents and two divs as columns inside. Normally, the columns will be shown side by side to each other inside the wrapper div. But when the user resizes the page to a smaller size, the column to the right will move and sit under the 1st column. So, its X and Y offset has changed according to the page. Now, if a user clicks on this 2nd column, the clicks won't map accurately to screen when I see the heatmap on my device in full page viewI'm a beginner, so I would need to know the details.
I am working on same thing to collect click coordinates to be plotted on heatmap. The method I used is to get the click coordinate and converting them into pixel average relative to the document and then when plotting again convert them into coordinates.
window.addEventListener("click",function(){
var posx = 0;
var posy = 0;
TotalX = document.body.scrollWidth;
TotalY = document.body.scrollHeight;
if (!e) {
var e = window.event;
}
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
console.log("X" + ((posx * 100)/TotalX)); //Just For Debugging
console.log("Y" + ((posy * 100)/TotalY)); // For Debugging
return {
x : ((posx * 100)/TotalX),
y : ((posy * 100)/TotalY)
};
});
The coordinates are not found relative to document would work pretty well in desktop clicks but Not with mobile clicks. You can put a condition to avoid mobile clicks or can record them differently.

Retreiving coordinates of a click inside a div for modern browsers?

For modern browsers (IE 10+, FF, Safari, Chrome): It looks like you would have to use the facade pattern to build a consistent interface and do a lot of fiddling using this info.
I'm looking for a simple modern way to determine the x, y coordinates of where a user clicked in a div and use those coordinates to position a pie menu as determined in this SO Question.
No libraries unless used to show concept.
Reference
What is the difference between screenX/Y, clientX/Y and pageX/Y?
Here is a google hit that shows 3 different event properties
You could try
element.onclick = function(e) {
var x = e.pageX - element.offsetLeft // the absolute x position
// minus the element's absolute x position
var y = e.pageY - element.offsetTop
alert('x : ' + x + ', y : ' + y)
}
Here is a fiddle
the following will give you the coordinates for any div clicked in the page; for a specific div replace 'div' with '#yourDivId'
$(document).ready(function(){
$('div').click(function(e){
var x = e.pageX;
var y = e.pageY;
alert(...);
});
});

How to get the correct mouse position in relation to a div that has has a scale transform applied

I am using CSS transform scale to create a smooth zoom on a div. The problem is that I want to be able to get the correct mouse position in relation to div even when scaled up, but I can seem figure out the correct algorithm to get this data. I am retrieving the current scale factor from:
var transform = new WebKitCSSMatrix(window.getComputedStyle($("#zoom_div")[0]).webkitTransform);
scale = transform.a;
When I read the position of the div at various scale settings it seems to report the correct position, i.e. when I scale the div until is is larger the the screen the position left and top values are negative and appear to be correct, as does the returned scale value:
$("#zoom_div").position().left
$("#zoom_div").position().top
To get the current mouse position I am reading the x and y position from the click event and taking away the offset. This works correctly at a scale value of 1 (no scale) but not when the div is scaled up. Here is my basic code:
$("#zoom_div").on("click", function(e){
var org = e.originalEvent;
var pos = $("#zoom_div").position();
var offset = {
x:org.changedTouches[0].pageX - pos.left,
y:org.changedTouches[0].pageY - pos.top
}
var rel_x_pos = org.changedTouches[0].pageX - offset.x;
var rel_y_pos = org.changedTouches[0].pageY - offset.y;
var rel_pos = [rel_x_pos, rel_y_pos];
return rel_pos;
});
I have made several attempts at multiplying dividing adding and subtracting the scale factor to/from from the pageX / Y but without any luck. Can anyone help me figure out how to get the correct value.
(I have simplified my code from the original to hopefully make my question clearer, any errors you may find in the above code is due to that editing down. My original code with the exception for the mouse position issue).
To illustrate what I am talking about I have made a quick jsfiddle example that allows the dragging of a div using translate3d. When the scale is normal (1) the div is dragged at the point where it is clicked. When the div is scales up (2) it no longer drags correctly from the point clicked.
http://jsfiddle.net/6EsYG/12/
You need to set the webkit transform origin. Basically, when you scale up it will originate from the center. This means the offset will be wrong. 0,0 will start in the center of the square. However, if you set the origin to the top left corner, it will keep the correct coordinates when scaling it. This is how you set the origin:
#zoom_div{
-webkit-transform-origin: 0 0;
}
This combined with multiplying the offset by the scale worked for me:
offset = {
"x" : x * scale,
"y" : y * scale
}
View jsFiddle Demo
dont use event.pageX - pos.left, but event.offsetX (or for some browser: event.originalEvent.layerX
div.on('click',function(e) {
var x = (e.offsetX != null) ? e.offsetX : e.originalEvent.layerX;
var y = (e.offsetY != null) ? e.offsetY : e.originalEvent.layerY;
});
see my jsFiddle exemple: http://jsfiddle.net/Yukulele/LdLZg/
You may embed the scaled content within an iframe. Scale outside the iframe to enable scaled mouse events within the iframe as mouse events are document scope.

Html5 Drag and Drop Mouse Position in Firefox

I have an HTML5 application which utilizes drag and drop. Essentially the user can drag an image from a "drawer" onto a canvas to create a larger image. I want the elements to drop in the place where they were release. I have this working in all browsers except Firefox.
On the drop event, I am using the following to get the coordinates of the mouse, and calculate the position of the dropped image within the canvas.
var top = evt.originalEvent.offsetX;
var left = evt.originalEvent.offsetY;
The issue is, this property is not available in FF. Is there any other way to get this? Without it, I can't see how to possible drag and move elements within FF.
Note: I am not using the canvas element. I am dropping images to a div. Not sure if that matters.
Try this in firefox..
var X = event.layerX - $(event.target).position().left;
var Y = event.layerY - $(event.target).position().top;
I tried using layerX and layerY but mysteriously they were different from same values in Chrome.
Then I realized that on a Retina display Firefox setDragImage won't take the scale into account.
In other words, calling setDragImage(div, 10, 10) would place the cursor at 5px; 5px point.
Ridiculous, isn't it?
var originalEvent = e.originalEvent,
offsetX = originalEvent.offsetX,
offsetY = originalEvent.offsetY;
if (_.isUndefined(offsetX) || _.isUndefined(offsetY)) {
// Firefox doesn't take scale into account so we need to compensate for it
offsetX = originalEvent.layerX * (window.devicePixelRatio || 1);
offsetY = originalEvent.layerY * (window.devicePixelRatio || 1);
}
originalEvent.dataTransfer.setDragImage(el, offsetX, offsetY);
I tried Kathirvans answer above but it didnt work for me. The magic potion for my page was...
var x = e.originalEvent.pageX - $(this).offset().left;
var y = e.originalEvent.pageY - $(this).offset().top;

How to log a click at an xy coordinate that remains reliable regardless of page design

I'm creating a website heat map. I know how to get the xy coordinate of a click, but on pages in centered divs the xy coordinate of the click varies based on the user's browser window width.
How do I log a consistent xy so that I can display the location of the click later regardless of the window size?
I can use jQuery's offset() to get the xy based on some centered parent element. But I'm placing this heat map on multiple sites. So given that each site's markup is unique, how do I determine what top level "wrapper" element should be used to calculate the offset?
Is there some simpler method I'm overlooking?
How about saving not only the x/y coordinates of the click but also the width/height of the view-port. That way you can get the position of the click relative to the view-port and calculate where on the content the click actually occured:
$(document).on('click', function (event) {
var x = event.pageX,
y = event.pageY,
w = $(window).width(),
h = $(window).height();
});
You could optimize this by only getting the view-port dimension when they change:
var windowWidth = 0,
windowHeight = 0;
$(window).on('resize', function () {
windowWidth = $(this).width();
windowHeight = $(this).height();
}).trigger('resize');//this .trigger will get the dimensions on page-load
$(document).on('click', function (event) {
var x = event.pageX,
y = event.pageY,
w = windowWidth,
h = windowHeight;
});
Update
For pages that are centered you could get the coordinate from the center of the view-port:
var windowWidth = 0,
windowHeight = 0;
$(window).on('resize', function () {
windowWidth = $(this).width();
windowHeight = $(this).height();
}).trigger('resize');//this .trigger will get the dimensions on page-load
$(document).on('click', function (event) {
var x = (event.pageX - (windowWidth / 2)),
y = event.pageY;
});
This will result in positive x dimensions for anything on the right side of the page and negative x dimensions for anything on the left side of the page.
Here is a demo: http://jsfiddle.net/aWBFM/
Have you tried using the <body> element? I know in HTML5 it isn't necessary, but I haven't ever come across an instance where it isn't used (and there is clicking involved).
Well according to the offset() documentation it retrieves the coordinates relative to the document, which is what you want. What you need to do is get the window height and width. Then using a bit of maths, calculate the distance between the window and the map.
$(window).width() and
$(window).height() will get you what you need.
You should be able to get the position of the mouse relative to the top left corner of the page by looking at event.clientX and event.clientY.
If you want the position of the mouse relative to a particular object, you can look at the offsetTop and offsetLeft properties of that object. (event.clientX - obj.offsetLeft) would be the position of the mouse relative to the object.

Categories