Ideally in a browser, mousemove should fire every frame when the mouse keeps moving. But when a key is pressed (or repeated) or released, the mousemove stops firing for a frame or two.
We can test this with the following code:
t0 = new Date().getTime()
window.onmousemove = function() {
t = new Date().getTime()
if (t-t0 > 20)
console.log(t-t0)
t0 = t
}
Try keep your mouse moving. The console will print delay of mousemove only when you press, release a key or keep a key pressed (because it's repeated).
I have tested this on both Firefox and Chrome. I use macOS 10.14.2.
I'm writing a web action game, so I need to make sure the mouse position is updated every frame. Any solutions please?
t0 = new Date().getTime()
window.onmousemove = function() {
t = new Date().getTime()
if (t-t0 > 2)
console.log(t-t0)
t0 = t
}
this will make console.log() go crazy fast it wil not skip when you move your mouse fast , also tested your code doesn't skip when pressing keys , on Chrome , Windows10
also you should consider using a main loop for your game to handle and manage times and frames and events
Related
I have this little code. It's the beginnig of a drawing app: https://jsfiddle.net/t2xycjcd/1/ (building on code by www.williammalone.com)
This is the key listener:
canvas.onkeypress = function (e) {
e.preventDefault();
var letter = String.fromCharCode(e.keyCode);
if (keyMap[letter]) {
settings[keyMap[letter].param] = keyMap[letter].value;
refreshToolStatusDisplay();
redraw();
}
}
This is the mouse listener (nothing fancy):
canvas.onmousedown = function(e)
{
console.log("mousedown");
clickX = offsetX(e, canvas);
...
I am getting crazy about mouse events not correctly firing when happening short time (or immediately) after a key event.
How to reproduce:
use the line tool to draw a line
press the "p" key to select "player" tool
now without pausing and without moving the mouse -> click
The mousedown event will not fire.
It will however if you either wait about one second before step three, or move the mouse or click one more time.
This is kind of catastrophic for my purpose.
I have tried various things but none worked:
Resetting the focus to the canvas element after the key event -> not the problem, the canvas still has the focus
Firing a custom mouse event after the key event through a MouseEvent.initMouseEvent() -> not working
Other crazy stuff not worth mentioning
This seems to be typical behaviour of canvas elements. This is a
similar but unrelated fiddle of a canvas element with a mouse listener: http://jsfiddle.net/4Lanc/ -> Same behaviour there: clicking shortly after a key press will prevent the click from happening.
Anybody have an idea?
In Javascript, is it possible in a mousemove event handler to determine if there are any pending mousemove events in the queue?
Or, preferably, is it possible to make the event queue skip all mousemove events in the queue except for the most recent one?
I'm using mousemove & other mouse events to allow users to drag elements around the screen, and I don't need to waste CPU & GPU cycles redrawing the dragged items on every mousemove event (in which I update the top & left CSS properties), as long as I can skip intermediate events quickly enough.
My site is not currently experiencing any performance or visualization problems; I just want to make my JavaScript as efficient as possible.
Use event debouncing. This small throttle/debounce library works well with or without jQuery.
Example:
function someCallback() {
// snip
}
// don't fire more than 10 times per second
var debouncedCallback = Cowboy.debounce(100, someCallback);
document.getElementById('some-id').addEventListener('mousemove', debouncedCallback);
You could keep track of the last time you handled a mousemove, then skip the current one if it's too soon.
For example:
elem.onmousemove = function() {
var lastcalled = arguments.callee.lastCallTime || 0,
now = new Date().getTime();
if( now-lastcalled < 250) return;
arguments.callee.lastCallTime = now;
// rest of code here
};
I am coding a javascript game, with a moving ball.
I want an alert message when the user manage to click on the moving ball.
It is working right now, but the event is not firing every times... It look likes the ball is moving too fast for the js engine to be able to notice that the ball was indeed clicked.
I am testing on Firefox 18, windows 7 on a 5 years old cpu...
Here are some bits of my code :
myBall = document.getElementById("myBall");
function move(){
myLeft += 20;
myBall.style.left = myLeft + "px";
}
myTimer = window.setInterval(move, 10);
...
myBall.addEventListener("click", function(){alert("win")});
Is there any way to set a click event listener on a small moving target, that will behave more accurately ? Would jQuery make any difference here ?
Thanks.
All right, to solve the problem you're having, you'll need to add event listener for mousedown instead of click.
It is because click requires mouse button to go both down and up, and – as #techfoobar noted – it must be done at the same place on the target element (if coords of mousedown and mouseup are not equal, the click event won't be fired). The ball simply moves too fast to meet the aforementioned condition, hence the problem.
I have an instant chat program I've created with HTML5/CSS, Asynch. Javascript and PHP. I have an interval that is constantly checking the user's chat box div is scrolled to the bottom for user convenience. This became a problem when a user wished to scroll up to view previous messages so I tried the onscroll event to stop the interval. I couldn't get this to work and so have gone the longer way around by using the onmouseover and onmouseout events to start and stop the interval.
This works perfectly fine for desktop computers as they have a visible mouse. For mobile devices however, such as my Windows phone - which the program is primarily designed for, there is an issue as you first have to tap the message box (presumably to first move the invisible mobile mouse over the chat box) and then scroll with the finger movement to scroll unaffected.
This isn't a major problem as I could inform mobile users to first tap then scroll, but I feel that successfully using the onscroll event would match the usability with desktop users.
Are there known issues with the onscroll event? I dare say I'm familiar with JS events and can use them appropriately, but this is the only event I haven't managed to get to work, in FF or IE.
Any thoughts or help would be appreciated,
Lee.
Here are the current events that manage the scrollcheck on/off, where ScrollCheck() is the function that checks the scroll position and moves it if not at the bottom and scrollInterval is the global var that holds the id of the interval.
document.getElementById('messages').onmouseover = function()
{
clearInterval(scrollInterval);
}
document.getElementById('messages').onmouseout = function()
{
scrollInterval = setInterval(ScrollCheck, 300);
}
I simply replaced the onmouseover event to onscroll without any luck.
When I make a chat page, I only check the scroll when new messages are added:
var currentScroll = elem.scrollTop, oldmaxScroll = elem.scrollHeight-elem.clientHeight;
// add new message(s) here
var newmaxScroll = elem.scrollHeight-elem.clientHeight;
if( currentScroll == oldmaxScroll) elem.scrollTop = newmaxScroll;
Within my Firefox extension I'm trying to keep track when the window is actually the active window. For this, I add the following two listener to the window:
window.addEventListener("deactivate", function(event) { alert("deactivate"); }, false);
window.addEventListener("activate", function(event) { alert("activate"); }, false);
Basically everything works fine. When I toggle between different windows, or minimize/maximize Firefox, the events fire quite as I would expect it. However, both events also fired when I move the window even if it is already active. When I start moving the window, the "deactivate" event is fired; when I stop moving and release the mouse button, the "activate" event is fired. I have no idea how can I detect and ignore this behavior. Intuitively, the window is all the time active.
I tried to check before I handle the "deactivate" event if the mouse button is pressed. However, adding a "click" event listener to the window seem not to include the window's title bar. Anyone any idea how I can distinguish beween "really" de-/activating the window and moving the window? Thanks a lot in advance!
You can use this answer to detect the browser position on the screen. If you do this at the start you can compare if they are changing.
Something like when the page loads:
var x,
y,
win = window;
if(win.screenTop !== undefined) {
x = win.screenleft;
y = win.screenTop;
} else {
x = win.screenX;
y = win.screenY
}
and compare those values to the current values when your events triggers.
(Note that this only works when the position of the window changes)