I have a mousemove sensor that scrolls the page in the direction the mouse moves, but even though I don't move the mouse, the event calls itself because the page got scrolling so its like the mouse had moved! I just want to get the real event when the mouse moves, not the page event but the client event.
$("body")
.mousemove(function(event){
if ($("#imgc").css("display")!=="block") {
var x = Math.round( ((event.clientX - ($(window).width()/2))/($(window).width()/2)*10) *100 )/100
this.scrollLeft += (x*3);
}
In your code that calculates which way the mouse has moved, use screenX and screenY instead of whatever you're currently using. This will give mouse coordinates relative to the screen, so it shouldn't trigger repeatedly if the mouse doesn't actually move.
Related
Here jsfiddle I have behaviour with mouse
Click (this will show you initial coordinates)
Move mouse whereever you want
On mouseup I want get a distance in px of Y and X from initial position
Now if you make circles around your initial mouse position you can get 100000+ distance. Because it just infinitely added.
Here jsfiddle you can see great example of needed result. BUT, I need to get separate Y and X, and only on mouseup
Rotation in 2D. Language: Javascript
Please tell me how to rotate the object with the mouse. I need to: click on the object with the mouse, rotate it to n degrees, release the mouse button and the object should start rotating according to where I released the mouse button.
Example implemented in 3D on Unity - Example
I'm not going to code this for you but this is the general flow of what you should get happening:
Add an event listener for mousedown().
add an event listener for mouseup().
When mousedown() occurs log the position of mouse.
when mouseup() occurs log the position of the mouse.
calculate the delta between positions.
decide how you translate that data into degrees.
use Animate to change to the rotation attribute of the element accordingly.
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.
After a sleepness night I discovered something about this question which I think is fundamentally mind boggling, at least to me.
Mouse coordinates ARE NOT PRECISE (I guess at a high speed of processing where the whole canvas has to be recreated when movement occurs) as in my codes above. I have tested this code piece by piece and discovered that the problem is not in my loop, but in the precision of
if ((newMouseX !== mouseX) && (newMouseY !== mouseY)).
If you tested this part of code by slower times (which will allow your eyes to detect the difference in coordinates when 'it stops', then you will realise that newMouseX & mouseX are off by 1-2 pixel 90% of the time, > 2 pixel 9% of the time, and only equal about 1% of the time. (I did not measure the statistics but that is what I picked on several rounds of testing).
I can't get it to work in fiddle but I think you can copy it to your testing ground to see what I mean. If you can get it to work in fiddle it would be great so experts can give it a short :)
This means that the mouse is considered to be 'moving' by my code even when it should have 'stopped', and thus 'stops' several times in between, therefore calling the loop too many times in a second, which is the problem I have been having.
I would be happy to hear comments from other experts, including those who can test this and come up with a statistical precision/advice.
My advice, and solution for the moment, is to consider movement when the difference is more than 10 pixels of either coordinates. Of course this presents a problem, but I can leave with that until some better solution comes up.
so instead of
if ((newMouseX !== mouseX) && (newMouseY !== mouseY))
i have used
if (( Math.abs(newMouseX - mouseX) > 10) || ( Math.abs(newMouseY != mouseY) > 10) )
Another thing to consider is how to deal with the mouse position when it goes off my target canvas area... that looks like an infinite movement at the moment!
The Question:
How can I get the precise mouse coordinates so I can compare mouseX & newMouseX?
Thanks.
Mouse precision is determined by the hardware. A high-precision mouse will produce different results than a built-in mouse pad for instance (not to mention touch devices).
However, this is not the problem with your code and your scenario. You are only listening to the mousemove event. It will by definition only throw an event when you move the mouse - hence the new mouse position can never be at the same position as the previous one. That would be impossible and should be off by 100% (unless you are triggering two+ moves where the last goes back to the fist position before you check).
Normally one would listen to the mousedown and mouseup events as well as they are not dependent on a mouse move to trigger. Detecting start and stop solely based on mouse movement is considered impossible under all possible circumstances.
You can do a compromise and make a definition of what a start is and what a stop is, ie. if the mouse has not moved after x milliseconds it is considered a stop (start would be on first move).
This means you will need to follow this rule every time you need to detect a stop. Imaging doing a drawing and sometimes you draw sometime slow other times fast. Or, how do you move the mouse to a new position without drawing anything... There is a good reason for the mouse button(s) to be invented :-)
The rule will soon prove to be useless (or overly complicated prone to more than one error).
As to mouse positions outside canvas there are several ways to handle this.
You can get the canvas bounds by calling:
var canvasRect = canvas.getBoundingClientRect();
which gives you properties to check when mouse position is inside or outside this rectangle.
Another way is to listen to the mouseleave and mouseenter events on the canvas element.
A third is to actually use the mouse buttons. When mouse button is held down on the canvas element you set a flag so mousemove events are considered.
This will keep listening until the mouse button is released. If you release it outside canvas and is using the canvas mouseup event it won't be detected. Therefor you should listen to the window's mouseup event which will trigger in either case.
This also goes for mousemove events. Using the window event will allow you to record positions outside canvas. If you don't want to do this you can use canvas' mousemove which will clip at the canvas' boundaries.
It boils down to:
Use the mousedown, mousemove and mouseup events in combination and you'll be fine. All these events delivers clientX and clientY for mouse positions.
And if I may - you can also test by going to my easyCanvas project and run the sample:
Sample - mouse event details
This will show you details for mouse down, move and up (the details are extended with other information, but you can at least verify mouse positions - do a click without moving and you see the mouse position is exactly the same).
http://jsfiddle.net/6czap/74/
I hope i helped with this :)
$("div").mousemove(function(e){
var pageCoords = "( " + e.pageX + ", " + e.pageY + " )";
var clientCoords = "( " + e.clientX + ", " + e.clientY + " )";
$("span:first").text("( e.pageX, e.pageY ) : " + pageCoords);
$("span:last").text("( e.clientX, e.clientY ) : " + clientCoords);
});
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.