Menu dinâmico com suporte para toque e movimento do mouse no RevolveR

Certamente, muitos de vocês gostariam de aprender como criar menus bonitos e fluidos no espírito dos aplicativos Android Java e Kotlin. Muito provavelmente, até mesmo muitos de vocês por causa disso deixaram o campo de programação de aplicativos individuais e foram forçados a dominar uma pilha estrangeira.



Neste artigo, vou dizer como é simples e fácil criar menus dinâmicos lineares que suportam não apenas eventos de mouse, mas também ponteiros para versões móveis.



E assim: Menu Dinâmico Simples da RevolveR Labs.



imagem



Tudo começa com o layout. Deve ser semântico, leve e moderno.





<nav class="dynamic-menu">

	<ul>
		<li><a href="https://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>


Usamos uma lista com marcadores padrão e HTML 5 como um elemento de wrapper e, para fazer o menu flutuar, escreveremos imediatamente estilos CSS que puxam o menu para fora da tela em toda a largura da lista de elementos e ocultam todos os desnecessários para o escopo:





.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 .







Muitos de vocês usam plug-ins prontos ou blocos de layout embutidos com menus de hambúrguer, mas menus lineares dinâmicos são tão bons e economizam espaço em interfaces. Muitos de vocês provavelmente achariam difícil implementar tais menus devido à diferença nos ouvintes de eventos e à incapacidade de usar sinalizadores. Este exemplo teve como objetivo mostrar que usando JavaScript comum é possível, sem nenhuma qualificação proibitiva, implementar as mesmas coisas que em aplicativos Android convenientes, e o trabalho magistral com animações permite criar efeitos de transição impressionantes e vários ganchos de evento para quaisquer gatilhos.




All Articles