Tracking mouse movements - javascript

This should be typically easy, I want to perform tracking of mouse movements. I'm capable of capturing the XY co-ords.
However, as far as I'm aware, this will vary according to the browser size, right ?
If so, can anyone recommend other things to track to ensure my results are accurate?
P.s I'm using the following Jquery example
$("html").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);
});

Coordinates are independent of the browser size.
Hope this helps. Cheers
PS: Use $(window).mousemove or $(document).mousemove instead of $("html").mousemove, it's a better practice.

Related

How to make mouse double click in JavaScript?

I need a JavaScript code to make mouse double click by itself. I will use it inside my Java code . This one is a selenium project for testing-purposes but there is not any way to make mouse double click in selenium so i want to use javaScript to do that inside my java code . Do you have any idea?
This is old question of me "How to double click any where on web page?"
They said i should use JavaScript to make mouse double click but how ?
To make Mouse Double Click you can write a script and pass it to the executeScript() method as follows :
Script :
String jsDoubleClick =
"var target = arguments[0]; " +
"var offsetX = arguments[1]; " +
"var offsetY = arguments[2]; " +
"var rect = target.getBoundingClientRect(); " +
"var cx = rect.left + (offsetX || (rect.width / 2)); " +
"var cy = rect.top + (offsetY || (rect.height / 2)); " +
" " +
"emit('mousedown', {clientX: cx, clientY: cy, buttons: 1}); " +
"emit('mouseup', {clientX: cx, clientY: cy}); " +
"emit('mousedown', {clientX: cx, clientY: cy, buttons: 1}); " +
"emit('mouseup', {clientX: cx, clientY: cy}); " +
"emit('click', {clientX: cx, clientY: cy, detail: 2}); " +
" " +
"function emit(name, init) { " +
"target.dispatchEvent(new MouseEvent(name, init)); " +
"} " ;
Invoking the script through executeScript() from your #Test :
new Actions(driver).moveToElement(myElem, posX, posY).perform();
((JavascriptExecutor)driver).executeScript(jsDoubleClick, myElem, posX, posY);
As Mozfet says JQuery ! it's so easy with JQuery !
$("#myId").trigger('dblclick');
then you listen for this double click
$("#myId").on('dblclick',function(){
// do it !
});
// you can event make you own event
$("#myId").trigger('retrieve');
then you listen for this custom event
$("#myId").on('retrieve',function(){
// do it !
});
I often use it in datatables : I've got a popover (a small menu on the left td of each row) if the user choose "open modal" i then trigger a double click which goes to the table which is already waiting for a double click from the user on the row. So i don't need to implement 2 events
Using JQuery:
$(selector).dblclick()

event.clientX and event.clientY vs event.x and event.y

When detecting mouse x and y coordinates, is it best to use event.clientX and event.clientY like this:
function show_coords(event){
var x=event.clientX;
var y=event.clientY;
alert("X coords: " + x + ", Y coords: " + y);
}
or use x and y, like this:
function show_coords(event){
var x=event.x;
var y=event.y;
alert("X coords: " + x + ", Y coords: " + y);
}
Is one method better/faster than the other? They seem to work identically to me.
I guess event.x/y are defined only in IEs. A quote from IE documentation:
"event.clientX: Retrieves the x-coordinate of the mouse cursor relative to the client area of the window, excluding window decorations or scroll bars."
"event.x: Retrieves the x-coordinate of the mouse cursor relative to the parent element."
As putvande stated, clientX maybe not cross-browser either. pageX/Y might be a safer choice.

How to zoom to mouse pointer while using my own mousewheel smoothscroll?

Part of my app contains functionality similar to google maps in that the user should be able to zoom in and out on an image within a container.
In the same way that google maps does I want the user to be able to scroll with the mousewheel and the pixel on the image to remain directly under the mousepointer at all times. So essentially the user will be zooming to wherever their mouse pointer is.
For the zooming/translating I am using css transforms like so:
visible
$('#image').css({
'-moz-transform': 'scale(' + ui.value + ') translate(' + self.zoomtrans.xNew + 'px, ' + self.zoomtrans.yNew + 'px)',
'-moz-transform-origin' : self.zoomtrans.xImage + 'px ' + self.zoomtrans.yImage + 'px',
'-webkit-transform': 'scale(' + ui.value + ') translate(' + self.zoomtrans.xNew + 'px, ' + self.zoomtrans.yNew + 'px)',
'-webkit-transform-origin' : self.zoomtrans.xImage + 'px ' + self.zoomtrans.yImage + 'px',
'-o-transform': 'scale(' + ui.value + ') translate(' + self.zoomtrans.xNew + 'px, ' + self.zoomtrans.yNew + 'px)',
'-o-transform-origin' : self.zoomtrans.xImage + 'px ' + self.zoomtrans.yImage + 'px',
'-ms-transform': 'scale(' + ui.value + ') translate(' + self.zoomtrans.xNew + 'px, ' + self.zoomtrans.yNew + 'px)',
'-ms-transform-origin' : self.zoomtrans.xImage + 'px ' + self.zoomtrans.yImage + 'px',
'transform': 'scale(' + ui.value + ') translate(' + self.zoomtrans.xNew + 'px, ' + self.zoomtrans.yNew + 'px)',
'transform-origin' : self.zoomtrans.xImage + 'px ' + self.zoomtrans.yImage + 'px'
});
I have managed to find various implementations of how to go about doing this however I am using a self rolled smooth scroll technique to interpolate the mouse events and provide momentum.
Trying to get the two to work correctly together is proving troublesome.
Rather than paste a whole load of code here I have created a jsFiddle that includes the mousewheel smoothscroll technique along with the zoom function that I have so far.
http://jsfiddle.net/gordyr/qGGwx/2/
This is essentially a fully functioning demo of this part of my app.
If you scroll the mousewheel you will see that the jqueryui slider interpolates and provides the momentum/deceleration correctly. However the zoom does not react correctly.
If you scroll your mousewheel only one point the zoom works perfectly but any further scrolls do not work. I assume this is because the scale of the image has now changed causing the calculations to be incorrect. I have attempted to compensate for this but have not had any luck so far.
So to summarise, I would like to modify the code in my jsFiddle so that the image zooms directly to the mousepointer at all times.
Huge thanks in advance to anyone willing to help.
You can do it more easily with css3 transitions.
Exemple: http://jsfiddle.net/BaliBalo/xn75a/
The main center-mouse algorithm is here:
//Center the image if it's smaller than the container
if(scale <= 1)
{
currentLocation.x = im.width() / 2;
currentLocation.y = im.height() / 2;
}
else
{
currentLocation.x += moveSmooth * (mouseLocation.x - currentLocation.x) / currentScale;
currentLocation.y += moveSmooth * (mouseLocation.y - currentLocation.y) / currentScale;
}
If you want to keep your already-existing code, I think you can do it approximatively the same: the trick to get the mouse position on the zoomed image when the image itself is zoomed by a css scale transform and using transform-origin is to substract the transform origin to your point then multiply by the factor and finally re-add the transform-origin.
You can also use translate as in this updated example: http://jsfiddle.net/BaliBalo/xn75a/15/
As you can see it even simplifies the formulas but don't forget to sub the center of the element to mouse point as a translation of {0, 0} will zoom on the middle of the image.
EDIT:
I stumbled on this answer of mine today and figured it wasn't really the behaviour you wanted. I didn't understand correctly the first time that you didn't want to center the point under the mouse but to keep it in the same spot. As I did it recently for a personnal project I tried to correct myself. So here is a more accurate answer :
http://jsfiddle.net/BaliBalo/7ozrc1cq/
The main part is now (if currentLocation is the top-left point of the image in the container) :
var factor = 1 - newScale / currentScale;
currentLocation.x += (mouseLocation.x - currentLocation.x) * factor;
currentLocation.y += (mouseLocation.y - currentLocation.y) * factor;
I also removed the CSS transition. I think the best way to achieve a smooth scrolling would be to use requestAnimationFrame to create an animation loop and instead of changing values directly in the zoom function, store values and animate towards them in the loop.

Strange behaviour of GestureEvent.rotation on iOS webkit

I am using javascript Gesture events to detect multitouch pan/scale/rotation applied to an element in a HTML document.
Visit this URL with an iPad:
http://www.merkwelt.com/people/stan/rotate_test/
You can touch the element with two finger and rotate it, but sometimes the rotation property goes go astray and my element flips around many full rotations.
Here is part of my code, I am really only taking the value directly from the event object:
...bind("gesturechange",function(e){
e.preventDefault();
curX = e.originalEvent.pageX - startX;
curY = e.originalEvent.pageY - startY;
node.style.webkitTransform = "rotate(" + (e.originalEvent.rotation) + "deg)" +
" scale(" + e.originalEvent.scale + ") translate3D(" + curX + "px, " + curY + "px, 0px)";
}...
What happens is that the value gets either 360 degrees added or subtracted, so I could monitor the value and react to sudden large changes, but this feels like a last resort.
Am I missing something obvious?
I found a solution.
In order to avoid sudden changes in the rotation that don't reflect real finger moves you need to test for that. I do that testing if the rotation changed more then 300 degrees in either direction, if it does then you need to add or subtract 360 depending on the direction. Not really intuitive, but it works.
Fixed page is here:
http://www.merkwelt.com/people/stan/rotate_test/index2.html
Here is the code
<script type="text/javascript">
var node;
var node_rotation=0;
var node_last_rotation=0;
$('.frame').bind("gesturestart",function(e){
e.preventDefault();
node=e.currentTarget;
startX=e.originalEvent.pageX;
startY=e.originalEvent.pageY;
node_rotation=e.originalEvent.rotation;
node_last_rotation=node_rotation;
}).bind("gesturechange",function(e){
e.preventDefault();
//whats the difference to the last given rotation?
var diff=(e.originalEvent.rotation-node_last_rotation)%360;
//test for the outliers and correct if needed
if( diff<-300)
{
diff+=360;
}
else if(diff>300)
{
diff-=360;
}
node_rotation+=diff;
node_last_rotation=e.originalEvent.rotation;
node.style.webkitTransform = "rotate(" + (node_rotation) + "deg)" +
" scale(" + (e.originalEvent.scale) +
") translate3D(" + (e.originalEvent.pageX - startX) + "px, " + (e.originalEvent.pageY - startY) + "px, 0px)";
}).bind("gestureend",function(e){
e.preventDefault();
});
</script>

Rotation of image with Raphael 2 does not work

when I try to animate the rotation of an image (with Raphael 2), which I have done before successfully with Raphael 1, nothing happens.
Animating another property such as height does work.
this.image.animate({rotation: this.angle + " " + this.centerY + " " + this.centerY}, this.animationTime, '<>');
Do you have an idea?
Thanks.
As I see on http://raphaeljs.com/reference.html element.animate does not have an rotation parameter(at least in version 2.0; maybe in earlier version it was there?).
You have to use
this.image.animate({transform:"r"+this.angle + "," + this.centerY + "," + this.centerY}, this.animationTime);
this.image.rotate(45);
I have noticed that the old way has been updated in 2.0.

Categories