Страницы

Поиск по вопросам

суббота, 30 ноября 2019 г.

CSS анимированное шестиугольное меню

#javascript #html #css #css3 #svg


Я пытаюсь создать анимированное шестиугольное меню.     

Пожалуйста, посмотрите для лучшего понимания  рисунок:

    

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

Поэтому мой вопрос заключается в следующем:   

Как  создавать эту анимацию из шестиугольника с помощью  HTML, CSS через jQuery или
другими способами.      

Какие способы вы бы использовали, чтобы сделать это?

Источник
    


Ответы

Ответ 1



Вариант с CSS-переменными + clip-path. Тут не вся функциональность, это лишь набросок, но идея, думаю, понятна. UPD: добавил кнопку и еще немного причесал код. document.querySelector('.menu__btn').addEventListener('click', () => { document.querySelector('.menu').classList.toggle('menu--open'); }); :root { --side: 200px; --a: 25% 5%; --b: 75% 5%; --c: 100% 50%; --d: 75% 95%; --e: 25% 95%; --f: 0% 50%; --g: 50% 50%; --x: 0; --y: 0; --coordAfter: 25px; } .menu { width: var(--side); height: var(--side); padding: 0; margin: 50px auto; position: relative; } .menu__list { padding: 0; margin: 0; list-style-type: none; } .menu__triangle { position: absolute; left: 0; top: 0; transition: transform .25s, opacity .25s; background-color: #d261ff; width: var(--side); height: var(--side); opacity: 0; } .menu__triangle:hover { background-color: #9c29c1; } .menu--open .menu__triangle { transform: translate3d(var(--x), var(--y), 0); opacity: 1; } .menu__btn { border: none; background: none; position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; background: #250031; clip-path: polygon(var(--a), var(--b), var(--c), var(--d), var(--e), var(--f)); font-size: 0; width: calc(var(--side) / 6); height: calc(var(--side) / 6); z-index: 1; text-align: center; } .menu__btn:hover, .menu--open .menu__btn { background-color: #613175; } .menu__btn-dash { width: calc(var(--side) / 14.285); background-color: #fff; height: 2px; display: inline-block; vertical-align: middle; position: relative; } .menu__btn-dash:after { width: inherit; height: inherit; left: 0; top: 0; background-color: inherit; transform: rotate(90deg); transform-origin: 50% 50%; transition: transform .2s; position: absolute; content: ' '; } .menu--open .menu__btn-dash:after { transform: rotate(0); } .menu__1 { clip-path: polygon(var(--a), var(--b) , var(--g)); --y: calc(var(--coordAfter) * -1); } .menu__2 { clip-path: polygon(var(--g), var(--b), var(--c)); --y: calc(var(--coordAfter) * -1/2); --x: var(--coordAfter); } .menu__3 { clip-path: polygon(var(--g), var(--c), var(--d)); --y: calc(var(--coordAfter) / 2); --x: var(--coordAfter); } .menu__4 { clip-path: polygon(var(--e), var(--g), var(--d)); --y: var(--coordAfter); } .menu__5 { clip-path: polygon(var(--f), var(--g), var(--e)); --x: calc(var(--coordAfter) * -1); --y: calc(var(--coordAfter) / 2); } .menu__6 { clip-path: polygon(var(--f), var(--a), var(--g)); --x: calc(var(--coordAfter) * -1); --y: calc(var(--coordAfter) * -1/2); }

Ответ 2



Вот пример и демонстрация: Hexagon menu demo И вот анимация gif шестиугольника в действии: Основные функции меню шестиугольника: адаптивность - в зависимости от размера viewport (vmin). Это можно изменить, изменив значения width/height на проценты (соотношениесторон должно поддерживаться см. здесь) Изображения (с тегом ), титры и субтитры 6 пунктов меню анимированный значок гамбургера в шестиугольном контуре границы пунктов меню привязаны к треугольникам, чтобы они не перекрывали друг друга.Таким образом, событие click и hover state запускаются только тогда, когда фактический элемент меню - hovered/clicked Может отображаться над изображениями, градиентами или любыми неосновными фонами Шестиугольная компоновка: CSS3 2d transforms позволяет создавать треугольники skewY() и rotate() элементы меню привязаны к треугольникам с помощью классов - .tr и .clip, unskewed с .clip и возврат поворота связан с классом .content, форма шестиугольника вокруг гамбургера выполнена полигоном SVG (легче сделать и получить лучший результат, чем с CSS Значок гамбургера выполнен с помощью span и двумя псевдоэлементами Шестиугольное меню с анимацией: треугольники переходят один за другим (translate() и opacity) со свойством transition-delay "bounce effect" для треугольника с анимацией производится с помощью функции transition-timming-function и кубической кривой безье. Значок гамбургера для перекрестной анимации создается путем перехода двух псевдоэлементов (translate() и rotate()) и затухания фона центральных элементов до прозрачного цвета rgba Hover анимация : эффект наведения гамбургера достигается путем анимации свойства stroke-dashoffset элемента SVG . названия элементов и субтитры отображаются при наведении с использованием 3D transforms (translateZ()) и непрозрачности. Изображения одновременно исчезают Используемая технология: CSS кодируется с помощью SCSS и Autoprefixer, чтобы упростить запись, чтение и сокращение. Вы можете увидеть скомпилированный CSS, нажав кнопку Скомпилированный вид в демоверсии (скомпилированный CSS также доступен в конце этого сообщения) Использован SVG для шестиугольника вокруг иконки гамбургера HTML для разметки простой JS для переключения анимации с добавлением класса на контейнере Поддержка браузерами: Я тестировал это меню на IE 11, chrome, FF и opera в системе Windows и меню работает во всех этих браузерах. Chrome и FF визуализируют шрифт с размытием (как видно в анимированном gif, сделанном из хрома), и FF имеет тенденцию создавать зубчатые стороны для треугольников IE 11 имеет наилучшее качество для шрифтов и треугольников, но он не поддерживает анимацию SMIL и, следовательно, не оказывает эффекта наведения на шестиугольник гамбургера Я использовал тестирование crossbrowser для проверки поддержки safari, и в этой системе также работает шестиугольное меню. var hexNav = document.getElementById('hexNav'); document.getElementById('menuBtn').onclick = function() { var className = ' ' + hexNav.className + ' '; if ( ~className.indexOf(' active ') ) { hexNav.className = className.replace(' active ', ' '); } else { hexNav.className += ' active'; } } * { margin: 0; padding: 0; } html, body { height: 100%; } body { font-family: 'Open Sans', sans-serif; background: #E3DFD2; } ul { list-style-type: none; } a, a:hover, a:focus, a:visited { text-decoration: none; } nav { position: relative; width: 70vmin; height: 70vmin; min-width: 500px; min-height: 500px; margin: 0 auto; overflow: hidden; } /** MENU BUTTON ******************************************/ #menuBtn { position: absolute; top: 45%; left: 45%; width: 10%; height: 10%; cursor: pointer; z-index: 2; will-change: transform; } #menuBtn svg { display: block; } #menuBtn:hover svg polygon { -webkit-animation: hexHover 0.7s; animation: hexHover 0.7s; } #menuBtn span { position: absolute; top: 50%; left: 50%; width: 20px; height: 2px; padding: 8px 0; background-clip: content-box; background-color: #585247; -webkit-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); transform: translate(-50%, -50%); -webkit-transition: background-color 0.5s; transition: background-color 0.5s; } #menuBtn span:before, #menuBtn span:after { position: absolute; background-color: #585247; content: ''; width: 20px; height: 2px; -webkit-transition: -webkit-transform 0.5s; transition: transform 0.5s; } #menuBtn span:before { top: 0; } #menuBtn span:after { bottom: 0px; } @-webkit-keyframes hexHover { 0% { stroke-dasharray: 0,0,300; } 10% { stroke-dasharray: 0,20,300; } 100% { stroke-dasharray: 300,20,300; } } @keyframes hexHover { 0% { stroke-dasharray: 0,0,300; } 10% { stroke-dasharray: 0,20,300; } 100% { stroke-dasharray: 300,20,300; } } /** MENU ITEMS *******************************************/ #hex { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-transform: scale(0.1) translatez(0); -ms-transform: scale(0.1) translatez(0); transform: scale(0.1) translatez(0); -webkit-transition: -webkit-transform 0.05s 0.5s; transition: transform 0.05s 0.5s; } .tr { position: absolute; left: 50%; bottom: 50%; width: 34.6%; height: 40%; -webkit-transform-origin: 0 100%; -ms-transform-origin: 0 100%; transform-origin: 0 100%; overflow: hidden; -webkit-transform: skewY(-30deg); -ms-transform: skewY(-30deg); transform: skewY(-30deg); opacity: 0; } .tr:nth-child(1) { -webkit-transform: rotate(0deg) skewY(-30deg); -ms-transform: rotate(0deg) skewY(-30deg); transform: rotate(0deg) skewY(-30deg); -webkit-transition: opacity 0.5s, -webkit-transform 0.5s; transition: opacity 0.5s, transform 0.5s; } .tr:nth-child(1) .clip { -webkit-transform: skewY(30deg) rotate(30deg); -ms-transform: skewY(30deg) rotate(30deg); transform: skewY(30deg) rotate(30deg); } .tr:nth-child(1) .content { -webkit-transform: rotate(-30deg); -ms-transform: rotate(-30deg); transform: rotate(-30deg); -webkit-transform-origin: 0 0; -ms-transform-origin: 0 0; transform-origin: 0 0; padding-left: 15%; -webkit-perspective-origin: 30% 70%; perspective-origin: 30% 70%; } .active .tr:nth-child(1) { -webkit-transform: rotate(0deg) skewY(-30deg) translate(10%, -10%); -ms-transform: rotate(0deg) skewY(-30deg) translate(10%, -10%); transform: rotate(0deg) skewY(-30deg) translate(10%, -10%); -webkit-transition: opacity 0.5s 0.05s, -webkit-transform 0.5s 0.05s cubic-bezier(0, 2.3, 0.8, 1); transition: opacity 0.5s 0.05s, transform 0.5s 0.05s cubic-bezier(0, 2.3, 0.8, 1); } .tr:nth-child(2) { -webkit-transform: rotate(60deg) skewY(-30deg); -ms-transform: rotate(60deg) skewY(-30deg); transform: rotate(60deg) skewY(-30deg); -webkit-transition: opacity 0.5s, -webkit-transform 0.5s; transition: opacity 0.5s, transform 0.5s; } .tr:nth-child(2) .clip { -webkit-transform: skewY(30deg) rotate(30deg); -ms-transform: skewY(30deg) rotate(30deg); transform: skewY(30deg) rotate(30deg); } .tr:nth-child(2) .content { -webkit-transform: rotate(-90deg); -ms-transform: rotate(-90deg); transform: rotate(-90deg); top: -8%; left: 6.67%; padding-left: 30%; -webkit-perspective-origin: 30% 50%; perspective-origin: 30% 50%; } .active .tr:nth-child(2) { -webkit-transform: rotate(60deg) skewY(-30deg) translate(10%, -10%); -ms-transform: rotate(60deg) skewY(-30deg) translate(10%, -10%); transform: rotate(60deg) skewY(-30deg) translate(10%, -10%); -webkit-transition: opacity 0.5s 0.1s, -webkit-transform 0.5s 0.1s cubic-bezier(0, 2.3, 0.8, 1); transition: opacity 0.5s 0.1s, transform 0.5s 0.1s cubic-bezier(0, 2.3, 0.8, 1); } .tr:nth-child(3) { -webkit-transform: rotate(120deg) skewY(-30deg); -ms-transform: rotate(120deg) skewY(-30deg); transform: rotate(120deg) skewY(-30deg); -webkit-transition: opacity 0.5s, -webkit-transform 0.5s; transition: opacity 0.5s, transform 0.5s; } .tr:nth-child(3) .clip { -webkit-transform: skewY(30deg) rotate(30deg); -ms-transform: skewY(30deg) rotate(30deg); transform: skewY(30deg) rotate(30deg); } .tr:nth-child(3) .content { -webkit-transform: rotate(-150deg); -ms-transform: rotate(-150deg); transform: rotate(-150deg); -webkit-transform-origin: 42.3% 36.5%; -ms-transform-origin: 42.3% 36.5%; transform-origin: 42.3% 36.5%; padding-left: 10%; -webkit-perspective-origin: 30% 30%; perspective-origin: 30% 30%; } .active .tr:nth-child(3) { -webkit-transform: rotate(120deg) skewY(-30deg) translate(10%, -10%); -ms-transform: rotate(120deg) skewY(-30deg) translate(10%, -10%); transform: rotate(120deg) skewY(-30deg) translate(10%, -10%); -webkit-transition: opacity 0.5s 0.15s, -webkit-transform 0.5s 0.15s cubic-bezier(0, 2.3, 0.8, 1); transition: opacity 0.5s 0.15s, transform 0.5s 0.15s cubic-bezier(0, 2.3, 0.8, 1); } .tr:nth-child(4) { -webkit-transform: rotate(180deg) skewY(-30deg); -ms-transform: rotate(180deg) skewY(-30deg); transform: rotate(180deg) skewY(-30deg); -webkit-transition: opacity 0.5s, -webkit-transform 0.5s; transition: opacity 0.5s, transform 0.5s; } .tr:nth-child(4) .clip { -webkit-transform: skewY(30deg) rotate(30deg); -ms-transform: skewY(30deg) rotate(30deg); transform: skewY(30deg) rotate(30deg); } .tr:nth-child(4) .content { -webkit-transform: rotate(-210deg); -ms-transform: rotate(-210deg); transform: rotate(-210deg); -webkit-transform-origin: 65.4% 38.4%; -ms-transform-origin: 65.4% 38.4%; transform-origin: 65.4% 38.4%; padding-left: 30%; -webkit-perspective-origin: 70% 30%; perspective-origin: 70% 30%; } .active .tr:nth-child(4) { -webkit-transform: rotate(180deg) skewY(-30deg) translate(10%, -10%); -ms-transform: rotate(180deg) skewY(-30deg) translate(10%, -10%); transform: rotate(180deg) skewY(-30deg) translate(10%, -10%); -webkit-transition: opacity 0.5s 0.2s, -webkit-transform 0.5s 0.2s cubic-bezier(0, 2.3, 0.8, 1); transition: opacity 0.5s 0.2s, transform 0.5s 0.2s cubic-bezier(0, 2.3, 0.8, 1); } .tr:nth-child(5) { -webkit-transform: rotate(240deg) skewY(-30deg); -ms-transform: rotate(240deg) skewY(-30deg); transform: rotate(240deg) skewY(-30deg); -webkit-transition: opacity 0.5s, -webkit-transform 0.5s; transition: opacity 0.5s, transform 0.5s; } .tr:nth-child(5) .clip { -webkit-transform: skewY(30deg) rotate(30deg); -ms-transform: skewY(30deg) rotate(30deg); transform: skewY(30deg) rotate(30deg); } .tr:nth-child(5) .content { -webkit-transform: rotate(-270deg); -ms-transform: rotate(-270deg); transform: rotate(-270deg); top: -8%; left: 6.67%; padding-left: 15%; -webkit-perspective-origin: 70% 50%; perspective-origin: 70% 50%; } .active .tr:nth-child(5) { -webkit-transform: rotate(240deg) skewY(-30deg) translate(10%, -10%); -ms-transform: rotate(240deg) skewY(-30deg) translate(10%, -10%); transform: rotate(240deg) skewY(-30deg) translate(10%, -10%); -webkit-transition: opacity 0.5s 0.25s, -webkit-transform 0.5s 0.25s cubic-bezier(0, 2.3, 0.8, 1); transition: opacity 0.5s 0.25s, transform 0.5s 0.25s cubic-bezier(0, 2.3, 0.8, 1); } .tr:nth-child(6) { -webkit-transform: rotate(300deg) skewY(-30deg); -ms-transform: rotate(300deg) skewY(-30deg); transform: rotate(300deg) skewY(-30deg); -webkit-transition: opacity 0.5s, -webkit-transform 0.5s; transition: opacity 0.5s, transform 0.5s; } .tr:nth-child(6) .clip { -webkit-transform: skewY(30deg) rotate(30deg); -ms-transform: skewY(30deg) rotate(30deg); transform: skewY(30deg) rotate(30deg); } .tr:nth-child(6) .content { -webkit-transform: rotate(-330deg); -ms-transform: rotate(-330deg); transform: rotate(-330deg); -webkit-transform-origin: 106.7% 25.2%; -ms-transform-origin: 106.7% 25.2%; transform-origin: 106.7% 25.2%; padding-left: 30%; -webkit-perspective-origin: 70% 70%; perspective-origin: 70% 70%; } .active .tr:nth-child(6) { -webkit-transform: rotate(300deg) skewY(-30deg) translate(10%, -10%); -ms-transform: rotate(300deg) skewY(-30deg) translate(10%, -10%); transform: rotate(300deg) skewY(-30deg) translate(10%, -10%); -webkit-transition: opacity 0.5s 0.3s, -webkit-transform 0.5s 0.3s cubic-bezier(0, 2.3, 0.8, 1); transition: opacity 0.5s 0.3s, transform 0.5s 0.3s cubic-bezier(0, 2.3, 0.8, 1); } .tr:nth-child(7) { -webkit-transform: rotate(360deg) skewY(-30deg); -ms-transform: rotate(360deg) skewY(-30deg); transform: rotate(360deg) skewY(-30deg); -webkit-transition: opacity 0.5s, -webkit-transform 0.5s; transition: opacity 0.5s, transform 0.5s; } .tr:nth-child(7) .clip { -webkit-transform: skewY(30deg) rotate(30deg); -ms-transform: skewY(30deg) rotate(30deg); transform: skewY(30deg) rotate(30deg); } .tr:nth-child(7) .content { -webkit-transform: rotate(-390deg); -ms-transform: rotate(-390deg); transform: rotate(-390deg); } .active .tr:nth-child(7) { -webkit-transform: rotate(360deg) skewY(-30deg) translate(10%, -10%); -ms-transform: rotate(360deg) skewY(-30deg) translate(10%, -10%); transform: rotate(360deg) skewY(-30deg) translate(10%, -10%); -webkit-transition: opacity 0.5s 0.35s, -webkit-transform 0.5s 0.35s cubic-bezier(0, 2.3, 0.8, 1); transition: opacity 0.5s 0.35s, transform 0.5s 0.35s cubic-bezier(0, 2.3, 0.8, 1); } .clip { position: absolute; top: 0; left: 0; width: 116%; height: 86.66%; overflow: hidden; -webkit-transform-origin: 0 0; -ms-transform-origin: 0 0; transform-origin: 0 0; } .content { position: absolute; width: 86.6%; height: 116%; top: 0; left: 0; box-sizing: border-box; font-size: 2vmin; -webkit-perspective: 500px; perspective: 500px; background: #000; } .content img { position: absolute; top: 0; left: -50%; right: -50%; margin: auto; height: 100%; z-index: -1; -webkit-transition: opacity 0.3s; transition: opacity 0.3s; pointer-events: none; } .content h2, .content p { position: absolute; width: 60%; line-height: 1em; color: #fff; opacity: 0; -webkit-transform: translateZ(-50px); transform: translateZ(-50px); } .content h2 { bottom: 50%; text-transform: uppercase; font-weight: 900; font-size: 2em; -webkit-transition: -webkit-transform 0.3s cubic-bezier(0, 2.3, 0.8, 1), opacity 0.3s; transition: transform 0.3s cubic-bezier(0, 2.3, 0.8, 1), opacity 0.3s; } .content p { position: absolute; top: 50%; font-size: 1em; -webkit-transition: -webkit-transform 0.3s 0.075s cubic-bezier(0, 2.3, 0.8, 1), opacity 0.3s 0.075s; transition: transform 0.3s 0.075s cubic-bezier(0, 2.3, 0.8, 1), opacity 0.3s 0.075s; } .content:hover h2, .content:hover p { opacity: 1; -webkit-transform: translatez(0); -ms-transform: translatez(0); transform: translatez(0); } .content:hover img { opacity: 0.4; } .active #menuBtn:hover svg polygon { -webkit-animation: none; animation: none; } .active #menuBtn span { background-color: transparent; } .active #menuBtn span:before { -webkit-transform: translatey(8px) rotate(45deg); -ms-transform: translatey(8px) rotate(45deg); transform: translatey(8px) rotate(45deg); } .active #menuBtn span:after { -webkit-transform: translatey(-8px) rotate(-45deg); -ms-transform: translatey(-8px) rotate(-45deg); transform: translatey(-8px) rotate(-45deg); } .active #hex { -webkit-transform: scale(0.9) translatez(0); -ms-transform: scale(0.9) translatez(0); transform: scale(0.9) translatez(0); -webkit-transition: none; transition: none; will-change: transform; } .active .tr { opacity: 1; will-change: transform; } Источник

Комментариев нет:

Отправить комментарий