JSFiddle - React, Tailwind, and code Playground

by xxxvvvxxx

HTML

<div class="w">
	<div class="a reveal-text">I'm here.</div>
	<div class="a">I'm here.</div>
	<div class="a">I'm here.</div>
</div>

CSS

* {
	padding:0; margin:0;
}
:root {
	--delay: 0;
	--duration: 800ms;
	--iterations: 1;
}
/* •·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•·•· */


.reveal-text,
.reveal-text::after {
	animation-delay: var(--animation-delay, 2s);
	animation-iteration-count: var(--iterations, 1);
	animation-duration: var(--duration, 800ms);
	animation-fill-mode: both;
	animation-timing-function: cubic-bezier(0.0, 0.0, 0.2, 1);
}

.reveal-text {
	--animation-delay: var(--delay, 0);
	--animation-duration: var(--duration, 800ms);
	--animation-iterations: var(--iterations, 1);
	position: relative;
	font-size: 10vw;
	animation-name: clip-text;
	color: #FFF;
	white-space: nowrap;
	cursor: default;
	
	&::after {
		content: "";
		position: absolute;
		z-index: 999;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background-color: #f2f98b;
		transform: scaleX(0);
		transform-origin: 0 50%;
		pointer-events: none;
		animation-name: text-revealer;
	}
	
}

@keyframes clip-text {
	from {
		clip-path: inset(0 100% 0 0);
	}
	to {
		clip-path: inset(0 0 0 0);
	}
}

@keyframes text-revealer {
	
	0%, 50% {
		transform-origin: 0 50%;
	}
	
	60%, 100% {
		transform-origin: 100% 50%;		
	}

	
	60% {
		transform: scaleX(1);
	}
	
	100% {
		transform: scaleX(0);
	}
}
.w {
	display:flex;
	flex-direction: column;
}
.a {
	height:100vh;
	width:100%;
	background:#333;
	color:#fff;
	box-sizing: border-box;
	align-items: center;
	text-align: center;
	font-size: 10vw;
}

JavaScript

const scrollElements = document.querySelectorAll(".a");

var throttleTimer;

const throttle = (callback, time) => {
  if (throttleTimer) return;

  throttleTimer = true;
  setTimeout(() => {
    callback();
    throttleTimer = false;
  }, time);
}

const elementInView = (el, dividend = 1) => {
  const elementTop = el.getBoundingClientRect().top;
  
  return (
    elementTop < (window.innerHeight || document.documentElement.clientHeight) / dividend
  );
};

const elementOutofView = (el) => {
  const elementTop = el.getBoundingClientRect().top;

  return (
    elementTop >= (window.innerHeight || document.documentElement.clientHeight)
  );
};

const displayScrollElement = (element) => {
  element.classList.add("reveal-text");
};

const hideScrollElement = (element) => {
  element.classList.remove("reveal-text");
};

const handleScrollAnimation = () => {
  scrollElements.forEach((el) => {
    if (elementInView(el, 1.25)) {
      displayScrollElement(el);
    } else if (elementOutofView(el)) {
      hideScrollElement(el)
    }
  })
}

window.addEventListener("scroll", () => { 
  throttle(() => {
    handleScrollAnimation();
  }, 250);
});