Полноэкранная круговая анимационная навигация на CSS и jQuer

Экспериментальная полноэкранная навигация, анимированная с использованием CSS и jQuery, которая расширяется в пределах круга.

 

ДЕМО
ИСХОДНИКИ

 

Я просматривал приложение Ping iOS - itunes.apple.com/gb/app/id922669797?mt=8. Эффект при нажатии на круг для переключения страницы слишком крут, поэтому я хочу вам показать что-то подобное в CSS и jQuery. Результат довольно интересный, поэтому мы решили выпустить этот фрагмент :) Это экспериментальная навигация, но она поддерживается всеми основными браузерами - мы использовали Velocity.js (julian.com/research/velocity) - и я уверен, что вы, ребята, найдете способ использовать это!

 

Создание структуры

В структуре HTML мы использовали неупорядоченный список для навигации, семантически завернутый в элемент <nav>. Содержимое .cd-overlay-nav и .cd-overlay-content используются для анимации круглой формы. Именно они используются в качестве контейнеров, чтобы расположить круги прямо за иконкой верхнего правого меню, а элементы <span> внутри - это два цветных круга, которые расширяются. Наконец, .cd-nav-trigger - это значок меню, который анимируется в виде перекрестного значка.

<header>
<a class="cd-logo" href="#0"><img src="img/cd-logo.svg" alt="Logo"></a>
</header>

<nav>
<ul class="cd-primary-nav">
<li><a href="#0">The team</a></li>
<li><a href="#0">Our services</a></li>
<li><a href="#0">Our projects</a></li>
<li><a href="#0">Start a project</a></li>
<li><a href="#0">Join In</a></li>
<li><a href="#0">Create an account</a></li>
</ul>
</nav>

<main class="cd-content">
<!-- your content here -->
</main>

<div class="cd-overlay-nav">
<span></span>
</div> <!-- cd-overlay-nav -->

<div class="cd-overlay-content">
<span></span>
</div> <!-- cd-overlay-content -->

<a href="#0" class="cd-nav-trigger">Menu<span class="cd-icon"></span></a>

 

Добавление стиля

Если вы посмотрите на CSS, вы заметите, что кнопка триггера .cd-nav-trigger находится в position:fixed в правом верхнем углу. Чтобы эффект работал правильно, нам пришлось центрировать контейнеры (.cd-overlay-nav и .cd-overlay-content) из 2 анимированных кругов прямо за курок. Чтобы сделать это, нам нужно было определить фиксированную высоту и ширину для них обоих. Но если вы посмотрите на элементы <span>, которые на самом деле являются анимированными кругами, вы можете заметить, что мы не определяли какое-либо значение позиционирования или размера. Поскольку круг должен покрывать весь экран, независимо от размера видового экрана, мы определяем позиционирование (верхнее и левое значения) и размер (ширину) в jQuery.

.cd-nav-trigger {
	top: 18px;
	right: 5%;
	height: 44px;
	width: 44px;
	z-index: 5;
	/* image replacement */
	overflow: hidden;
	text-indent: 100%;
	white-space: nowrap;
}
 
.cd-overlay-nav, .cd-overlay-content {
	/* containers of the 2 main rounded backgrounds - these containers are used to position the rounded bgs behind the menu icon */
	position: fixed;
	top: 18px;
	right: 5%;
	height: 4px;
	width: 4px;
	transform: translateX(-20px) translateY(20px);
}
 
.cd-overlay-nav span, .cd-overlay-content span {
	display: inline-block;
	position: absolute;
	border-radius: 50%;
	will-change: transform;
	transform: scale(0);
}

Идея состояла в том, чтобы анимировать значок меню, а не просто заменить «гамбургер» значком «закрыть», поэтому мы добавили элемент <span> (.cd-icon) внутри триггера. Таким образом, мы можем создавать и анимировать значок с использованием ::before и ::after псевдоэлементов.

.cd-nav-trigger .cd-icon {
	/* icon created in CSS */
	position: absolute;
	left: 50%;
	top: 50%;
	bottom: auto;
	right: auto;
	transform: translateX(-50%) translateY(-50%);
	display: inline-block;
	width: 18px;
	height: 3px;
	background-color: #ffffff;
	z-index: 10;
}
 
.cd-nav-trigger .cd-icon::before, .cd-nav-trigger .cd-icon:after {
	/* upper and lower lines of the menu icon */
	position: absolute;
	top: 0;
	right: 0;
	width: 100%;
	height: 100%;
	background-color: inherit;
	transition: transform .3s;
}
 
.cd-nav-trigger .cd-icon::before {
 	transform: translateY(-6px) rotate(0deg);
}
 
.cd-nav-trigger .cd-icon::after {
  transform: translateY(6px) rotate(0deg);
}
 
.cd-nav-trigger.close-nav .cd-icon {
  /* user clicks on the .cd-nav-trigger element - transform the icon */
  background-color: rgba(255, 255, 255, 0);
}
 
.cd-nav-trigger.close-nav .cd-icon::before, .cd-nav-trigger.close-nav .cd-icon::after {
  background-color: white;
}
 
.cd-nav-trigger.close-nav .cd-icon::before {
  transform: translateY(0) rotate(45deg);
}
 
.cd-nav-trigger.close-nav .cd-icon::after {
  transform: translateY(0) rotate(-45deg);
}

Цвет фона меню / триггера изменяется, и он оживлен с небольшой задержкой. Еще раз мы использовали 2 псевдоэлемента для достижения этого эффекта:

.cd-nav-trigger::before, .cd-nav-trigger::after {
  /* 2 rounded colored backgrounds for the menu icon */
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 50%;
  height: 100%;
  width: 100%;
  transition-property: transform;
}
.cd-nav-trigger::before {
  background-color: #091d23;
  transform: scale(1);
  transition-duration: 0.3s;
  transition-delay: 0.4s;
}
.cd-nav-trigger::after {
  background-color: #ffb441;
  transform: scale(0);
  transition-duration: 0s;
  transition-delay: 0s;
}
.cd-nav-trigger.close-nav::before {
  /* user clicks on the .cd-nav-trigger element - 1st rounded background disappears */
  transform: scale(0);
}
.cd-nav-trigger.close-nav::after {
  /* user clicks on the .cd-nav-trigger element - 2nd rounded background appears */
  transform: scale(1);
  transition-duration: 0.3s;
  transition-delay: 0.4s;
}

 

Обработка событий

Прежде чем погрузиться в jQuery, я хотел бы объяснить, что происходит в нескольких простых словах: когда пользователь щелкает / нажимает на кнопку меню, мы анимируем <span> внутри .cd-overlay-nav. Когда круг заполняет экран, мы показываем навигацию. Когда пользователь снова нажимает / повторяет триггер, чтобы закрыть навигацию, мы анимируем <span> внутри содержимого cd-overlay-content. В конце этой анимации мы скроем первый круг и навигацию, которые все еще там, просто не видны, потому что они имеют более низкий индекс z. Наконец, мы уменьшаем непрозрачность формы второго раунда (желтый в демо), тем самым раскрывая контент - и притворяясь, что контент находится поверх навигации.

О jQuery мы определили положение и размер элемента <span> круги (используя функцию initLayer()). Мы назначили высоту, равную удвоенной диагонали окна просмотра, а верхнюю (и левую) равную отрицательному значению диагональ окна просмотра (<span> находится внутри содержимого .cd-overlay-nav / cd-overlay-content и имеет position: absolute).

Когда пользователь сначала нажимает на .cd-nav-trigger, мы анимируем элемент span .cd-overlay-nav span, меняя его значение scale от 0 до 1 (мы использовали Velocity.js - julian.com/research/velocity для анимации):

var overlayNav = $('.cd-overlay-nav'),
	toggleNav = $('.cd-nav-trigger'),
	navigation = $('.cd-primary-nav');
 
toggleNav.on('click', function(){
	if(!toggleNav.hasClass('close-nav')) {
		//animate menu icon into a cross icon
		toggleNav.addClass('close-nav');
		//animate the navigation layer
		overlayNav.children('span').velocity({
			translateZ: 0,
			scaleX: 1,
			scaleY: 1,
		}, 500, 'easeInCubic', function(){
			//show navigation
			navigation.addClass('fade-in');
		});
	}
}

Когда пользователь нажимает кнопку .cd-nav-trigger, чтобы закрыть меню, мы анимируем значение шкалы диапазона cd-overlay-content span:

var overlayNav = $('.cd-overlay-nav'),
	overlayContent = $('.cd-overlay-content'),
	toggleNav = $('.cd-nav-trigger'),
	navigation = $('.cd-primary-nav');
 
toggleNav.on('click', function(){
	if(!toggleNav.hasClass('close-nav')) {
		//it means navigation is not visible yet - open it and animate navigation layer
		//....
	} else {
		//animate cross icon into a menu icon
		toggleNav.removeClass('close-nav');
		//animate the content layer
		overlayContent.children('span').velocity({
			translateZ: 0,
			scaleX: 1,
			scaleY: 1,
		}, 500, 'easeInCubic', function(){
			//hide navigation
			navigation.removeClass('fade-in');
			//scale to zero the navigation layer
			overlayNav.children('span').velocity({
				translateZ: 0,
				scaleX: 0,
				scaleY: 0,
			}, 0);
			//reduce to opacity of the content layer with the is-hidden class
			overlayContent.addClass('is-hidden').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
				//wait for the end of the transition and scale to zero the content layer
				overlayContent.children('span').velocity({
					translateZ: 0,
					scaleX: 0,
					scaleY: 0,
				}, 0, function(){overlayContent.removeClass('is-hidden')});
 
			});
		});
	}
});

 

Вот и всё!


Top

🔖 Выбор по тегам ×

💌 Написать сообщение ×

Все поля обязательны для заполнения!