简体   繁体   中英

How can I let my hamburger animation reverse?

I can't get my animation to work smoothly.

I've creating a burger icon, with three divs, like this:

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

I've got three different keyframes, for each line one.

.line:first-child {
   animation-name: firstChild;
   transform-origin: 30px 25px;
   animation-duration: 0.5s;
   animation-fill-mode: forwards;
   margin: 10px;
}

Then the keyframes:

@keyframes firstChild {
0% {transform: translateY(0);}
50% {transform: translateY(10px);}
100% {transform: rotate(-45deg);}
}

All three have slightly different animation. Child two only disappears, while child three goes up instead of down.

To do the click function, I use jquery to add / remove classes like this:

$(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; 
}

}


});

Then my plan to reverse the animation was to use the CSS animation-direction: reverse; like this:

.line:first-child.reverse {
animation-name: firstChild;
transform-origin: 30px 25px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
margin: 10px;
animation-direction: reverse;
}

Again on all three lines.

However, the problem is that while the first animation goes fine. The second time around it stops animating all together. There is no transition between the states of the Burger to Cross. Both in back and forth, like the animation can only be used once.

Is my logic wrong, or am I misunderstanding the use of the reverse animation?

Your understanding of reverse isn't completely true.

The animation plays backwards each cycle. In other words, each time the animation cycles, the animation will reset to the end state and start over again . Animation steps are performed backwards, and timing functions are also reversed. For example, an ease-in timing function becomes ease-out. ref

In your case, the animation already ended so adding reverse will not trigger the animation again, it will simply switch the start and end state.

Here is a simplified example. On hover you will see that the animation will jump and not change direction smoothly because we reverse the whole animation and we don't move back the element from where it is. It's like looking at a mirror:

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

When the animation is done, you can clearly notice how on hover we switch first and last state.


Here is an easier way to do this using transition instead of animation where you will need less of code.

I used hover but you can easily replace with a class that you add/remove

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

Working fiddle: https://jsfiddle.net/upnhcw69/38/

To solve that we need to have 2 animations and change them one with another, then they are trigegred correctly.

After first click firstChild animation is triggered after second click firstChild2 animation is triggered. We are using 2 classes with different animations.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM