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

I am creating a game with HTML, CSS, & JavaScript. I have 5 h2(s) and I want to wait for the animation to finish before moving on to any part of the code. The animation works how I want it to but the JavaScript is starting the next animation before the first one is even done! I have tried using

window.setTimeOut

but no luck. Here is the code with the required code: https://codepen.io/HumanFriend/pen/mdOBvoL Can someone help me?

2 answers

  • answered 2021-02-22 22:47 entio

    You can listen to animationend event, fe:

    const animated = document.querySelector('.animated');
    
    animated.addEventListener('animationend', () => {
      console.log('Animation ended');
    });
    

    Read more: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/animationend_event


    Random thing:

    When you use setTimeout(nextI_ifelse(), 5000); you just invoke the nextI_ifelse inline (and you're setting timeout for the value returned from this function). Change it to setTimeout(nextI_ifelse, 5000);

    Any you just want to read about algorithms in general. What you try to do makes sense, but the way you're trying to achieve that does not. The for loop in your codepen runs instantly, so iLevel is directly set to the last value.

  • answered 2021-02-22 23:37 Jeff

    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>