Text Wave
An interactive collection of stacked headings that reveal individual content sections with a click.
An interactive collection of stacked headings that reveal individual content sections with a click.
Follow these simple steps to add the Text Wave component to your project:
Install Dependencies
pnpm add motion
Create a new file: components/motions/text-wave.tsx
and copy the code below:
"use client";
import { type JSX } from "react";
import { motion, Transition } from "motion/react";
import { cn } from "@/lib/utils";
export type TextShimmerWaveProps = {
children: string;
as?: React.ElementType;
className?: string;
duration?: number;
zDistance?: number;
xDistance?: number;
yDistance?: number;
spread?: number;
scaleDistance?: number;
rotateYDistance?: number;
transition?: Transition;
};
export function TextShimmerWave({
children,
as: Component = "p",
className,
duration = 1,
zDistance = 10,
xDistance = 2,
yDistance = -2,
spread = 1,
scaleDistance = 1.1,
rotateYDistance = 10,
transition,
}: TextShimmerWaveProps) {
const MotionComponent = motion.create(
Component as keyof JSX.IntrinsicElements,
);
return (
<MotionComponent
className={cn(
"relative inline-block [perspective:500px]",
"[--base-color:#a1a1aa] [--base-gradient-color:#000]",
"dark:[--base-color:#71717a] dark:[--base-gradient-color:#ffffff]",
className,
)}
style={{ color: "var(--base-color)" }}
>
{children.split("").map((char, i) => {
const delay = (i * duration * (1 / spread)) / children.length;
return (
<motion.span
key={i}
className={cn(
"inline-block whitespace-pre [transform-style:preserve-3d]",
)}
initial={{
translateZ: 0,
scale: 1,
rotateY: 0,
color: "var(--base-color)",
}}
animate={{
translateZ: [0, zDistance, 0],
translateX: [0, xDistance, 0],
translateY: [0, yDistance, 0],
scale: [1, scaleDistance, 1],
rotateY: [0, rotateYDistance, 0],
color: [
"var(--base-color)",
"var(--base-gradient-color)",
"var(--base-color)",
],
}}
transition={{
duration: duration,
repeat: Infinity,
repeatDelay: (children.length * 0.05) / spread,
delay,
ease: "easeInOut",
...transition,
}}
>
{char}
</motion.span>
);
})}
</MotionComponent>
);
}
Adjust the import paths in both files according to your project's structure.
Generating code...