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);
});