Anime.js Moving Letters - Multiple Text Lines

1.5k Views Asked by At

I am working on implementing the following anime.JS effect on my site and having trouble manipulating the javascript to accommodate multiple lines of text. My desired output is that line one animates then fades out, line 2 animates etc.

https://tobiasahlin.com/moving-letters/#11

<script>
// Wrap every letter in a span
var textWrapper = document.querySelector('.ml11 .letters');
textWrapper.innerHTML = textWrapper.textContent.replace(/([^\x00-\x80]|\w)/g, "<span class='letter'>$&</span>");

anime.timeline({loop: true})
  .add({
    targets: '.ml11 .line',
    scaleY: [0,1],
    opacity: [0.5,1],
    easing: "easeOutExpo",
    duration: 700
  })
  .add({
    targets: '.ml11 .line',
    translateX: [0, document.querySelector('.ml11 .letters').getBoundingClientRect().width + 10],
    easing: "easeOutExpo",
    duration: 700,
    delay: 100
  }).add({
    targets: '.ml11 .letter',
    opacity: [0,1],
    easing: "easeOutExpo",
    duration: 600,
    offset: '-=775',
    delay: (el, i) => 34 * (i+1)
  }).add({
    targets: '.ml11',
    opacity: 0,
    duration: 1000,
    easing: "easeOutExpo",
    delay: 1000
  });
</script>

I'd like the output to look something like this where 3 separate lines are displayed one after another - https://codepen.io/dsr/pen/mdJXEdP

How should I manipulate the JS code and what HTML classes I am using to get this effect?

1

There are 1 best solutions below

2
On

you can do it with interval function, here is the example:

https://jsfiddle.net/3ux2jkpq/

<h1 class="ml11">
  <span class="text-wrapper">
    <span class="line line1"></span>
    <span class="letters">Hello</span>
    <span class="letters">Goodbye</span>
  </span>
</h1>

<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<style>
.ml11 {
  font-weight: 700;
  font-size: 3.5em;
}

.ml11 .text-wrapper {
  position: relative;
  display: inline-block;
  padding-top: 0.1em;
  padding-right: 0.05em;
  padding-bottom: 0.15em;
}

.ml11 .line {
  opacity: 0;
  position: absolute;
  left: 0;
  height: 100%;
  width: 3px;
  background-color: #fff;
  transform-origin: 0 50%;
}

.ml11 .line1 { 
  top: 0; 
  left: 0;
}

.ml11 .letter {
  display: inline-block;
  line-height: 1em;
}
</style>
<script>
var i = 0;
 function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
var textWrapper = document.getElementsByClassName('letters');
textWrapper[0].style.display="none";
textWrapper[1].style.display="none";
 setInterval( function() {
 
// Wrap every letter in a span
textWrapper[0].style.display="none";
textWrapper[1].style.display="none";
textWrapper[i].style.display="block";
textWrapper[i].innerHTML = textWrapper[i].textContent.replace(/([^\x00-\x80]|\w)/g, "<span class='letter'>$&</span>");
anime.timeline({loop: true})
  .add({
    targets: '.ml11 .line',
    scaleY: [0,1],
    opacity: [0.5,1],
    easing: "easeOutExpo",
    duration: 700
  })
  .add({
    targets: '.ml11 .line',
    translateX: [0, document.querySelector('.ml11 .letters').getBoundingClientRect().width + 10],
    easing: "easeOutExpo",
    duration: 700,
    delay: 100
  }).add({
    targets: '.ml11 .letter',
    opacity: [0,1],
    easing: "easeOutExpo",
    duration: 600,
    offset: '-=775',
    delay: (el, i) => 34 * (i+1)
  }).add({
    targets: '.ml11',
    opacity: 0,
    duration: 1000,
    easing: "easeOutExpo",
    delay: 1500
  });
  if(i==0){i=1;}
  else{i=0;} 
},1800);
</script>