"use client";
import { useState } from "react";
interface GlitchTextProps {
text: string;
className?: string;
}
export function GlitchText({ text, className = "" }: GlitchTextProps) {
const [isAnimating, setIsAnimating] = useState(false);
return (
<>
<style>{`
@keyframes glitch-clip-1 {
0% { clip-path: inset(20% 0 60% 0); transform: translate(-4px, 0); }
20% { clip-path: inset(70% 0 10% 0); transform: translate(4px, 0); }
40% { clip-path: inset(40% 0 40% 0); transform: translate(-2px, 0); }
60% { clip-path: inset(10% 0 80% 0); transform: translate(3px, 0); }
80% { clip-path: inset(50% 0 30% 0); transform: translate(-4px, 0); }
100% { clip-path: inset(20% 0 60% 0); transform: translate(-4px, 0); }
}
@keyframes glitch-clip-2 {
0% { clip-path: inset(60% 0 20% 0); transform: translate(4px, 0); }
20% { clip-path: inset(10% 0 70% 0); transform: translate(-4px, 0); }
40% { clip-path: inset(80% 0 10% 0); transform: translate(2px, 0); }
60% { clip-path: inset(30% 0 50% 0); transform: translate(-3px, 0); }
80% { clip-path: inset(20% 0 60% 0); transform: translate(4px, 0); }
100% { clip-path: inset(60% 0 20% 0); transform: translate(4px, 0); }
}
.glitch-layer-1 {
animation: glitch-clip-1 0.4s steps(1) infinite;
color: #6366f1;
opacity: 0.8;
}
.glitch-layer-2 {
animation: glitch-clip-2 0.4s steps(1) infinite;
color: #ec4899;
opacity: 0.8;
}
`}</style>
<span
className={`relative inline-block cursor-default select-none ${className}`}
onMouseEnter={() => setIsAnimating(true)}
onMouseLeave={() => setIsAnimating(false)}
>
{/* Base text */}
<span className="relative z-10">{text}</span>
{/* Glitch Layer 1 (Indigo) */}
<span
aria-hidden="true"
className={`absolute inset-0 ${isAnimating ? "glitch-layer-1" : "hidden"}`}
>
{text}
</span>
{/* Glitch Layer 2 (Pink) */}
<span
aria-hidden="true"
className={`absolute inset-0 ${isAnimating ? "glitch-layer-2" : "hidden"}`}
>
{text}
</span>
</span>
</>
);
}