Text Reveal
A text with a moving blob that reveals the text as it passes.
Light shines brightest in shadow
1. Copy the component file
Create a new file called text-reveal-animation.jsx in
your reusable components folder (for example
/src/components/) and paste the following code
into it.
text-reveal-animation.jsx
import { memo, useCallback, useEffect, useRef } from "react";
import styles from "./text-reveal-animation.module.css";
const TextRevealAnimation = (props) => {
const {
text
} = props;
const textRef = useRef(null);
const updateTextSize = useCallback(() => {
const width = Math.round(textRef.current.getBoundingClientRect().width);
textRef.current.style.setProperty("--animation-name", styles["reveal-text-keyframes"]);
textRef.current.style.setProperty("--width", `${width}px`);
}, []);
useEffect(() => {
const resizeOberver = new ResizeObserver(updateTextSize);
resizeOberver.observe(textRef.current);
updateTextSize();
return () => {
resizeOberver.disconnect();
}
}, [updateTextSize]);
return (
<span
className={styles["reveal-text"]}
ref={textRef}
>
<span>
{text}
</span>
</span>
);
};
export default memo(TextRevealAnimation); 2. Copy the CSS module file
In the same folder, create a file called text-reveal-animation.module.css and paste the following CSS.
text-reveal-animation.module.css
.reveal-text {
--background: transparent;
--text-color: white; /* should be set same as background */
--blob-color: #0b0b0c;
--blob-shadow-color: #222;
--animation-name: none;
--animation-duration: 4s;
--width: 0px; /* dynamically set by js */
@media (prefers-color-scheme: dark) {
--text-color: #0b0b0c;
--blob-color: white;
--blob-shadow-color: #ddd;
}
position: relative;
display: inline-block;
background: var(--background);
font: inherit;
white-space: nowrap;
word-break: keep-all;
text-transform: inherit;
>span {
padding: 0 2px;
color: var(--text-color);
mix-blend-mode: lighten;
@media (prefers-color-scheme: dark) {
mix-blend-mode: darken;
}
}
/* blob */
&:before {
content: "";
position: absolute;
top: 50%;
left: 0px;
transform: translate(0px, -50%);
height: 100%;
aspect-ratio: 1;
background: var(--blob-color);
border-radius: 50%;
box-shadow: inset 0px 0px 32px 8px var(--blob-shadow-color);
animation: var(--animation-name) var(--animation-duration) ease-in-out infinite;
}
}
@keyframes reveal-text-keyframes {
0%,
100% {
transform: translate(0px, -50%);
}
50% {
transform: translate(calc(var(--width) - 100%), -50%);
}
} 3. Use the component
Now you can import and use the component anywhere in your project.
text-reveal-animation-preview.jsx
import TextRevealAnimation from "@/components/text-effects/text-reveal-animation/text-reveal-animation";
/* keep text on center */
const wrapperStyles = {
textAlign: "center",
padding: "24px",
textWrap: "balance",
};
const TextRevealAnimationPreview = () => {
return (
<div style={wrapperStyles}>
<h2>
Light shines brightest in {" "}
<TextRevealAnimation
text="shadow"
/>
</h2>
</div>
);
};
export default TextRevealAnimationPreview; Props
Configure the component with the following props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| text | string | Yes | — | The text content to be revealed with the animation effect. |