Emscripten Canvas + jQuery - переключить фокус

У меня есть HTML-страница, примерно разделенная на 30% - 70% на две вертикальные колонки. Левый столбец содержит канал чата (обрабатывается через Node и Socket.io), а правый столбец содержит созданный emscripten canvas (с идентификатором canvas). Холст содержит базовый трехмерный мир, по которому пользователь может перемещаться, используя стандартные элементы управления от первого лица (WASD для движения, мышь для «взгляда»).

По умолчанию холст поглощает все события клавиатуры. Я исправил это с помощью следующего кода в процедуре инициализации холста:

Module.preRun.push(function () {
    ENV.SDL_EMSCRIPTEN_KEYBOARD_ELEMENT = "#canvas";
});

Это позволяет мне вручную сосредоточиться на окне чата, набрать сообщение и отправить его.

Проблема, с которой я сталкиваюсь, заключается в том, что после отправки сообщения чата я пытаюсь вернуть фокус на холст с помощью следующего кода (чтобы позволить игрокам перемещаться по трехмерному миру с помощью WASD):

 $('#canvas').focus();

Это номинально возвращает фокус холсту, но движение мыши и клавиатуры не работает. Как ни странно, нажатие на вкладку / окно браузера, а затем на холст, кажется, работает - фокус возвращается на холст, и я могу перемещаться еще раз. Ручной вызов $(window).blur().focus() не помогает.

Кто-нибудь знает, как вернуть фокус обратно на холст после отправки сообщения чата?

- ОБНОВЛЕНИЕ -

Я добавил поле ввода текста (с идентификатором hiddenField) за холстом, и я использую функцию preRun, чтобы назначить ключевые события холста этому полю (холст по какой-то причине работал некорректно).

Это работает нормально до, пока пользователь не щелкнет холст, например, в поле чата, после чего холст перестает реагировать на любой ввод с клавиатуры или мыши, даже если я снова переключаю фокус на hiddenField ( и видно, что он это получает).

Кажется, что выполнение чего-либо на странице конфликтует с поведением фокусировки emscripten (я полагаю, привязанным к объекту окна) и не позволяет холсту восстановить фокус.

Конечно, есть способ разрешить холсту emscripten жить вместе с другими элементами HTML?


person MassivePenguin    schedule 29.08.2017    source источник


Ответы (3)


Лучший подход, который мне удалось найти - действительно, единственный способ заставить отдельные аспекты приложения (чат и трехмерный мир) работать правильно - это встроить холст emscripten в iframe и использовать кросс-фрейм. функция вызывает, когда это необходимо для запуска действий.

Page
    - chat
    - iframe
        -- emscripten-generated page

Это не мой первый вариант решения, но он единственный, с которым мне удалось заставить работать.

person MassivePenguin    schedule 04.09.2017

Вам нужно сделать объект canvas доступным для фокусировки, добавив атрибут tabindex="0".

Тогда должно быть возможно правильно запустить событие фокуса:

document.querySelector("#canvas").focus()
person luke    schedule 06.09.2017

РЕДАКТИРОВАТЬ:

Посмотреть полную демонстрацию можно на CodePen (включая ссылки на .js ресурсы)

Структура:

Page
    - emscripten-generated-page
       - loop
    - chat
    - script to handle global key input handlers

Вы должны установить tabindex в элементе холста (как указано luke и описано в MDN), подключите глобальные прослушиватели событий через встроенный JavaScript Document интерфейс, а затем вызовите .triggerHandler(), чтобы убедиться, что холст вернулся в состояние по умолчанию, управляемое click:

var chatInputField = $("#message-input");
var canvas = $("#canvas");


canvas.on("click", function(e){
  return document.addEventListener("keyup", game.toggleKeys);
});

chatInputField.on("focusin", function(e) {
    $('#canvas').attr('tabindex', 0);
    return document.removeEventListener("keyup", game.toggleKeys, false);
});

chatInputField.on("focusout", function(e) {
    $("#canvas").triggerHandler('click');
    chatInputField.attr('tabindex', 0);
});

Я это проверил, работает. Вот мой файл app.js для управления вводом клавиш (см. Строку 297).

https://gist.github.com/shagamemnon/585df8dd215a949b839f8b02199af31b

Предупреждение: вы должны явно определить поведение клавиши tab внутри игрового холста.

person shagamemnon    schedule 07.09.2017