So I can make an element move with the mouse, however the problem is the offset is calculated from the top left corner of the element and doesn't take into account the mouse's position within the element causing the object to leap towards the mouse and preventing you from dragging it upwards or left.
So I came up with this function:
handle.on("mousemove", function(e) {
if (state.dragging) {
var paneOffset = pane.offset();
var mouseOffset = {
'top': e.pageY - paneOffset.top,
'left': e.pageX - paneOffset.left
}
pane.offset({
top: e.pageY - mouseOffset.top,
left: e.pageX - mouseOffset.left
});
}
});
Example: http://jsfiddle.net/SEKxc/
The problem with this is it stops the element from moving as it always calculates the element's same exact offset. How would I make the element follow the mouse but relative to the mouse's position with the object.
I am aware of jQueryUI having this functionality built-in but don't want to use that.
You could calculate the initial mouseoffset on dragstart and hence use it as a global variable from within the mousemove handler. Since the dragstart starts before mouse move i dont see a problem.
Update: you need to store both the objects initial offset and the mouses initial offset and calculate the relative offset of the mouse compared to the original on mouseMove then apply the same transformation to the element.
Store the distance between the mouse position and the element top left corner when you start dragging. Then you just subtract those from the mouse position to calculate the element position when the mouse moves.
Related
How can I calculate offsetX and offsetY of the mouse cursor, relative to an element being transformed, even though the mouse is not moving?
https://jsfiddle.net/kevin_dorion/usrLd1x3/34/
// this is the value I need to update, even when the mouse is not moving
offsetEl.innerHTML = `x: ${evt.offsetX} y: ${evt.offsetY}`;
As you can see, on mousemove, I get the offsetX and offsetY values, which are exactly what I need. But I also need to be aware of these values changing when the mouse is not moving.
requestAnimationFrame(animate);
// how do I manually calculate offsetX and offsetY of the mouse cursor relative to the "el" element when the mouse is not moving?
I was thinking of keeping the last mouse event, use the pageX/pageY to position an element, then calculate its offset, but I can't get it working properly.
Thank you!
EDIT: I was thinking of storing the last known matrix / mouse coordinates combinaison, use the current matrix and make some interpolation, but I can't get it right either...
I was wondering how you would be able to use the 'enddrop' event listener to change the position of an element.
I tried using this:
document.addEventListener('dragend', e => {
e.target.style.left = e.clientX;
e.target.style.top = e.clientY;
});
This works, but it's looks un-natural because the coordinates of the upper-left of the element are changed to the mouse position. So, if the user drags the element by the upper-left point it will work perfectly, but if you drag anywhere else on the element, it gives it a snappy effect because the upper-left corner will snap to the mouse's position.
Thanks!
I recently solved a similar problem:
follow the link: Prevent drop event when it's already have child element ? Drag and Drop
at the moment you start drag(dragstart) you calculate the top and left offset based on the element and mouse position
and at the end drag(dragend) event you use this offset to adapt as needed.
let offset = [0, 0] // initial state offset x, y
function dragStart(ev) {
// your code..
offsetX = ev.target.offsetLeft - ev.clientX
ev.target.offsetLeft - ev.clientX,
ev.target.offsetTop - ev.clientY
]
}
Any doubt put the code that I can help you.
Hope this helps.
I need to track mouse position relative to a <canvas> element in my app. Currently, I have a mousemove event listener attached to the <canvas> that updates my mouse position whenever it fires, using offsetX/offsetY when available, or layerX/layerY when the offsetX/Y is not available. Using offsetX/Y or layerX/Y gives me mouse coordinates relative to my <canvas>, which is exactly what I want. As my app works its magic, various CSS 3d transformations get applied to the <canvas>, and even when <canvas> is very transformed, offsetX/Y still gives me accurate coordinates within the <canvas>'s local, transformed coordinate-space.
That's kind of confusing, so I'll try stating an example. If my <canvas> is 100px in both width and height, and is located at (0,0) relative to the browser viewport, and I click at (50,50) (in viewport coords), that corresponds to (50,50) in my <canvas>, and 50 is the value that is (correctly) returned via offsetX and offsetY. If I then apply transform: translate3d(20px,20px,0px) to my <canvas> and click at (50,50) (in viewport coords), since my canvas has been shifted 20px down and 20px to the right, that actually corresponds to (30,30) relative to the <canvas>, and 30 is the value that is (correctly) returned via offsetX and offsetY.
The problem I'm facing is what to do when the user is not physically moving the mouse, yet the <canvas> is being transformed. I'm only updating the position of the mouse on mousemove events, so what do I do when there is no mousemove?
For example. My mouse is positioned at (50,50) and no transformations are applied to the <canvas>. My this.mouseX and this.mouseY are both equal to 50; they were saved at the final mousemove event when I moved the mouse to (50,50). Without moving the mouse at all, I apply the above transformation (transform: translate3d(20px,20px,0px)) to my <canvas>. Now, I need this.mouseX and this.mouseY to each be equal to 30, as that is my mouse's new position relative to the current transformation of <canvas>. But this.mouseX and this.mouseY are still equal to 50. Since I never moved the mouse, there was no mousemove event fired, and those saved coords never got updated.
How can I deal with this? I thought about creating a new jQuery event, manually assigning some properties (pageX and pageY?) based on my old/previous mouse position, and then triggering that event, but I don't think that's going to cause the browser to recalculate the offsetX and offsetY properties. I've also been thinking about taking the known old/previous mouse position and multiplying it by my transformation matrix, but that's going to get real complicated since my mouse coordinates are in 2d-space, but the transformations I'm applying to <canvas> are all 3d transformations.
I guess really, what I want to do is take my known 2d page position and raycast it into the 3d space and find out where I'm hitting the transformed <canvas>, all in javascript (jQuery is available).
Is this possible? Does this even make sense?
Works in all browsers
var mouseX=0;
var mouseY=0;
var canvas = document.querySelector('#canvas');
var rect = canvas.getBoundingClientRect();
document.onmousemove = function(e) {
mouseX=e.clientX-rect.left;
mouseY=e.clientY-rect.top;
};
function updateCoords() {
mouseX=e.clientX-mouseX;
mouseY=e.clientY-mouseY;
setTimeout(updatecoords,10);
}
Now we can call updateCoords() function once to repeatedly check for new position.
updateCoords();
You can add your code inside the updateCoords() function and it will be executed each 10 milliseconds
Concept: mouseX and mouseY variables get updated on mousemove event, and also get updated when there is any change in the canvas position.
It looks like you want to refresh your mouseposition-values even if you don't move your mouse. You should try something like this:
var event = '';
var counter = 1;
$(function(e){
event = e;
window.setInterval(refresh, 10);
});
$(document).mousemove(function(e){
event = e;
refresh;
});
function refresh(){
counter++;
$('#mousepos').val("event.pageX: " + event.pageX + ", event.pageY: " + event.pageY + ", counter: " + counter)
}
The counter is just for visualisation of the refresh. You can set the interval to everything you want (10 = 10ms = 0.01s) Just move everything from your .mousemove() event into this refresh() function and call it properly and your mouse position should update even if you don't move your mouse.
Look at this fiddle for a life example: http://jsfiddle.net/82cmxw8L/1
EDIT:
Because my fiddle didn't work for the asker, i updated it: http://jsfiddle.net/82cmxw8L/8/
New is, that the mouseposition is now set every 0.1 Second, no matter what, rather than being updated only when the mouse moves.
I get mouse coordinates on some web page and save them.
$("div#container").mousemove( function(e) {
client_x = e.pageX;
client_y = e.pageY;
// save x,y
});
Now other person load that same page and i want to show them the same coordinates (x,x position).
How can I get the same point if I have to take in consideration that the div#container is not at same position as it was in my browser (considering screen resolution and scroll)?
I would use $.offset().top and $.offset().left of the parent div container, and calculate the difference from that to the current X and Y coordinates of the mouse cursor.
.offset() always refers to the document and not to the parent of the element.
For example:
$('#element').mousemove(function(e){
var client_x = e.pageX;
var client_y = e.pageY;
var elementOffset = $(this).offset();
client_x -= elementOffset.left;
client_y -= elementOffset.top;
// save x, y.
});
Then, on the other users display, show the coordinates after adding them to his offsets.
This doesn't seem possible because of the variables you mentioned in the question. Screen resolution is the main reason, but, also, it depends on how big their window is. At first, you might think that you could compute the mouse's position relative to fixed points, like divs shown (take Stack Overflow, for example, where the main container of the site doesn't resize with the browser window). But if their window is smaller than the container, you would be making some false assumptions about what they see.
That being said, you can always just compute the mouse position relative to fixed elements you know will be on the screenusing $.offset() and just assume they have their screen showing everything (or check $(window) size) and are using "normal" viewing conditions.
You can use the values returned by offset(), in your example:
$("div#container").offset().left
and
$("div#container").offset().top
to substract them to e.pageXand e.pageY.
offset() function gives you the matched element's position relative to the document (see the docs), so there's no problem if the users scroll down.
Example: http://jsfiddle.net/3jMRS/
I want to get mouse co-ordinates on a button click. If I use event.pageX, it returns the mouse co-ordinates relative to document. How can I convert or get the value relative to view port?
I'm not entirely clear on what you're asking, but if you're looking to get the mouse position relative to an element:
$("input").focus(function(e){
var relativeX = e.pageX - this.offsetLeft;
var relativeY = e.pageY - this.offsetTop;
});
Subtract the scroll position (scrollTop/scrollLeft) of the document from your coords to get it relative to the view port.
It should be the your current position relative to the document - current scroll position
What are you really trying to achieve? You could just wrap the button with a div and get the x,y relative to the div itself. Perhaps I am being redundant.