skip to Main Content

I want to make an animation of type writer so when it reaches the last world it just delete everything and start over. so what can I do to make it simple ?

<body>
    <h1 id="main-text">
      <span id="sp1"></span>
    </h1>

    <script>
      let mainText = document.getElementById("main-text");
      let txt1 = "this is the main text!!!";
      let sp1 = document.getElementById("sp1");
      let cnt = 0;
      let txt1Handle = document.getElementById(txt1);

        let myInterval = setInterval(() => {
          let letter = document.createTextNode(txt1[cnt]);
          sp1.appendChild(letter);
          cnt++;
          console.log(cnt);
          if (cnt >= txt1.length) {
            cnt = 0;
            clearInterval(myInterval);
          }
        }, 200);

    </script>
  </body>

2

Answers


  1. Is this what you were looking for? You could even add a small delay inbetween swapping the texts so users have more of a chance to read it.

    let txts = [];
    txts.push("this is the main text!!!");
    txts.push("this is the second text");
    txts.push("this is the third text");
    
    let sp1 = document.getElementById("sp1");
    let cnt = 0;
    let txtIndex = 0;
    
    
    
    let myInterval = setInterval(() => {
       
      console.log(txts);
    
      sp1.textContent = txts[txtIndex].substring(0, cnt++);
    
      if (cnt > txts[txtIndex].length){
            cnt = 0;
        txtIndex++
            if (txtIndex >= txts.length) 
            txtIndex = 0;
      }
    
    }, 100);
            
    <h1 id="main-text">
      <span id="sp1"></span>
    </h1>
    Login or Signup to reply.
    • First of, create a reusable function that accepts two arguments, the element to target, and an Array of words to be typed in.
    • Don’t use setInterval, use setTimeout that recalls an inner type function. That way you can wait longer once a text is fully typed for a better UX
    • use String.prototype.slice() to get the portion of text (from 0 to the incrementing charIndex) and use Node.textContent to print it as the element’s text
    • use the Modulo (Remainder) operator % to loop the text index back to 0
    const typewriter = (el, texts) => {
      
      const textsTotal = texts.length;
      let textIndex = 0;
      let charIndex = 0;
      
      const text = texts[textIndex]; // Get the text by index
    
      const type = () => {
        
        const text = texts[textIndex];
        const isEnded = charIndex >= text.length;
        const time = isEnded ? 1500 : 260; // Wait longer when text is fully typed
        el.textContent = text.slice(0, charIndex + 1);
    
        charIndex += 1; // increment character index
        
        if (isEnded) {
          charIndex = 0; // Reset char index
          textIndex = ++textIndex % textsTotal; // next text (and loop)
        }
        
        setTimeout(type, time); // Loop!
      };
      
      // Start!
      type();
    };
    
    
    typewriter(
      document.getElementById("sp1"),
      ["Main!!", "Second text", "Third text example"]
    );
    
    typewriter(
      document.getElementById("sp2"),
      ["code", "examples", "quality"]
    );
    <div id="sp1"></div>
    We provide <span id="sp2"></span>

    For completeness, "simple" – but unsure if that’s exactly the desired… here’s the simple:

    const typewriter = (el) => {
      const text = el.dataset.typewriter;
      let i = 0;
      setInterval(() => {
        i = ++i % (text.length + 1);
        el.textContent = text.slice(0, i);
      }, 300);
    };
    
    document.querySelectorAll("[data-typewriter]").forEach(typewriter);
    <span data-typewriter="Main text!!!"></span>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search