27.01.2021, 21:49
|
Кандидат Javascript-наук
|
|
Регистрация: 20.09.2020
Сообщений: 130
|
|
Какие event принято биндить для 3Д вращения в мобильном приложении?
Добрый день,
помогите, пожалуйста, советом!
Недавно начал разрабатывать приложение базы молекул, которое лежит тут. В базе можно поискать молекулы и результаты покрутить на экране в 3Д (WebGL, каюсь, еще не прикрутил, хотя планирую).
В обычном браузере я использую евенты:
mousedown,
mouseup,
mousemove,
mouseleave
Если произошел mousedown и потом потащили, то я вращаю молекулу на экране, а при mouseleave или mouseup сохраняю величину поворота. Если было нажато mousedown и сразу mouseup (фактически был клик), и мы попали на атом, то я его маркирую, чтобы показать свойства молекулы - длины связей, углы и торсионные углы.
Я хотел бы, чтобы мое клиенское приложение так же работало на мобильнике. Вернее не также, а так, чтобы всеми узнаваемо.
Попробовал забиндить
Код:
|
mousedown -> touchstart
mouseup -> touchend
mousemove -> touchmove
mouseleave -> touchcancel |
дополнительно пришлось добавить в начале event.preventDefault(); и все евенты биндить как:
Код:
|
canvas.addEventListener('touchstart', MolFrameCanvasTouchMouseDown, true); |
Но получается лажа... Когда я нажимаю пальцем, то touchstart получается, а вот когда я заканчиваю, touchend обычно не срабатывает.
Более того, touchmove часто вызывается несколько раз друг за другом, и надо семафорить, а я не понимаю как. В обычном браузере я заводил глобальную переменную var Busy, и присваивал ей 1 при входе в первый mousemove, а по выходе занулял и такой семафор работал, а в мобильном так не получается...
Пожалуйста, подскажите, правильно ли я в мобильном приложении пользую соответствие:
Код:
|
mousedown -> touchstart
mouseup -> touchend
mousemove -> touchmove
mouseleave -> touchcancel |
и как семафорить наплывающие друг за другом евенты от touchmove,
а может я просто не то использую в мобильном приложении и надо другие евенты пользовать, пожалуйста, посоветуйте?
PS: пример отрисовки 3Д у меня в базе: если Вы кликните по ссылке https://www.elegant-nmr.com/mdb/ и в первом поле введете например, C2, и нажмете на "Search Molecules", появится список молекул, удовлетворяющий поиску. Под каждой такой молекулой можно переключиться 2D - Conformer #1, в 2D ничего двигать нельзя, а в Conformer как раз мышкой в настольном браузере можно крутить молекулу и отмечать ее атомы. В мобильнике я пытался, но, пока лажа получается.
Спасибо!
|
|
27.01.2021, 23:27
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,745
|
|
Я бы посоветовал использовать более современные pointerEvents.
https://developer.mozilla.org/ru/doc...Pointer_events
Работают во всех современных браузерах (ну у Файрфокса есть некоторые глюки, при обработке касаний двумя пальцами).
А, например, на ноутбуках с сенсорным экраном под Windows touchEvents просто не существует ни в Хроме, ни в Мозиле.
По использованию, если обрабатывать только касание одним пальцем, мало, чем отличается от мышиных событий. При этом не надо думать о мыши вообще и обрабатывать всякие мышиные события - они обрабатывается этими событиями тоже. Есть один существенный плюс - возможность захвата указателя. Т.е события всегда передаются в то окно, где началось касание. Это работает и для мыши. Не надо думать о том, что мышь уйдет за пределы элемента и вешать дополнительные обработчики на document.
|
|
28.01.2021, 00:00
|
Кандидат Javascript-наук
|
|
Регистрация: 20.09.2020
Сообщений: 130
|
|
Спасибо большое, voraa!!!
То, что надо, классно, пошел переписывать!
СПАСИБО!!!
|
|
28.01.2021, 03:56
|
Кандидат Javascript-наук
|
|
Регистрация: 20.09.2020
Сообщений: 130
|
|
Пожалуйста, подскажите вдогонку один вопрос на ту же тему...
Сделал все на Pointer-events, все стало классно работать, но есть одна неувязка.
Чтобы маскировать системные евенты мобильника (зум и скроллинг), надо выставлять в канвасе touch-action: none; но это, понятно дело не удобно.
Если это не делать, то мобильник через, буквально десятую долю секунды, забирает управление и движение не получается.
У меня движение сделано так
при PointerDown я начинаю движение,
пока нет PointerUp или PointerLeave, я кручу молекулу.
Если не делать touch-action: none; то кручение заканчивается буквально за десятую долю секунды, так как происходит PointerLeave, хотя я не отрываю пальца от экрана, просто мобильник перехватывает управление и начинает скролить.
Я попробовал при PointerDown менять класс в канвасе с touch-action: none; но это не срабатывает.
Я заметил, что когда мобильник перехватывает управление, то он дает PointerLeave и я решил, что на него я не буду выключать touch-action: none; в touch-action: auto;
Такой режим работает существенно интуитивнее, но, все равно, как-то криво.
Понятно можно сделать кнопку, что де - включи кручение, но это вроде совсем как-то не красиво.
Скажите, пожалуйста, можно ли по первому евенту PointerDown как-то так гарантированно поменять класс у канваса с touch-action: auto; на touch-action: none; чтобы мобильник не перехватил свое управление пока я ему не разрешу?
PS: пример, лежит там же, в сорсах эти евенты на 2075-ой строчке.
Спасибо!!!
|
|
28.01.2021, 07:46
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,745
|
|
Сообщение от Was-Ja
|
надо выставлять в канвасе touch-action: none; но это, понятно дело не удобно.
|
А чем неудобно?
Ведь если в элементе надо выполнять какие то специальные действия, а не стандартные, то и надо ему ставить touch-action. Других то все равно выполнять нельзя. Ведь никто не разберется, что вот в этот раз я кручу молекулу, а в этот раз роллингую.
Может конечно быть вариант, что когда в элементе нет молекулы, то его и роллинговать можно, а когда есть - только крутить. Тогда и надо менять touch-action. Нарисовали молекулу - поставили ему none, убрали - auto
Сообщение от Was-Ja
|
Я заметил, что когда мобильник перехватывает управление, то он дает PointerLeave
|
PointerLeave - это вторично. Там несколько событий в этот момент. Основное - pointercancel.
|
|
28.01.2021, 09:58
|
Кандидат Javascript-наук
|
|
Регистрация: 20.09.2020
Сообщений: 130
|
|
Спасибо большое, voraa, за помощь!!!
Сообщение от voraa
|
PointerLeave - это вторично. Там несколько событий в этот момент. Основное - pointercancel.
|
ой, не знал, спасибо большое!!! Поправил, ИМХО, стало визуально более разумно функционировать.
Сообщение от voraa
|
А чем неудобно?
Ведь если в элементе надо выполнять какие то специальные действия, а не стандартные, то и надо ему ставить touch-action. Других то все равно выполнять нельзя. Ведь никто не разберется, что вот в этот раз я кручу молекулу, а в этот раз роллингую.
|
я понял, что хочу... Мне хотелось оставить зум по всему документу включая канвас, а вот pointerdown, pointerup, pointermove, poitercancel сделать своими.
То есть юзер может крутить молекулу как он хочет, зазумив ее почти полностью в размер мобильника, но для выхода из этого режима ему просто надо отзумить назад. Молекулы-то могут быть большими - больше ста атомов, а юзер в них может хотеть атомы пометить, чтобы углы посчитать. На большом экране десктопа мышкой это сделать легко, а вот в мобильнике попасть пальцем без зума - очень проблематично.
Скажите, пожалуйста, можно ли как-то сделать так, что touch-action распространяется на скрол, но не распространялся бы на зум?
Спасибо!!!
|
|
28.01.2021, 11:05
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,745
|
|
Сообщение от Was-Ja
|
Скажите, пожалуйста, можно ли как-то сделать так, что touch-action распространяется на скрол, но не распространялся бы на зум?
|
По идее можно.
https://developer.mozilla.org/ru/doc...S/touch-action
Т.е touch-action: pinch-zoom; - должно разрешить только зум.
Пробуйте.
Последний раз редактировалось voraa, 28.01.2021 в 11:07.
|
|
28.01.2021, 12:49
|
Кандидат Javascript-наук
|
|
Регистрация: 20.09.2020
Сообщений: 130
|
|
Спасибо большое, voraa!!!
Заработало, ура!!! СПАСИБО ОГРОМНОЕ!!!
|
|
|
|