JSFiddle - React, Tailwind, and code Playground

by Dogbert

HTML

<div id="message">
  <div class="container">
    <div class="top">
      <div class="text rtl">
        <span></span>
      </div>
    </div>
    <div class="middle">- websites -</div>
    <div class="bottom">
      <div class="text">
        <span></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 {
    display: inline-block;
    span {
      padding: 0 6px;
      position: relative;
      &::before {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        width: 0;
        left: 0;
        background: rgba(255, 0, 0, 1);
        transition: .6s width cubic-bezier(.82, 0, .21, 1);
      }
    }
    &.masked span::before {
      width: 100%;
    }
    &.rtl span::before {
    left: auto;
      right: 0;
    }
    &.transparent {
      color: transparent;
    }
  }
}

JavaScript

function run($el, instructions) {
  var $top = $el.find(".top"),
    $bottom = $el.find(".bottom"),
    $topText = $top.find(".text"),
    $bottomText = $bottom.find(".text"),
    $texts = $topText.add($bottomText);

  tick(0);

  function tick(i) {
    var instruction = instructions[i % instructions.length];
    if (typeof instruction === 'number') {
      instruction = ["sleep", instruction];
    }
    switch (instruction[0]) {
      case "sleep":
        setTimeout(function() {
          tick(i + 1);
        }, instruction[1]);
        return;
      case "set":
        $topText.find("span").text(instruction[1]);
        $bottomText.find("span").text(instruction[2]);
        break;
      case "hide":
        $texts.addClass("transparent");
        break;
      case "show":
        $texts.removeClass("transparent");
        break;
      case "mask":
        $topText.addClass("masked");
        setTimeout(function() {
          $bottomText.addClass("masked");
          tick(i + 1);
        }, instruction[1] || 0);
        return;
      case "unmask":
        $texts.toggleClass("rtl");
        $topText.removeClass("masked");
        setTimeout(function() {
          $bottomText.removeClass("masked");
          tick(i + 1);
        }, instruction[1] || 0);
        return;
      case "stop":
        return;
    }
    tick(i + 1);
  }
}

var scale = 1;
var sleepOnText = 2000;

function slide(a, b) {
  var mask = ["mask", 66 / scale];
  var unmask = ["unmask", 66 / scale];
  var hide = ["hide"];
  var show = ["show"];
  var set = ["set", a, b];

  return [
    mask, sleep(800),
    hide, sleep(100),
    unmask, sleep(600),
    set, sleep(0),
    mask, sleep(800),
    show, sleep(100),
    unmask, sleep(sleepOnText),
  ];

  function sleep(t) {
    return ["sleep", t / scale];
  }
}

run($("#message"), [
  ["set", "Simple", "Minimal"],
  ["stop"]
]);

setTimeout(function() {
  run($("#message"), [].concat(
    slide("Beautiful", "Effective"),
    slide("Elegant",...