Как я могу позволить моей анимации гамбургера вернуться?
Я не могу заставить мою анимацию работать плавно.
Я создал иконку бургера, с тремя элементами, например:
<div class="container">
<div class="burger-contain">
<div id="line-1" class="line"></div>
<div id="line-2" class="line"></div>
<div id="line-3" class="line"></div>
</div>
</div>
У меня есть три разных ключевых кадра для каждой строки.
.line:first-child {
animation-name: firstChild;
transform-origin: 30px 25px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
margin: 10px;
}
Тогда ключевые кадры:
@keyframes firstChild {
0% {transform: translateY(0);}
50% {transform: translateY(10px);}
100% {transform: rotate(-45deg);}
}
Все три имеют немного различную анимацию. Ребенок два только исчезает, а ребенок три идет вверх, а не вниз.
Чтобы сделать функцию щелчка, я использую jquery для добавления / удаления классов следующим образом:
$(document).ready(function(){
var line = $(".line");
var burger = $(".burger-contain")
var toggled = false;
burger.click(function(){
triggerAnimation();
});
function triggerAnimation(){
if (toggled === false){
line.removeClass("reverse");
line.addClass("animate");
toggled = true;
} else {
line.removeClass("animate");
line.addClass("reverse");
toggled = false;
}
}
});
Тогда мой план обратить анимацию в том, чтобы использовать CSS animation-direction: reverse;
как это:
.line:first-child.reverse {
animation-name: firstChild;
transform-origin: 30px 25px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
margin: 10px;
animation-direction: reverse;
}
Снова по всем трем линиям.
Однако проблема в том, что пока первая анимация идет нормально. Во второй раз это перестает анимировать все вместе. Между состояниями Бургера и Креста нет перехода. Как вперед-назад, так и анимацию можно использовать только один раз.
Моя логика неверна или я неправильно понимаю использование обратной анимации?
2 ответа
Ваше понимание обратного не совсем верно.
Анимация воспроизводится в обратном направлении каждого цикла. Другими словами, каждый раз, когда анимация циклически повторяется, анимация сбрасывается в конечное состояние и начинается снова. Этапы анимации выполняются в обратном направлении, а функции синхронизации также меняются местами. Например, функция синхронизации замедления становится замедлением. ссылка
В вашем случае анимация уже закончилась, поэтому добавление reverse
не будет запускать анимацию снова, она просто переключит начальное и конечное состояние.
Вот упрощенный пример. При наведении курсора вы увидите, что анимация будет прыгать, а не менять направление плавно, потому что мы переворачиваем всю анимацию и не перемещаем элемент туда, где он находится. Это как смотреть в зеркало:
.box {
width:50px;
height:50px;
background:red;
animation:change 5s linear forwards;
}
@keyframes change {
from {transform:translateX(0)}
to {transform:translateX(300px)}
}
body:hover .box{
animation-direction:reverse;
}
<div class="box">
</div>
Когда анимация завершена, вы можете четко заметить, как при наведении мыши мы переключаем первое и последнее состояние.
Вот более простой способ сделать это, используя переход вместо анимации, где вам потребуется меньше кода.
Я использовал hover, но вы можете легко заменить класс, который вы добавляете / удаляете
.menu {
height:50px;
width:60px;
position:relative;
margin:50px;
background:
linear-gradient(#000,#000) center/100% 10px no-repeat;
transition:all 0s 0.5s;
}
.menu:before,
.menu:after{
content:"";
position:absolute;
left:0;
height:10px;
width:100%;
background:#000;
transition:0.5s 0.5s top,0.5s 0.5s bottom,0.5s transform;
}
.menu:before {
top:0;
}
.menu:after {
bottom:0;
}
.menu:hover {
background-size:0px 0px;
}
.menu:hover:before {
top:calc(50% - 5px);
transform:rotate(45deg);
transition:0.5s top,0.5s 0.5s transform;
}
.menu:hover:after {
bottom:calc(50% - 5px);
transform:rotate(-45deg);
transition:0.5s bottom,0.5s 0.5s transform;
}
<div class="menu">
</div>
Рабочая скрипка: https://jsfiddle.net/upnhcw69/38/
Чтобы решить эту проблему, нам нужно иметь 2 анимации и менять их одну на другую, тогда они корректно срабатывают.
После первого клика анимация firstChild запускается после второго клика анимация firstChild2. Мы используем 2 класса с разными анимациями.
.line{
height: 10px;
width: 100px;
margin: 10px;
background-color:red;
}
@keyframes firstChild {
0% {transform: translateY(0);}
50% {transform: translateY(10px);}
100% {transform: rotate(-45deg);}
}
@keyframes firstChild2 {
0% {transform: rotate(-45deg);}
50% {transform: translateY(10px);}
100% {transform: rotate(0deg);}
}
.animate {
animation-name: firstChild;
transform-origin: 30px 25px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
.reverse {
animation-name: firstChild2;
transform-origin: 30px 25px;
animation-duration: 0.5s;
}