Русский
Русский
English
Статистика
Реклама

Из песочницы Динамическое меню c поддержкой touch move и mouse move на RevolveR

Наверняка многие из вас хотели бы научиться создавать красивые и подвижные меню в духе Android Java и Kotlin приложений. Скорее всего даже многие из вас ради этого уходили в области программирования отдельных приложений и были вынуждены осваивать инородный стек.

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

И так: Simple Dynamic Menu by RevolveR Labs.

image

Начинается все с верстки. Она должна быть семантической, легкой и современной.



<nav class="dynamic-menu"><ul><li><a href="http://personeltest.ru/aways/revolvercmf.ru">RevolveR Labs</a></li><li><a href="#">Ultra newest solutions</a></li><li><a href="#">The way of incredible</a></li><li><a href="#">In search of the best</a></li><li><a href="#">Progressive RevolveR frontends</a></li><li><a href="#">Developing of new era</a></li></ul></nav>

Мы используем стандартный маркированный список и HTML 5 в качестве элемента враппера, а чтобы сделать меню плавающим сразу пропишем CSS стили вытягивающие меню на за пределы экрана на всю ширину списка элементов и скроем все лишнее до области видимости:



.dynamic-menu {display: inline-block;text-align: center;overflow: hidden;margin: 0 auto;height: 3vw;width: 80%;}.dynamic-menu ul {transition: all 2.5s ease-in-out;position: relative;list-style: none;width: 900vw;padding: 0;margin: 0;left: 0vw;}.dynamic-menu ul li {box-shadow: 0 0 0.1vw #333;border: .1vw dashed #fff;background: #a2a2a2;margin-bottom: 1vw;display: inline-block;border-radius: .2vw;margin-right: .5vw;padding: .2vw 1vw;background: #888;float: left;}.dynamic-menu ul li a {text-shadow: 0 0 0.2vw #fff;font: normal 2vw Helvetica;text-decoration: none;color: #006400;}.dynamic-menu ul li a:hover {text-decoration: underline;color: #674c2be0;}

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



Handler для desktop версии


Для работы хэндлера нам понадобится инициализировать RevolveR инстанс и использовать некоторое встроенное API работы с событиями:



let launch = RR.browser;RR.menuMove = null;if( !RR.isM ) {RR.event('.dynamic-menu ul', 'mousedown', (e) => {e.preventDefault();if( !RR.menuMove ) {RR.menuLeft = RR.curxy[0];RR.MenuMoveObserver = RR.event('body', 'mousemove', (e) => {e.preventDefault();RR.styleApply('.dynamic-menu ul', ['transition: all 0s ease']);RR.menuMove = true;RR.menuPosition = ( RR.menuLeft - RR.curxy[0] ) *-1;RR.styleApply('.dynamic-menu ul', ['left:'+ RR.menuPosition +'px']);RR.event('body', 'mouseup', (e) => {e.preventDefault();if( e.target.tagName === 'A' && !RR.touchFreeze ) {//R.loadURI(target.href, target.title);console.log(e.target.href);RR.touchFreeze = true;RR.menuMove = null;}void setTimeout(() => { RR.menuMove = null;}, 50);void setTimeout(() => {if( !RR.menuMove ) {RR.styleApply('.dynamic-menu ul', ['left: 0px', 'transition: all 2.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)']);}}, 2500);});});}});}

Большинство необходимых event уже работают после запуска гетера RR.browser(). Это например отслеживание событий изменения размера окна и постоянно обновление положения указателя мыши RR.curxy.



Здесь мы используем метод блокировки флагами для того, чтобы добиться синхронности выполнения событий и задать блокирующие флаги, например, для реализации запрета события перехода по ссылке, если меню находится в движении.



RR.MenuMoveObserver является собой event стеком, который хранит MD5 hash события для того, чтобы можно было выключить часть хэндлера отвечающего за смену положения по оси X. Мы выключаем обсерверы каждый раз когда событие клик завершилось в пользу mouseup.



Готово. При нажатии на левую клавишу мыши, если держать кнопку утопленной будет происходить отслеживание положения курсора мыши по оси X, а обсервер обеспечит своевременное обновление положения left контейнера списка меню внутри враппера области видимости и лента меню начнет двигаться открывая не поместившиеся элементы списка.



Мобильный handler меню


Основной принцип работы остается примерно таким же, но я не стал схлопывать разные хэндлерры в один обработчик чтобы оставить понятность и читабельность кода.



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



if( RR.isM ) {RR.event('.dynamic-menu ul', 'touchstart', (e) => {e.preventDefault();RR.menuMove = null;RR.event('body', 'touchend', (e) => {e.preventDefault();if( !RR.menuMove ) {RR.touchFreeze = null;let target = e.changedTouches[0].target;if( RR.isO(RR.MenuMoveObserver) ) {for( i of RR.MenuMoveObserver ) {RR.detachEvent( i[ 2 ] );}}if( target.tagName === 'A' && !RR.touchFreeze ) {//R.loadURI(target.href, target.title);console.log(e.target.href);RR.touchFreeze = true;RR.menuMove = null;}void setTimeout(() => {if( !RR.menuMove ) {RR.styleApply('.dynamic-menu ul', ['left: 0px', 'transition: all 2.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)']);//RR.animate('.dynamic-menu ul', ['left:0px:1000:wobble']);}}, 2500);}});if( !RR.menuMove ) {RR.menuLeft = e.changedTouches[0].screenX;RR.MenuMoveObserver = RR.event('body', 'touchmove', (e) => {e.preventDefault();RR.styleApply('.dynamic-menu ul', ['transition: all 0s ease']);RR.menuMove = true;RR.menuPosition = ( RR.menuLeft - e.changedTouches[0].screenX ) *-1; RR.styleApply('.dynamic-menu ul', ['left:'+ RR.menuPosition +'px']);RR.event('body', 'touchend', (e) => {RR.menuMove = null;});});}});}

В коде вы увидите небольшую разницу. Во первых event.target теперь не работает и нужно следить за сериями touch. Я добавил анимацию возвращения меню с эффектом easing и теперь меню само плавно возвращается в начальное положение спустя некоторое время бездействия с меню:



void setTimeout(() => {if( !RR.menuMove ) {RR.styleApply('.dynamic-menu ul', ['left: 0px', 'transition: all 2.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)']);}}, 2500);

Demo


Чтобы посмотреть как работает Dynamic Menu на базе библиотеки RevolveR вы можете пройти по ссылке.



Итог


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

Источник: habr.com
К списку статей
Опубликовано: 18.10.2020 20:21:07
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Css

Javascript

Интерфейсы

Html

Html 5

Touch

Mouse

Menu

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru