Text Effect Configurable
FREE
A configurable text effect for elements
Demo
Animate your ideas with CSS
Exclusive Launch 50% offspots left: 0 / 50


$39.99
$19.99
Payment once and get lifetime access
Access to all animations
All updates
All animations
No subscriptions
Installation
1
Copy and paste the following code into your project.
Add this component text-effect-configurable.tsx to your project.
import type { ReactNode, ElementType } from "react";
import { cn } from "~/lib/utils";
interface TextEffectConfigurableProps {
children: ReactNode;
as?: ElementType;
effect?: "fade" | "blur" | "slide" | "scale" | "rotate";
delay?: number;
duration?: number;
className?: string;
}
// Function to extract text from React children recursively
function extractTextFromChildren(children: ReactNode): string {
if (typeof children === "string") {
return children;
}
if (typeof children === "number") {
return String(children);
}
if (Array.isArray(children)) {
return children.map(extractTextFromChildren).join("");
}
if (children && typeof children === "object" && "props" in children) {
// If it's a React element, try to extract text from its children
return extractTextFromChildren((children as { props: { children: ReactNode } }).props.children);
}
return "";
}
export function TextEffectConfigurable({
children,
as: Component = "div",
effect = "fade",
delay = 0.05,
duration = 0.6,
className = "",
}: TextEffectConfigurableProps) {
// Convert children to string using our extraction function
const text = extractTextFromChildren(children);
const getAnimationClass = () => {
switch (effect) {
case "blur":
return "animate-blur-in";
case "slide":
return "animate-slide-up";
case "scale":
return "animate-scale-in";
case "rotate":
return "animate-rotate-in";
default:
return "animate-fade-in";
}
};
const getInitialClasses = () => {
switch (effect) {
case "blur":
return "blur-sm opacity-0";
case "slide":
return "opacity-0 translate-y-0";
case "scale":
return "opacity-0 scale-none";
case "rotate":
return "opacity-0";
default:
return "opacity-0";
}
};
const animatedContent = text.split("").map((char, index) => (
<span
key={index}
className={cn("inline-block", getInitialClasses(), getAnimationClass())}
style={{
animationDelay: `${index * delay}s`,
animationDuration: `${duration}s`,
animationFillMode: "forwards",
}}
>
{char === " " ? "\u00A0" : char}
</span>
));
const renderElement = () => {
const commonProps = {
className: cn("text-3xl font-bold text-white", className),
};
switch (Component) {
case "h1":
return <h1 {...commonProps}>{animatedContent}</h1>;
case "h2":
return <h2 {...commonProps}>{animatedContent}</h2>;
case "h3":
return <h3 {...commonProps}>{animatedContent}</h3>;
case "h4":
return <h4 {...commonProps}>{animatedContent}</h4>;
case "h5":
return <h5 {...commonProps}>{animatedContent}</h5>;
case "h6":
return <h6 {...commonProps}>{animatedContent}</h6>;
case "p":
return <p {...commonProps}>{animatedContent}</p>;
case "span":
return <span {...commonProps}>{animatedContent}</span>;
case "blockquote":
return <blockquote {...commonProps}>{animatedContent}</blockquote>;
case "strong":
return <strong {...commonProps}>{animatedContent}</strong>;
case "em":
return <em {...commonProps}>{animatedContent}</em>;
default:
return <div {...commonProps}>{animatedContent}</div>;
}
};
return renderElement();
}
2
Add the following keyframes and animations to your project.
@layer utilities {
// START HERE ------------------------------------------------------------
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.animate-fade-in {
animation: fade-in 0.6s ease-out forwards;
}
@keyframes blur-in {
from {
opacity: 0;
filter: blur(12px);
}
to {
opacity: 1;
filter: blur(0px);
}
}
.animate-blur-in {
animation: blur-in 0.8s ease-out forwards;
}
@keyframes slide-in {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-slide-in {
animation: slide-in 0.6s ease-out forwards;
}
@keyframes scale-in {
from {
opacity: 0;
transform: scale(0);
}
to {
opacity: 1;
transform: scale(1);
}
}
.animate-scale-in {
animation: scale-in 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
}
@keyframes rotate-in {
from {
opacity: 0;
transform: rotate(-180deg) scale(0);
}
to {
opacity: 1;
transform: rotate(0deg) scale(1);
}
}
.animate-rotate-in {
animation: rotate-in 0.8s ease-out forwards;
}
// END HERE ------------------------------------------------------------
}
3
Start using the component TextEffectConfigurable in your project.
Usage Example
// Basic character-by-character animation
<TextEffectConfigurable effect="slide" delay={0.1} duration={0.8}>
Animate your ideas with CSS
</TextEffectConfigurable>
// ------------------------------------------------------------
// Fast scale animation
<TextEffectConfigurable
effect="scale"
delay={0.03}
duration={0.4}
as="h1"
className="text-4xl font-bold"
>
Quick Animation
</TextEffectConfigurable>
// ------------------------------------------------------------
// Slow fade with custom styling
<TextEffectConfigurable
effect="fade"
delay={0.15}
duration={1.2}
className="text-blue-400"
>
Elegant and Slow
</TextEffectConfigurable>
Properties
The TextEffectConfigurable
component accepts the following props:
Property | Type | Default | Description |
---|---|---|---|
children | ReactNode | - | The text content to animate |
as | ElementType | "div" | The HTML element to render |
effect | "fade" | "blur" | "slide" | "scale" | "rotate" | "fade" | The type of animation |
delay | number | 0.05 | Delay between each character animation (seconds) |
duration | number | 0.6 | Duration of each character animation (seconds) |
className | string | "" | Additional CSS classes |
Usage Examples
Scale Characters
Blur Effect
Rotate Text
Fade In
Fast Scale