简体   繁体   中英

print text with typewriter effect, clear after each sentence on loop

I am trying to achieve a typewriter effect with my text where each sentence (h1 tags) gets printed then the text is cleared and the second sentence gets printed. Once the second or third sentence is done printing it should clear and start printing the first sentence again on loop.

I am unable to clear the first sentence, all text just gets stacked, also the word 'the' is not appearing.

Any ideas how to proceed? I would like to keep the text in the HTML so I can re-use the script on different pages.

JSFiddle link: https://jsfiddle.net/b33uhLL2/

HTML:

<div id="typewriter">
  <h1>This<br> is<br> the<br>first<br><span class="highlight">sentence</span></h1>
  <h1>This<br> is<br> the<br>second<br>sentence</h1>
</div>

JS:

function setupTypewriter(t) {
  var HTML = t.innerHTML;

  t.innerHTML = "";

  var cursorPosition = 0,
    tag = "",
    writingTag = false,
    tagOpen = false,
    typeSpeed = 200,
    tempTypeSpeed = 0;

  var type = function() {

    if (writingTag === true) {
      tag += HTML[cursorPosition];
    }

    if (HTML[cursorPosition] === "<") {
      tempTypeSpeed = 0;
      if (tagOpen) {
        tagOpen = false;
        writingTag = true;
      } else {
        tag = "";
        tagOpen = true;
        writingTag = true;
        tag += HTML[cursorPosition];
      }
    }
    if (!writingTag && tagOpen) {
      tag.innerHTML += HTML[cursorPosition];
    }
    if (!writingTag && !tagOpen) {
      if (HTML[cursorPosition] === " ") {
        tempTypeSpeed = 0;
      } else {
        tempTypeSpeed = (Math.random() * typeSpeed) + 50;
      }
      t.innerHTML += HTML[cursorPosition];
    }
    if (writingTag === true && HTML[cursorPosition] === ">") {
      tempTypeSpeed = (Math.random() * typeSpeed) + 50;
      writingTag = false;
      if (tagOpen) {
        var newSpan = document.createElement("span");
        t.appendChild(newSpan);
        newSpan.innerHTML = tag;
        tag = newSpan.firstChild;
      }
    }

    cursorPosition += 1;
    if (cursorPosition < HTML.length - 1) {
      setTimeout(type, tempTypeSpeed);
    }

  };

  return {
    type: type
  };
}


var typer = document.getElementById('typewriter');
typewriter = setupTypewriter(typewriter);
typewriter.type();

CSS:

h1 {
  font-family: helvetica;
  font-size: 20px;
}

You may have some luck with GreenSock .

You could use .from inside a timeline. Here's a starting point using two headers.

 const container = document.querySelector('div') const h1 = document.querySelector('h1') const h2 = document.querySelector('h2') const typewriterTimeline = new TimelineMax({ onStart: () => container.classList.remove('hidden') }) typewriterTimeline .add(TweenMax.from(h1, 3, {text: '', delimiter: ' '})) .add(TweenMax.from(h2, 3, {text: '', delimiter: ' '})) 
 .hidden { display: none; } 
 <div class='hidden'> <h1>This is the title</h1> <h2>This is the subtitle</h2> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/plugins/TextPlugin.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script> 

To make this more dynamic, you could loop over your content and generate a timeline.

Hope that helps you out!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM