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).
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;
});
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;
});
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.
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.
I also had a requirement to find the acceleration, speed, movement of the mouse. Below is the code which is implemented for the react application. Through this we were able to find the movement, speed, max speed, acceleration, maximum acceleration of the mouse.
let previousEvent, currentEvent;
let maxSpeed = 0, previousSpeed = 0, speed = 0, maxPositiveAcc = 0, maxNegativeAcc = 0;
componentDidMount() {
document.addEventListener('mousemove', (event) => {
currentEvent = event
});
setInterval(function () {
if (currentEvent && previousEvent) {
let movementX = Math.abs(currentEvent.pageX - previousEvent.pageX);
let movementY = Math.abs(currentEvent.pageY - previousEvent.pageY);
let movement = Math.sqrt(movementX * movementX + movementY * movementY);
//Dividing by 100 since the setInterval function is called every 100ms
speed = 10 * movement;
maxSpeed = Math.round(speed > maxSpeed ? (maxSpeed = speed) : maxSpeed);
let acceleration = 10 * (speed - previousSpeed);
if (acceleration > 0) {
maxPositiveAcceleration = Math.round(acceleration > maxPositiveAcc ? (maxPositiveAcc = acceleration) : maxPositiveAcc);
} else {
maxNegativeAcceleration = Math.round(acceleration < maxNegativeAcc ? (maxNegativeAcc = acceleration) : maxNegativeAcc);
}
}
previousEvent = currentEvent
previousSpeed = speed;
}, 100);
}
I'm looking for a way to track mouse speed as well. I found this video on Youtube https://www.youtube.com/watch?v=Lrfmu9V_foE. You can see how to track mouse speed with mousemove event once has defined previous mouse event and current mouse event.
Anyways, I want to store the speed as a value to use elsewhere but don't know how to.
Post Answer
to ask a question. Use the Ask Question
button and include these details. You can also add a link to this question if the context would be useful. - From Review –
Romansh This uses e.movementX instead of e.screenX - lastMouseX
. The speed
is for any direction, not only speedX
or speedY
. speedMax
is useful to trig something at a turn fast enough (a throw). The direction
can define a turn.
var timestamp = 0, speedMax = 0;
document.body.addEventListener("mousemove", function(e) {
var now = Date.now();
var dt = now - timestamp;
var dx = e.movementX;
var dy = e.movementY;
var distance = Math.sqrt(dx*dx + dy*dy);
var direction = Math.atan2(dy, dx);
//speed is zero when mouse was still (dt hold a long pause)
var speed = parseInt(distance / dt * 100);
var speedX = Math.round(dx / dt * 100);
var speedY = Math.round(dy / dt * 100);
//reset if speed is zero, otherwise set max of any speed
speedMax = !speed? 0: speed > speedMax? speed: speedMax;
timestamp = now;
});
The first speed is zero because dt is a big number.
© 2022 - 2024 — McMap. All rights reserved.
mrefreshinterval
a "predefined" attribute? I don't see how you use it. Thanks. – Primo