Wait for CSS Transition

How do I wait for this animation to finish before moving on to the next one?

To elaborate on entio's answer, your animation occurs when an element has the class "typing-effect." When that animation ends, the browser calls an event called "animationend." You can use JavaScript to run your animation on the next element by accessing that event.

Notice in HTML the snippit below, I've moved the "display: hidden" to a CSS class and removed the "typing-effect." In my JavaScript function, I enable the class in the first element, increment the counter, and told the "animationend" to call the function again with the new value for "i."

Edit: I forgot to mention, I modified the id values. I don't believe a valid id value in HTML5 can contain parenthesis.

console.log("script.js connected");

let iLevel = 1;
let loop = 0;

function animateNext(i){
let stop = document.querySelectorAll('.animated').length;
let animated = document.querySelector(`#h2_${i}`);
animated.classList.add('typing-effect');

animated.addEventListener('animationend', () => {
if(i===stop){
iLevel = "iDone";
}else{
animateNext(i+1);
}
});
}

function startGame() {
animateNext(1);
}
.animated{
display: none;
}
.typing-effect {
display: block;
animation: typing-effect 5s steps(130, end), 0.75s step-end infinite;
white-space: nowrap;
overflow: hidden;
border-right: 2px solid black;
}
.typing-effect:after {
content: " ";
}
@keyframes typing-effect {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
@keyframes blink-caret {
from,
to {
border-color: transparent;
}
50% {
border-color: black;
}
}
<button onclick="startGame();">START GAME</button>

<div id="instructions">

<div>
<h2 id="h2_1" class="animated">Welcome to The Number Wizrd</h2>
</div>

<div>
<h2 id="h2_2" class="animated">Adjfosdf</h2>
</div>
<div>
<h2 id="h2_3" class="animated">sosidjfs</h2>
</div>
<div>
<h2 id="h2_4" class="animated">difjspodf</h2>
</div>
<div>
<h2 id="h2_5" class="animated">skidjfosidf</h2>
</div>

</div>

Wait for CSS Animation to Complete

Solved Demo

Second Demo with fast paced movement

Fiddle with .on() method instead of .bind()

Example given in your question with simple modifications according to my way

[Tested on chrome Version 50.0.2661.87 m (64-bit),
opera 36.0.2130.65,Firefox 45.0.2 IE version 11.0.9600.17843 ]

I have kept it simple to make things easily noticeable I used simple bounce animation with 3 seconds delay and the issue that was happening with your logic was the with each new hover you were starting new animation (Each time position is calculated and switch statement adds the class). I just put an end to it so after each transition effect is completed only new transition will begin so the issue which you were talking about regarding the right left motion followed by sudden top causing both transition happening without one completing other never happens

  1. Added a finished class to div by default
  2. Then what I did was to check it inside switch if that class was there
  3. Then remove it once entered if case
  4. Next Add css class like you do
  5. Next inside bind method remove animation class
  6. Finally add finished class

$(".box").on("webkitAnimationEnd oAnimationEnd msAnimationEnd animationend", function(e) {

$(this).removeClass("animated animatedL animatedR animatedT");
$(this).addClass("finished");
})

$(".box").hover(function(e) {
var $class = $(this).hasClass("finished");
//$(this).addClass("animated");
/* */
var w = $(this).width();
var h = $(this).height();
var x = (e.pageX - this.offsetLeft - (w / 2)) * (w > h ? (h / w) : 1);
var y = (e.pageY - this.offsetTop - (h / 2)) * (h > w ? (w / h) : 1);
var direction = Math.round(Math.atan2(y, x) / 1.57079633 + 5) % 4;

switch (direction) {
case 0: // Top
if ($class) {
$(this).removeClass("finished");
$(this).addClass('animatedT');
}
break;

case 1: // Right
if ($class) {
$(this).removeClass("finished");
$(this).addClass('animatedR');
}
break;

case 2: // Bottom
if ($class) {
$(this).removeClass("finished");
$(this).addClass('animated');
}
break;

case 3: // Left
if ($class) {
$(this).removeClass("finished");
$(this).addClass('animatedL');
}

}
})
@-webkit-keyframes bounce {
0% {
top: 0;
animation-timing-function: ease-out;
}
17% {
top: 15px;
animation-timing-function: ease-in;
}
34% {
top: 0;
animation-timing-function: ease-out;
}
51% {
top: 8px;
animation-timing-function: ease-in;
}
68% {
top: 0px;
animation-timing-function: ease-out;
}
85% {
top: 3px;
animation-timing-function: ease-in;
}
100% {
top: 0;
}
}
@-moz-keyframes bounce {
0% {
top: 0;
animation-timing-function: ease-out;
}
17% {
top: 15px;
animation-timing-function: ease-in;
}
34% {
top: 0;
animation-timing-function: ease-out;
}
51% {
top: 8px;
animation-timing-function: ease-in;
}
68% {
top: 0px;
animation-timing-function: ease-out;
}
85% {
top: 3px;
animation-timing-function: ease-in;
}
100% {
top: 0;
}
}
@keyframes bounce {
0% {
top: 0;
animation-timing-function: ease-out;
}
17% {
top: 15px;
animation-timing-function: ease-in;
}
34% {
top: 0;
animation-timing-function: ease-out;
}
51% {
top: 8px;
animation-timing-function: ease-in;
}
68% {
top: 0px;
}
85% {
top: 3px;
animation-timing-function: ease-in;
}
100% {
top: 0;
}
}
@-webkit-keyframes bounceL {
0% {
left: 0;
animation-timing-function: ease-out;
}
17% {
left: 15px;
animation-timing-function: ease-in;
}
34% {
left: 0;
animation-timing-function: ease-out;
}
51% {
left: 8px;
animation-timing-function: ease-in;
}
68% {
left: 0px;
animation-timing-function: ease-out;
}
85% {
left: 3px;
animation-timing-function: ease-in;
}
100% {
left: 0;
}
}
@-moz-keyframes bounceL {
0% {
left: 0;
animation-timing-function: ease-out;
}
17% {
left: 15px;
animation-timing-function: ease-in;
}
34% {
left: 0;
animation-timing-function: ease-out;
}
51% {
left: 8px;
animation-timing-function: ease-in;
}
68% {
left: 0px;
animation-timing-function: ease-out;
}
85% {
left: 3px;
animation-timing-function: ease-in;
}
100% {
left: 0;
}
}
@keyframes bounceL {
0% {
left: 0;
animation-timing-function: ease-out;
}
17% {
left: 15px;
animation-timing-function: ease-in;
}
34% {
left: 0;
animation-timing-function: ease-out;
}
51% {
left: 8px;
animation-timing-function: ease-in;
}
68% {
left: 0px;
}
85% {
left: 3px;
animation-timing-function: ease-in;
}
100% {
left: 0;
}
}
@-webkit-keyframes bounceR {
0% {
right: 0;
animation-timing-function: ease-out;
}
17% {
right: 15px;
animation-timing-function: ease-in;
}
34% {
right: 0;
animation-timing-function: ease-out;
}
51% {
right: 8px;
animation-timing-function: ease-in;
}
68% {
right: 0px;
animation-timing-function: ease-out;
}
85% {
right: 3px;
animation-timing-function: ease-in;
}
100% {
right: 0;
}
}
@-moz-keyframes bounceR {
0% {
right: 0;
animation-timing-function: ease-out;
}
17% {
right: 15px;
animation-timing-function: ease-in;
}
34% {
right: 0;
animation-timing-function: ease-out;
}
51% {
right: 8px;
animation-timing-function: ease-in;
}
68% {
right: 0px;
animation-timing-function: ease-out;
}
85% {
right: 3px;
animation-timing-function: ease-in;
}
100% {
right: 0;
}
}
@keyframes bounceR {
0% {
right: 0;
animation-timing-function: ease-out;
}
17% {
right: 15px;
animation-timing-function: ease-in;
}
34% {
right: 0;
animation-timing-function: ease-out;
}
51% {
right: 8px;
animation-timing-function: ease-in;
}
68% {
right: 0px;
}
85% {
right: 3px;
animation-timing-function: ease-in;
}
100% {
right: 0;
}
}
@-webkit-keyframes bounceT {
0% {
top: 0;
animation-timing-function: ease-out;
}
17% {
top: 15px;
animation-timing-function: ease-in;
}
34% {
top: 0;
animation-timing-function: ease-out;
}
51% {
top: 8px;
animation-timing-function: ease-in;
}
68% {
top: 0px;
animation-timing-function: ease-out;
}
85% {
top: 3px;
animation-timing-function: ease-in;
}
100% {
top: 0;
}
}
@-moz-keyframes bounceT {
0% {
top: 0;
animation-timing-function: ease-out;
}
17% {
top: 15px;
animation-timing-function: ease-in;
}
34% {
top: 0;
animation-timing-function: ease-out;
}
51% {
top: 8px;
animation-timing-function: ease-in;
}
68% {
top: 0px;
animation-timing-function: ease-out;
}
85% {
top: 3px;
animation-timing-function: ease-in;
}
100% {
top: 0;
}
}
@keyframes bounceT {
0% {
top: 0;
animation-timing-function: ease-out;
}
17% {
top: 15px;
animation-timing-function: ease-in;
}
34% {
top: 0;
animation-timing-function: ease-out;
}
51% {
top: 8px;
animation-timing-function: ease-in;
}
68% {
top: 0px;
}
85% {
top: 3px;
animation-timing-function: ease-in;
}
100% {
top: 0;
}
}
#container {
position: relative;
}
.box {
position: relative;
float: left;
background: #f00;
width: 50px;
height: 50px;
margin-right: 5px;
margin: 50px;
}
.box.animated {
-moz-animation: bounce .5s;
-webkit-animation: bounce .5s;
animation: bounce .5s;
}
.box.animatedL {
-moz-animation: bounceL .5s;
-webkit-animation: bounceL .5s;
animation: bounceL .5s;
}
.box.animatedR {
-moz-animation: bounceR .5s;
-webkit-animation: bounceR .5s;
animation: bounceR .5s;
}
.box.animatedT {
-moz-animation: bounceT .5s;
-webkit-animation: bounceT .5s;
animation: bounceT .5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="container">
<div class="box finished"></div>
<div class="box finished"></div>
<div class="box finished"></div>
<div class="box finished"></div>
</div>

How to use jQuery to wait for the end of CSS3 transitions?

For transitions you can use the following to detect the end of a transition via jQuery:

$("#someSelector").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });

Mozilla has an excellent reference:

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#Detecting_the_start_and_completion_of_a_transition

For animations it's very similar:

$("#someSelector").bind("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function(){ ... });

Note that you can pass all of the browser prefixed event strings into the bind() method simultaneously to support the event firing on all browsers that support it.

Update:

Per the comment left by Duck: you use jQuery's .one() method to ensure the handler only fires once. For example:

$("#someSelector").one("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });

$("#someSelector").one("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function(){ ... });

Update 2:

jQuery bind() method has been deprecated, and on() method is preferred as of jQuery 1.7. bind()

You can also use off() method on the callback function to ensure it will be fired only once. Here is an example which is equivalent to using one() method:

$("#someSelector")
.on("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
function(e){
// do something here
$(this).off(e);
});

References:

  • .off()

  • .one()

Waiting for DOM manipulation to finish before triggering CSS transition?

Take a look at : https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/transitionend_event

The transitionend event is fired when a CSS transition has completed. In the case where a transition is removed before completion, such as if the transition-property is removed or display is set to none, then the event will not be generated.

possible code update

function dostuff() {

let el = document.getElementById("widget");

// before state (beginning of transition)
// big box in lower right corner
el.style.top = "100px"
el.style.left = "100px"
el.style.width = "200px"
el.style.height = "200px"

el.addEventListener('transitionend', () => {
el.style.top = "0px"
el.style.left = "0px"
el.style.width = "10px"
el.style.height = "10px"
});
}
#widget {
position: absolute;
left: 0px;
top: 0px;
height: 0px;
width: 0px;
border: 3px solid red;
transition: all 0.2s;
}
<button type="button" onClick="dostuff()">Click Me!</button>

<div id="widget">
</div>

css transform wait until transition is completed

As noted here, you could achieve it using the following jQuery function:

$("#someSelector").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });

This, in this provided case, will wait for the '#someSelector' CSS animation to finish and then execute whatever piece of code you wish.

This is a possible duplicate to this and this.



Related Topics



Leave a reply



Submit