Помогите новичку. Бургер меню
Пытаюсь сделать анимацию для кнопки бургер меню. По идеи сначала должны линии идти к центральной линии (плавно) а потом поворачиваться на 45 градусов (тоже плавно). На деле же первая часть анимации попросту не срабаывает, а вторая срабатывает. (Если отключить воторую часть анимации то первая сработает). Как сделать так что бы они работали вместе? (Чтобы отключить вотрую часть анимации надо удалить стили где есть класс ".menu-line")
document.querySelector('.menu-btn').addEventListener('click', (e) => {
let menuBtn = document.querySelector('.menu-btn');
if (menuBtn.classList.contains("isActive")) {
menuBtn.classList.remove("isActive");
} else {
menuBtn.classList.add("isActive");
}
})
* {
margin: 0;
padding: 0;
}
.menu-btn {
font-size: 0;
width: 50px;
height: 50px;
outline: none;
background: red;
border: none;
position: relative;
cursor: pointer;
}
.menu-btn span {
position: absolute;
height: 2px;
width: 24px;
background: white;
left: 13px;
top: 23px;
}
.menu-btn span::before, .menu-btn span::after {
display: block;
position: absolute;
height: 2px;
width: 24px;
background: white;
content: "";
}
.menu-btn span::before {
right: 0;
bottom: 10px;
transition-property: bottom;
transition-timing-function: ease;
transition-duration: 0.3s, 0.3s;
}
.menu-btn span::after {
left: 0;
top: 10px;
transition-property: top;
transition-timing-function: ease;
transition-duration: 0.3s;
}
.menu-btn.isActive span::before {
bottom: 0;
}
.menu-btn.isActive span:after {
top: 0;
}
.menu-line span::before {
transition-property: transform;
transition-timing-function: ease;
transition-duration: 0.3s;
transition-delay: 0.3s;
}
.menu-line span::after {
transition-property: transform;
transition-timing-function: ease;
transition-duration: 0.3s;
transition-delay: 0.3s;
}
.menu-line.isActive span::before {
transform: rotate(45deg);
}
.menu-line.isActive span:after {
transform: rotate(-45deg);
}
.menu-line.isActive span {
background: none;
transition: background 0s 0.3s;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="menu">
<button class="menu-btn menu-line">
<span>Меню</span>
</button>
</div>
<script src="script.js"></script>
</body>
</html>
Ответы (1 шт):
Может не совсем элегантное решение, но работает. Я использовал css анимации @keyframes и свойство animation. Разные анимации для 2 классов isActive и notActive, которые переключаются по событыю клика в JS.
document.querySelector('.menu-btn').addEventListener('click', function(_e) {
this.classList.toggle("isActive");
this.classList.remove("notActive");
if (!this.classList.contains("isActive")) this.classList.add("notActive");
});
* {
margin: 0;
padding: 0;
}
.menu-btn {
font-size: 0;
width: 50px;
height: 50px;
outline: none;
background: red;
border: none;
position: relative;
cursor: pointer;
}
.menu-btn span {
position: absolute;
height: 2px;
width: 24px;
background: white;
left: 13px;
top: 23px;
transition-timing-function: ease;
transition-duration: 0.3s;
}
.menu-btn span::before, .menu-btn span::after {
display: block;
position: absolute;
height: 2px;
width: 24px;
background: white;
content: " ";
transition-timing-function: ease;
transition-duration: 0.3s;
}
.menu-btn span::before {
right: 0;
bottom: 10px;
transition-property: bottom;
}
.menu-btn span::after {
left: 0;
top: 10px;
transition-property: top;
}
@keyframes clockwise {
0% {
bottom: 10px;
transform: rotate(0deg);
}
50% {
bottom: 0px;
transform: rotate(0deg);
}
80% {
transform: rotate(0deg);
}
100% {
transform: rotate(45deg);
}
}
@keyframes counterclockwise {
0% {
top: 10px;
}
50% {
top: 0px;
transform: rotate(0deg);
}
90% {
transform: rotate(0deg);
}
100% {
transform: rotate(-45deg);
}
}
@keyframes clockwiseback {
0% {
transform: rotate(45deg);
}
50% {
transform: rotate(0deg);
}
70% {
bottom: 0px;
}
100% {
bottom: 10px;
}
}
@keyframes counterclockwiseback {
0% {
transform: rotate(-45deg);
}
50% {
transform: rotate(0deg);
}
70% {
top: 0px;
}
100% {
top: 10px;
}
}
.menu .isActive span::before {
bottom: 0;
animation: .3s clockwise ease;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.menu .isActive span:after {
top: 0;
animation: .3s counterclockwise ease;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.menu .notActive span::before {
bottom: 0;
animation: .3s clockwiseback ease;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.menu .notActive span:after {
top: 0;
animation: .3s counterclockwiseback ease;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.menu .isActive span {
background: transparent;
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="menu">
<button class="menu-btn menu-line">
<span>Меню</span>
</button>
</div>
</body>
</html>
Можно еще использовать Element.animate() в связке с svg, но это уже другая история.