1

I'm trying to combine several parts of animation together by clicking a button. Here's an example:

.element {
  background-color: black;
  display: block;
  width: 160px;
  height: 160px;
  border-radius: 80%;
}
.one { 
  animation: one 1.5s ease 1 forwards;
}
.two {
  animation: two 1s forwards;
}

@keyframes one {
  from {
    transform: scale(0.25);
    opacity: 0;
  }
  25% {
    opacity: 0.5;
  }
  to {
    transform: scale(1);
    opacity: 0.5;
  }
}

@keyframes two {
  from {
    opacity: 0.5;
  }
  to {
    opacity: 0;
  }
}

I'm trying to combine these two animation: one and two. My way of doing this was to use JS: classList.add('.two') when I clicked the button. But the problem was: at the moment I added the class, the element changed to its default opacity which was 1.

To solve this, I added a new class contained styles which were actually clones of final styles of the first animation. And after the second part was finished, I had to remove the class list to prepared for the first animation to be played.

So my question is, is there a better way of doing this?

Here is a CodePen Demo

I just realised a problem with this: If I start the second animation before the first one was finished, there would be a discontinuity (the circle would just turns to a larger one all of a sudden).

The demo can be found from the above link, thanks!

Harry
  • 87,580
  • 25
  • 202
  • 214
Heyi
  • 57
  • 6
  • The two animations have exactly the reverse setting of each other for `opacity` so how can you combine the two? The question is not clear. Can you show us a demo of what you are trying to do? – Harry Mar 05 '16 at 07:34
  • Hi Harry, I'm not sure if you can open the link? Thanks a lot! http://codepen.io/q105037696/pen/MyaXpL – Heyi Mar 05 '16 at 07:54
  • Do you have to mandatorily do this with animations? You can achieve something almost the same with just transitions like shown [here](http://codepen.io/hari_shanx/pen/vGNaOd) with much less code. – Harry Mar 05 '16 at 08:55
  • Erh... This is awkward, I didn't even know about transition... I just learned about it, I think it does help. Thanks a lot! – Heyi Mar 05 '16 at 09:42
  • 1
    lol, done, thanks again for your efforts!!! – Heyi Mar 06 '16 at 07:57

1 Answers1

0

Can I combine these two animations?

I assume by combine you mean producing forward (on click of add animation) and reverse (on click of remove animation) animations using the same keyframe rules. It's possible to achieve but for that both the forward and reverse animations should be exactly the same (but in opposite directions). When it is same, we can use animation-direction: reverse to achieve reverse effect with same keyframes.

Here, the forward animation has a transform change whereas the reverse doesn't and hence adding animation-direction: reverse would not produce the same effect as the original snippet. Moreover, coding it is not as easy as just adding a property also, a lot of work is needed like mentioned here.


What is the reason for the other two issues?

The reason for both the issues (that is, the element getting opacity: 1 immediately when the remove button is clicked and element getting full size when remove button is clicked while forward animation is still happening) are the same. When you remove the animation on an element (by removing the class) it immediately snaps to the size specified outside of the animation.

For the first case, the size is the one that is mentioned under .element (as .one is removed) and its opacity is default 1 because there is no opacity setting in it. For the second case, when the .one is removed and .two is added, the animation is removed and so the element's size is as specified in .element and the opacity is as specified in .two (because that is later in CSS file).


So what else is the alternate?

When both forward and reverse effects are required and the animation doesn't have any intermediate states (that is, there is only a start state and an end state) then it is better to use transitions instead of animations. The reason is because transitions automatically produce the reverse effect on removal of the class (unlike animations where the reverse animation needs to be written as a separate keyframe and added to the element).

Below is a sample snippet showing how you can achieve a similar effect using just one class without the need for writing keyframes.

 var theBut = document.getElementById('butt');
 var theBut2 = document.getElementById('butt2');
 theBut.addEventListener('click', function a() {
   document.querySelector('.element').classList.add('one');
 });

 theBut2.addEventListener('click', function b() {
   document.querySelector('.element').classList.remove('one');
 });
.element {
  background-color: #d91e57;
  display: block;
  width: 160px;
  height: 160px;
  border-radius: 90%;
  transform: scale(0.25);
  opacity: 0;
  transition: opacity 2s, transform .1s 2s;
}
.one {
  transform: scale(1);
  opacity: 0.5;
  transition: all 2s;
}
<div class="element">
</div>
<button id="butt">add animation</button>
<button id='butt2'>remove animation</button>
Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214