What\'s the best way to track the mouse speed with plain JS/JQuery? I\'d like to track how fast a user moves the mouse in all directions (up/down/left/right).
With current modern browser we can now use movementX or movementY to detect mouse's movement speed. Before you want to use it you should see the compatibility table because older browser will have a prefix like webkitMovementX
.
document.addEventListener("mousemove", function(ev){
console.log(`Movement X: ${ev.movementX}, Y: ${ev.movementY}`);
}, false);
The result above is not an average speed like pixel/second but it's total movement between triggered mousemove
event. If you need px/s
then you can do it like below:
var totalX = 0;
var totalY = 0;
var moveX = 0;
var moveY = 0;
document.addEventListener("mousemove", function(ev){
totalX += Math.abs(ev.movementX);
totalY += Math.abs(ev.movementY);
moveX += ev.movementX;
moveY += ev.movementY;
}, false);
setInterval(function(){
console.log(`Speed X: ${totalX}px/s, Y: ${totalY}px/s`);
console.log(`Movement X: ${moveX}px/s, Y: ${moveY}px/s`);
moveX = moveY = totalX = totalY = 0;
}, 1000);
Negative number represent movement to the left or top, while positive represent movement to the bottom or right direction.
Sparklines has a nifty example of tracking mouse movement and graphing it. Their code is available in the source of their site starting at line 315.
Simple and effective.
Here is the code:
var mrefreshinterval = 500; // update display every 500ms
var lastmousex=-1;
var lastmousey=-1;
var lastmousetime;
var mousetravel = 0;
$('html').mousemove(function(e) {
var mousex = e.pageX;
var mousey = e.pageY;
if (lastmousex > -1)
mousetravel += Math.max( Math.abs(mousex-lastmousex), Math.abs(mousey-lastmousey) );
lastmousex = mousex;
lastmousey = mousey;
});
Same way you get speed for anything else:
speed = distance / time
acceleration = speed / time
And use:
$(document).mousemove(function(e){
var xcoord = e.pageX;
var ycoord = e.pageY;
});
To get the mouse coordinates whenever the mouse moves.
This is a method to counter the fact you could start tracking, pause and then move your finger or mouse very quickly (suppose a sudden flick on a touch screen).
var time = 200
var tracker = setInterval(function(){
historicTouchX = touchX;
}, time);
document.addEventListener("touchmove", function(){
speed = (historicTouchX - touchX) / time;
console.log(Math.abs(speed));
}, false);
I have done this with only the touchX in this example. The idea is to take a snapshot of the x position every 200 milliseconds, and then take that from the current position then divide by the 200 (speed = distance / time). This would keep a fresh update on the speed. The time is milliseconds and the output would be the number of pixels traveled per 200 milliseconds.
var timestamp = null;
var lastMouseX = null;
var lastMouseY = null;
document.body.addEventListener("mousemove", function(e) {
if (timestamp === null) {
timestamp = Date.now();
lastMouseX = e.screenX;
lastMouseY = e.screenY;
return;
}
var now = Date.now();
var dt = now - timestamp;
var dx = e.screenX - lastMouseX;
var dy = e.screenY - lastMouseY;
var speedX = Math.round(dx / dt * 100);
var speedY = Math.round(dy / dt * 100);
timestamp = now;
lastMouseX = e.screenX;
lastMouseY = e.screenY;
});