-1

I have a keyframe animation which plays when I hover on element. After the mouseout event, it stops too abruptly. How could I force it play till it's end? I tried on.(animationend) event, it doesn't work. Transform origin and huge delay, either don't work. Thanks.

CodePen Demo

class Main {
  constructor() {

  }


  waveOn() {
    $(this).addClass('wave-active');
  }

  waveOut() {
    var elem = $('.info__block');

    elem.removeClass('wave-active');
  }

  jsInit() {
    $('.info__block').hover(this.waveOn);
    $('.info__block').on('animationend', this.waveOut)
  }

}

new Main().jsInit();
.info__block {
  width: 100px;
  height: 100px;
  background: aqua;
  border-radius: 50px;
  position: relative;
  display: flex;
  justify-content: center;
  margin-top: 100px;
}

.info__block:before {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50px;
  border-top: 2px solid aqua;
}

.info__block.wave-active:before {
  animation: link-line 2.5s infinite .5s linear;
}

@keyframes link-line {
  0% {
    transform: translateY(0);
    opacity: 1;
  }
  60% {
    opacity: 0;
  }
  100% {
    transform: translateY(-50%) scale(1.6);
    opacity: 0;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="info__block info__block-1">
</div>
Harry
  • 87,580
  • 25
  • 202
  • 214
Alex
  • 73
  • 1
  • 1
  • 7
  • 1
    Looks like a dupe of http://stackoverflow.com/questions/31806649/how-to-run-the-css3-animation-to-the-end-if-the-selector-is-not-matching-anymore/31833533#31833533. For your case, you should basically forget about the `:hover` selector. Use JS to trigger the animation on `mouseover` and then allow it to run till the end irrespective of whether the mouse is over the element or not. – Harry Mar 01 '17 at 16:03
  • Ok, I've found the problem. (a) Your CodePen CSS doesn't use the `.wave-active` class, it uses `:hover` and (b) An `infinite` animation has no `animationend`. – Harry Mar 01 '17 at 16:20
  • in different browser with diff css attribute for animation.e.g: IE @keyframes , firefox @-moz-keyframes.you must provide all for the browsers – holi-java Mar 01 '17 at 16:21
  • Harry, thank you. The fact that infinite doesn't have animationend solved the problem! – Alex Mar 01 '17 at 16:25
  • @Alex: Did that answer based on `animationiteration` not help you? Is that not close to what you were looking for? – Harry Mar 02 '17 at 03:01

2 Answers2

2

Here is a solution to your problem using the native animationiteration event that is described in the W3C Spec for animations. This event is fired after every single iteration of the animation. So, what we are doing is that on hover out, we are attaching the animationiteration event listener (which will get fired only once due to the one). Within this event's listener, I've simply placed the contents of original waveOut function. So, everytime you hover the mouse out of the element, the animation will complete one single iteration (after the hover out has happened) and then stop with that. I think this is a lot more graceful than an abrupt end.

class Main {
  constructor() {}
  jsInit() {
    $('.info__block').hover(function() {
      $('.info__block').off('animationiteration'); /* switch off the event handler when you quickly hover back in again */
      $('.info__block').addClass('wave-active');
    }, function() {
      $('.info__block').one('animationiteration', function() {
        $('.info__block').removeClass('wave-active');
      })
    });
  }
}

new Main().jsInit();
body {
  padding: 200px 200px;
}

.info__block {
  width: 100px;
  height: 100px;
  background: aqua;
  border-radius: 50px;
  position: relative;
  display: flex;
  justify-content: center;
}

.info__block:before {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50px;
  border-top: 2px solid aqua;
}

.info__block.wave-active:before {
  animation: link-line 2.5s infinite .5s linear;
}

@keyframes link-line {
  0% {
    transform: translateY(0);
    opacity: 1;
  }
  60% {
    opacity: 0;
  }
  100% {
    transform: translateY(-50%) scale(1.6);
    opacity: 0;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="info__block info__block-1">
</div>

(Note: In the above demo sometimes the animation stops after just one iteration during the second and subsequent hover operations. This seems to be some glitch with the Run Snippet window. I don't see this problem happening in the Editor's output window or in this CodePen demo. If you also encounter the same problem let me know and I'll see if there is any fix for it.)

Note: The problem mentioned above has been fixed and the snippet is also updated with the revised code. Revised CodePen Demo.

Harry
  • 87,580
  • 25
  • 202
  • 214
0

An infinite animation doesn't have animationend event.

Alex
  • 73
  • 1
  • 1
  • 7