Javascript-форум (https://javascript.ru/forum/)
-   Мобильный JavaScript (https://javascript.ru/forum/mobile/)
-   -   Какие event принято биндить для 3Д вращения в мобильном приложении? (https://javascript.ru/forum/mobile/81769-kakie-event-prinyato-bindit-dlya-3d-vrashheniya-v-mobilnom-prilozhenii.html)

Was-Ja 27.01.2021 21:49

Какие 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 как раз мышкой в настольном браузере можно крутить молекулу и отмечать ее атомы. В мобильнике я пытался, но, пока лажа получается.

Спасибо!

voraa 27.01.2021 23:27

Я бы посоветовал использовать более современные pointerEvents.
https://developer.mozilla.org/ru/doc...Pointer_events
Работают во всех современных браузерах (ну у Файрфокса есть некоторые глюки, при обработке касаний двумя пальцами).
А, например, на ноутбуках с сенсорным экраном под Windows touchEvents просто не существует ни в Хроме, ни в Мозиле.
По использованию, если обрабатывать только касание одним пальцем, мало, чем отличается от мышиных событий. При этом не надо думать о мыши вообще и обрабатывать всякие мышиные события - они обрабатывается этими событиями тоже. Есть один существенный плюс - возможность захвата указателя. Т.е события всегда передаются в то окно, где началось касание. Это работает и для мыши. Не надо думать о том, что мышь уйдет за пределы элемента и вешать дополнительные обработчики на document.

Was-Ja 28.01.2021 00:00

Спасибо большое, voraa!!!

То, что надо, классно, пошел переписывать!

СПАСИБО!!!

Was-Ja 28.01.2021 03:56

Пожалуйста, подскажите вдогонку один вопрос на ту же тему...

Сделал все на 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-ой строчке.

Спасибо!!!

voraa 28.01.2021 07:46

Цитата:

Сообщение от Was-Ja
надо выставлять в канвасе touch-action: none; но это, понятно дело не удобно.

А чем неудобно?
Ведь если в элементе надо выполнять какие то специальные действия, а не стандартные, то и надо ему ставить touch-action. Других то все равно выполнять нельзя. Ведь никто не разберется, что вот в этот раз я кручу молекулу, а в этот раз роллингую.
Может конечно быть вариант, что когда в элементе нет молекулы, то его и роллинговать можно, а когда есть - только крутить. Тогда и надо менять touch-action. Нарисовали молекулу - поставили ему none, убрали - auto

Цитата:

Сообщение от Was-Ja
Я заметил, что когда мобильник перехватывает управление, то он дает PointerLeave

PointerLeave - это вторично. Там несколько событий в этот момент. Основное - pointercancel.

Was-Ja 28.01.2021 09:58

Спасибо большое, voraa, за помощь!!!

Цитата:

Сообщение от voraa (Сообщение 533168)
PointerLeave - это вторично. Там несколько событий в этот момент. Основное - pointercancel.

ой, не знал, спасибо большое!!! Поправил, ИМХО, стало визуально более разумно функционировать.

Цитата:

Сообщение от voraa (Сообщение 533168)
А чем неудобно?
Ведь если в элементе надо выполнять какие то специальные действия, а не стандартные, то и надо ему ставить touch-action. Других то все равно выполнять нельзя. Ведь никто не разберется, что вот в этот раз я кручу молекулу, а в этот раз роллингую.

я понял, что хочу... Мне хотелось оставить зум по всему документу включая канвас, а вот pointerdown, pointerup, pointermove, poitercancel сделать своими.

То есть юзер может крутить молекулу как он хочет, зазумив ее почти полностью в размер мобильника, но для выхода из этого режима ему просто надо отзумить назад. Молекулы-то могут быть большими - больше ста атомов, а юзер в них может хотеть атомы пометить, чтобы углы посчитать. На большом экране десктопа мышкой это сделать легко, а вот в мобильнике попасть пальцем без зума - очень проблематично.

Скажите, пожалуйста, можно ли как-то сделать так, что touch-action распространяется на скрол, но не распространялся бы на зум?

Спасибо!!!

voraa 28.01.2021 11:05

Цитата:

Сообщение от Was-Ja
Скажите, пожалуйста, можно ли как-то сделать так, что touch-action распространяется на скрол, но не распространялся бы на зум?

По идее можно.
https://developer.mozilla.org/ru/doc...S/touch-action
Т.е touch-action: pinch-zoom; - должно разрешить только зум.
Пробуйте.

Was-Ja 28.01.2021 12:49

Спасибо большое, voraa!!!

Цитата:

Сообщение от voraa (Сообщение 533176)
По идее можно.
https://developer.mozilla.org/ru/doc...S/touch-action
Т.е touch-action: pinch-zoom; - должно разрешить только зум.
Пробуйте.


Заработало, ура!!! СПАСИБО ОГРОМНОЕ!!!


Часовой пояс GMT +3, время: 19:47.