JSFiddle - React, Tailwind, and code Playground

by Dogbert

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenLite.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/plugins/CSSPlugin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/easing/EasePack.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TimelineMax.min.js"></script>
<div id="message">
  <div class="container">
    <div class="top">
      <div class="text">
        <span class="actual"></span>
        <span class="overlay"></span>
      </div>
    </div>
    <div class="middle">- websites -</div>
    <div class="bottom">
      <div class="text">
        <span class="actual"></span>
        <span class="overlay"></span>
      </div>
    </div>
  </div>
</div>

SCSS

body {
  font-family: Open Sans, Verdana;
  margin: 0;
  background: white;
}

#message {
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100vh;
  .top,
  .middle,
  .bottom {
    margin: 20px 0;
  }
  .top,
  .bottom {
    font-size: 2em;
    text-transform: uppercase;
  }
  .middle {
    color: #999;
  }
  .text {
    position: relative;
    display: inline-block;
  }
  .second-half .text .actual {
    color: transparent;
  }
  .overlay {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 0;
    background: rgba(255, 0, 0, 1);
  }
  .top .overlay,
  .bottom.second-half .overlay {
    left: 0;
    right: auto;
  }
  .top.second-half .overlay,
  .bottom .overlay {
    left: auto;
    right: 0;
  }
}

JavaScript

function go(el, pairs) {
  var tl = new TimelineLite({
    onComplete: function() {
      tl.restart();
    }
  });

  tl.pause();

  var top = el.find(".top"),
    bottom = el.find(".bottom");

  pairs.forEach(function(pair, i) {
    var pi = "pair" + i;
    tl.call(function() {
      top.removeClass("second-half");
      bottom.removeClass("second-half");
      top.find(".actual").text(pair[0]);
      bottom.find(".actual").text(pair[1]);
    });

    tl.add(pi, "+=3");

    [top, bottom].forEach(function(el, j) {
      var overlay = el.find(".overlay");

      tl.to(overlay, .5, {
        width: "100%",
        ease: Power3.easeOut
      }, pi);

      tl.call(function() {
        el.addClass("second-half");
      }, pi + "+=0.5");
      
      tl.to(overlay, .5, {
        width: 0,
        ease: Power3.easeIn
      }, pi + "+=0.56666");
    });
  });

  tl.to(document.body, 0, {}, "+=2");
  // tl.timeScale(0.2);
  tl.play();
}

go($("#message"), [
  ["Simple", "Minimal"],
  ["Beautiful", "Effective"],
  ["Elegant", "Functional"]
]);