I have an HTML page roughly divided 30% - 70% into two vertical columns. The left column contains a chat feed (handled via Node and Socket.io), and the right column contains an emscripten-generated canvas
(with the ID of canvas
). The canvas contains a basic 3D world that the user can navigate using standard first-person controls (WASD for movement, mouse to 'look').
By default, the canvas swallows all keyboard events. I've fixed this with the following code in the canvas initialisation procedure:
Module.preRun.push(function () {
ENV.SDL_EMSCRIPTEN_KEYBOARD_ELEMENT = "#canvas";
});
This allow me to manually focus on the chat box, type a message, and submit it.
The issue I'm running into is that once the chat message has been submitted, I try and return focus to the canvas with the following code (to allow the players to navigate the 3d world with WASD):
$('#canvas').focus();
This nominally returns focus to the canvas, but mouse and keyboard movement does not work. Oddly, clicking off the tab/browser window and then into the canvas seems to work - focus is returned to the canvas, and I can navigate once more. Manually calling $(window).blur().focus()
doesn't do the trick.
Does anyone know how to force focus back to the canvas once a chat message has been sent?
-- UPDATE --
I've added a text input field (with the ID of hiddenField
) behind the canvas and I'm using the preRun function to assign key events for the canvas to that field (canvas wasn't working consistently for some reason).
This works fine until the user clicks off the canvas - for example, into the chat field - whereupon the canvas stops responding to any keyboard or mouse input, even though I'm triggering focus back onto the hiddenField
(and can see that it's getting it).
It seems that doing anything on the page conflicts with emscripten's focussing behaviour (tied to the window object, I believe) and prevents the canvas from regaining focus.
Surely there's some way of aloowing the emscripten canvas to live alongside other HTML elements?
You need to make canvas
object focusable by adding tabindex="0"
attribute.
Then it should be possible to trigger the focus event properly:
document.querySelector("#canvas").focus()
The best approach I've been able to find to this - indeed, the only way to get the separate aspects of the application (chat & 3D world) working correctly - has been to embed the emscripten canvas in an iframe
and use cross-frame function calls when necessary to trigger actions.
Page
- chat
- iframe
-- emscripten-generated page
It's not my first choice of solution, but it's the only one I've managed to get working.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With