Reputation: 61
I want to know the instant speed of the mouse in my update()
function.
But here's my problem: when fps
is high (>30), update()
is sometimes triggered twice between two onmousemove
events. And so, even if the mouse is moving, it's considered still for a moment.
I think this is about the relation between setInterval()
and the onmousemove
event. So here is the code that matters :
var fps = 60;
setInterval(update,1000/fps);
function update() {
console.log('update');
}
document.onmousemove = function(){
console.log('mouse');
}
It displays "update"
60 times a second, and "mouse"
each time the onmousemove
event triggers.
When the mouse is still, it goes : "update"
"update"
"update"
"update"
...
When the mouse moves, it is : "update"
"mouse"
"update"
"mouse"
...
But sometimes : "update"
"mouse"
"update"
"update"
"mouse"
...
And that's bullshit because the mouse IS moving.
So I tried different mouse movements, to see if there was a pattern, but no: circles, loops, straight lines... I also tried another mouse, but it's not a hardware problem.
I've found a partial solution. With a counter++
at each update()
, and counter=0
when onmousemove
, it allows me to skip the second update()
of a sequence of updates. But it's not perfect because sometimes there are 3 or 4 update()
in a row.
.
Is it solvable ? How to be SURE there is one and only one update()
between 2 onmousemove
?
PS 1: The more fps
, the more update()
called between two events.
PS 2: It's fine if onmousemove
is triggered several times between two update()
.
PS 3: I tried with document.addEventListener('mousemove')
, it's the same.
PS 4: I'm on a mac
Upvotes: 1
Views: 178
Reputation: 54026
This is unusual..
Mouse events should fire much more often than once every 30ms.
Two test snippets.
The first snippet records mouse moves and frame updates and will show a stream of events, plus the max mouse events per 160 events, and max mouse events in a row.
On my machine I am getting max 9 mouse events in a row and max 142/18 mouse events / frame events, running at 60FPS
But that said you can lose mouse events. The second snippet deliberately blocks all events for 26ms (approx 30FPS) and when I run that the max mouse events between frames is 4 and max rate is 115/45 mouse events to frame events. I am losing around 27 mouse events every 2.66 seconds
But still this does not explain your mouse problem.
most likely reason for your slow mouse is that another event listener is consuming mouse events. Use the dev tools to check for other mouse event listeners that may be chewing up events.
Apart from that all I can say is look at the OS mouse settings as could be the source of the problem.
Additional note, when testing the code on this page the max mouse events between frames is 3 (second snippet) as opposed to 4 on my testing environment. Reason Unknown????
Mouse events V frame events
var lastTime = 0;
var max = 0;
var maxInARow = 0;
var inARow = 0;
var record = [];
function recordEvent(type){
record.push(type);
if(record.length > 160){
record.shift();
}
}
document.addEventListener("mousemove",function(){
recordEvent(".");
inARow += 1;
});
function update(time){
recordEvent("|");
var count = 0;
for(var i = 0; i < record.length;i ++){
if(record[i] === "."){
count += 1;
}
}
maxInARow = Math.max(inARow,maxInARow);
mousebet.textContent = maxInARow;
inARow = 0;
mouserate.textContent = "Max : "+ max +"/"+(record.length - max)+ " Current : " + count +"/"+(record.length - count) ;
framerate.textContent = (1000 / (time-lastTime)).toFixed(0);
lastTime = time;
stream.textContent = record.join("");
if(max < count && record.length === 160){
var div = document.createElement("div");
div.textContent = stream.textContent;
document.body.appendChild(div);
}
max = Math.max(max,count);
requestAnimationFrame(update);
}
requestAnimationFrame(update);
body {
font-family :Arial,"Helvetica Neue",Helvetica,sans-serif;
}
div {
width : 100%;
}
FPS : <div id="framerate"></div>
Mouse : <div id="mouserate"></div>
Max mouse events between frames : <div id="mousebet"></div>
Events : <div id="stream"></div>
Mouse events V Blocking frame events
var lastTime = 0;
var max = 0;
var maxInARow = 0;
var inARow = 0;
var record = [];
function recordEvent(type){
record.push(type);
if(record.length > 160){
record.shift();
}
}
function mouseE(){
recordEvent(".");
inARow += 1;
};
document.addEventListener("mousemove",mouseE);
function update(time){
if(performance){
var n = performance.now();
}else{
document.body.innerHTML = "FAILED no performance API."
document.removeEventListener("mousemove",mouseE);
return;
}
recordEvent("|");
var count = 0;
for(var i = 0; i < record.length;i ++){
if(record[i] === "."){
count += 1;
}
}
maxInARow = Math.max(inARow,maxInARow);
mousebet.textContent = maxInARow;
inARow = 0;
max = Math.max(max,count);
mouserate.textContent = "Max : "+ max +"/"+(record.length - max)+ " Current : " + count +"/"+(record.length - count) ;
framerate.textContent = (1000 / (time-lastTime)).toFixed(0);
lastTime = time;
stream.textContent = record.join("");
// block javascript context till 28 ms used up;
while(performance.now() - n < 26);
requestAnimationFrame(update);
}
requestAnimationFrame(update);
body {
font-family :Arial,"Helvetica Neue",Helvetica,sans-serif;
}
div {
width : 100%;
}
26ms Blocking frame Event test <br>
FPS : <div id="framerate"></div>
Mouse : <div id="mouserate"></div>
Max mouse events between frames : <div id="mousebet"></div>
Events : <div id="stream"></div>
Upvotes: 1