Glitch Text
Glitch Text is a React and Tailwind CSS text component from Kokonut UI, licensed MIT. Copy it and paste it into your project.
Kokonut UI
MIT
text
What it is
Glitch Text is a React and Tailwind CSS text component from Kokonut UI, licensed MIT. Copy it and paste it into your project.
How to use it
Open it in the catalogue, press copy, and paste it into your project. The prompt you copy carries the code and the rules that tell your agent to reproduce it without changing anything.
Five free copies a month. No card.
Needs
npm i motion
Licence
This component comes from Kokonut UI and is redistributed under the MIT licence, which permits commercial use. The copyright notice travels with the code.
Glitch Text
"use client";
/**
* @author: @dorianbaffier
* @description: Glitch Text
* @version: 1.0.0
* @date: 2025-06-26
* @license: MIT
* @website: https://kokonutui.com
* @github: https://github.com/kokonut-labs/kokonutui
*/
import { motion } from "motion/react";
import { useRef } from "react";
import { cn } from "@/lib/utils";
interface GlitchTextProps {
text: string;
className?: string;
glitchIntensity?: "light" | "medium" | "heavy" | "extreme";
color?:
| "rainbow"
| "blue"
| "purple"
| "cyan"
| "pink"
| "orange"
| "gradient-orange";
backgroundColor?: string;
isStatic?: boolean;
size?: "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | number;
fontWeight?: number;
letterSpacing?: number;
}
const GlitchText = ({
text = "Glitch Text",
className,
glitchIntensity = "medium",
color = "gradient-orange",
backgroundColor,
isStatic = false,
size = "md",
fontWeight = 700,
letterSpacing = 5,
}: GlitchTextProps) => {
const containerRef = useRef<HTMLDivElement>(null);
// Vibrant color schemes
const colorSchemes = {
rainbow: {
primary: "oklch(0.85 0.2 var(--rainbow-hue, 270))",
before: "oklch(0.9 0.15 calc(var(--rainbow-hue, 270) + 60))",
after: "oklch(0.8 0.25 calc(var(--rainbow-hue, 270) - 60))",
},
blue: {
primary: "oklch(0.65 0.2 250)", // Vibrant blue
before: "oklch(0.75 0.15 255)", // Lighter blue
after: "oklch(0.55 0.25 245)", // Deeper blue
},
purple: {
primary: "oklch(0.6 0.22 290)", // Rich purple
before: "oklch(0.7 0.18 295)", // Lighter purple
after: "oklch(0.5 0.25 285)", // Deep purple
},
cyan: {
primary: "oklch(0.8 0.15 200)", // Bright cyan
before: "oklch(0.85 0.12 205)", // Light cyan
after: "oklch(0.7 0.18 195)", // Deep cyan
},
pink: {
primary: "oklch(0.7 0.25 330)", // Vibrant pink
before: "oklch(0.8 0.2 335)", // Light pink
after: "oklch(0.6 0.28 325)", // Deep pink
},
orange: {
primary: "oklch(0.7 0.25 45)", // Vibrant tangerine orange
before: "oklch(0.85 0.2 40)", // Warm light orange
after: "oklch(0.6 0.28 50)", // Deep sunset orange
},
"gradient-orange": {
primary:
"linear-gradient(135deg, oklch(0.7 0.25 45) 0%, oklch(0.75 0.28 30) 50%, oklch(0.65 0.3 60) 100%)",
before:
"linear-gradient(135deg, oklch(0.85 0.2 40) 0%, oklch(0.8 0.22 25) 50%, oklch(0.75 0.25 55) 100%)",
after:
"linear-gradient(135deg, oklch(0.6 0.28 50) 0%, oklch(0.55 0.3 35) 50%, oklch(0.5 0.32 65) 100%)",
},
};
const selectedScheme = colorSchemes[color];
// Glitch intensity settings
const intensitySettings = {
light: {
animationDuration: "2s",
translateRange: 2,
opacityRange: [0.8, 0.9],
skewRange: 0.5,
},
medium: {
animationDuration: "1s",
translateRange: 3,
opacityRange: [0.7, 0.85],
skewRange: 1,
},
heavy: {
animationDuration: "0.5s",
translateRange: 5,
opacityRange: [0.6, 0.8],
skewRange: 2,
},
extreme: {
animationDuration: "0.3s",
translateRange: 8,
opacityRange: [0.5, 0.75],
skewRange: 3,
},
};
const settings = intensitySettings[glitchIntensity];
const sizeMap = {
sm: "text-2xl",
md: "text-4xl",
lg: "text-5xl",
xl: "text-6xl",
"2xl": "text-7xl",
"3xl": "text-8xl",
};
// Animation variants for the glitch effect
const glitchAnimation = {
initial: {
transform: "translate(0)",
opacity: settings.opacityRange[1],
},
animate: {
transform: [
"translate(0)",
`translate(${
settings.translateRange
}px, ${-settings.translateRange}px) skew(${settings.skewRange}deg)`,
`translate(${-settings.translateRange}px, ${
settings.translateRange
}px) skew(${-settings.skewRange}deg)`,
`translate(${-settings.translateRange}px, ${-settings.translateRange}px) skew(${
settings.skewRange
}deg)`,
`translate(${settings.translateRange}px, ${
settings.translateRange
}px) skew(${-settings.skewRange}deg)`,
"translate(0)",
],
opacity: [
settings.opacityRange[1],
settings.opacityRange[0],
settings.opacityRange[1],
settings.opacityRange[0],
settings.opacityRange[1],
],
transition: {
duration: Number(settings.animationDuration.replace("s", "")),
ease: [0.25, 0.46, 0.45, 0.94],
repeat: Number.POSITIVE_INFINITY,
},
},
};
return (
<div
className={cn(
"relative flex items-center justify-center",
"overflow-visible p-8",
className
)}
ref={containerRef}
>
<motion.div
animate={isStatic ? "initial" : "animate"}
className={cn(
"relative font-bold tracking-wider",
typeof size === "string" ? sizeMap[size] : ""
)}
initial="initial"
style={{
fontSize: typeof size === "number" ? `${size}px` : undefined,
fontWeight,
letterSpacing,
color: selectedScheme.primary,
textShadow: `0 0 5px ${selectedScheme.primary}40`,
}}
variants={glitchAnimation as any}
>
{text}
<motion.div
animate={isStatic ? "initial" : "animate"}
className="pointer-events-none absolute inset-0"
initial="initial"
style={{
color: selectedScheme.before,
textShadow: `0 0 7px ${selectedScheme.before}40`,
}}
variants={{
...(glitchAnimation as any),
animate: {
...(glitchAnimation as any).animate,
transform: [
"translate(0)",
`translate(${-settings.translateRange}px, ${
settings.translateRange
}px) skew(${-settings.skewRange}deg)`,
`translate(${
settings.translateRange
}px, ${-settings.translateRange}px) skew(${
settings.skewRange
}deg)`,
`translate(${settings.translateRange}px, ${
settings.translateRange
}px) skew(${-settings.skewRange}deg)`,
`translate(${-settings.translateRange}px, ${-settings.translateRange}px) skew(${
settings.skewRange
}deg)`,
"translate(0)",
],
},
}}
>
{text}
</motion.div>
<motion.div
animate={isStatic ? "initial" : "animate"}
className="pointer-events-none absolute inset-0"
initial="initial"
style={{
color: selectedScheme.after,
textShadow: `0 0 7px ${selectedScheme.after}40`,
}}
variants={{
...(glitchAnimation as any),
animate: {
...(glitchAnimation as any).animate,
transform: [
"translate(0)",
`translate(${
settings.translateRange
}px, ${-settings.translateRange}px) skew(${
settings.skewRange
}deg)`,
`translate(${-settings.translateRange}px, ${
settings.translateRange
}px) skew(${-settings.skewRange}deg)`,
`translate(${-settings.translateRange}px, ${
settings.translateRange
}px) skew(${settings.skewRange}deg)`,
`translate(${
settings.translateRange
}px, ${-settings.translateRange}px) skew(${-settings.skewRange}deg)`,
"translate(0)",
],
},
}}
>
{text}
</motion.div>
</motion.div>
</div>
);
};
export default GlitchText;