故障文字
文字以数字故障风格闪烁和偏移,带有赛博朋克美学的视觉冲击力。
交互预览
动效定义与代码
{
"slug": "glitch-text",
"name": "故障文字",
"nameEn": "Glitch Text",
"description": "文字以数字故障风格闪烁和偏移,带有赛博朋克美学的视觉冲击力。",
"descriptionEn": "Text flickers and shifts with a digital glitch aesthetic, creating a cyberpunk visual impact.",
"category": "text",
"tags": [
"glitch",
"distortion",
"cyberpunk",
"effect",
"text"
],
"trigger": "continuous",
"difficulty": "advanced",
"duration": "3s",
"easing": "steps(2, end)",
"cssProperties": [
"transform",
"clip-path"
],
"isGPUAccelerated": true,
"previewBg": "dark",
"keywords": [
"glitch",
"distortion",
"cyberpunk",
"retro",
"vhs",
"noise"
],
"useCases": [
"Hero title effect",
"Error/404 page",
"Gaming UI",
"Tech/hacker aesthetic"
],
"relatedAnimations": [
"typewriter",
"text-gradient-flow"
],
"recommendedStyles": [
"cyberpunk",
"dark-mode",
"retro-pixel"
],
"codeSnippets": [
{
"label": "CSS Keyframes",
"language": "css",
"code": "/* 3-layer glitch: original text + 2 pseudo-element copies */\n@keyframes glitch-1 {\n 0% {\n clip-path: inset(40% 0 61% 0);\n transform: translate(-2px, 2px);\n }\n 20% {\n clip-path: inset(92% 0 1% 0);\n transform: translate(1px, -1px);\n }\n 40% {\n clip-path: inset(43% 0 1% 0);\n transform: translate(-1px, 3px);\n }\n 60% {\n clip-path: inset(25% 0 58% 0);\n transform: translate(3px, 1px);\n }\n 80% {\n clip-path: inset(54% 0 7% 0);\n transform: translate(-3px, -2px);\n }\n 100% {\n clip-path: inset(58% 0 43% 0);\n transform: translate(2px, -3px);\n }\n}\n\n@keyframes glitch-2 {\n 0% {\n clip-path: inset(65% 0 13% 0);\n transform: translate(3px, -1px);\n }\n 20% {\n clip-path: inset(15% 0 72% 0);\n transform: translate(-2px, 3px);\n }\n 40% {\n clip-path: inset(80% 0 5% 0);\n transform: translate(1px, -2px);\n }\n 60% {\n clip-path: inset(10% 0 65% 0);\n transform: translate(-3px, 1px);\n }\n 80% {\n clip-path: inset(35% 0 30% 0);\n transform: translate(2px, 2px);\n }\n 100% {\n clip-path: inset(2% 0 90% 0);\n transform: translate(-1px, -1px);\n }\n}\n\n.glitch-text {\n position: relative;\n will-change: transform;\n}\n\n.glitch-text::before,\n.glitch-text::after {\n content: attr(data-text);\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n will-change: transform, clip-path;\n}\n\n.glitch-text::before {\n color: #ff00ff;\n animation: glitch-1 3s steps(2, end) infinite;\n}\n\n.glitch-text::after {\n color: #00ffff;\n animation: glitch-2 3s steps(2, end) infinite reverse;\n}\n\n/* Usage: <h1 class=\"glitch-text\" data-text=\"GLITCH\">GLITCH</h1> */\n\n@media (prefers-reduced-motion: reduce) {\n .glitch-text::before,\n .glitch-text::after {\n animation: none;\n display: none;\n }\n}"
},
{
"label": "Tailwind CSS",
"language": "css",
"code": "/* Add to your global CSS or Tailwind v4 theme */\n@keyframes glitch-1 {\n 0% { clip-path: inset(40% 0 61% 0); transform: translate(-2px, 2px); }\n 20% { clip-path: inset(92% 0 1% 0); transform: translate(1px, -1px); }\n 40% { clip-path: inset(43% 0 1% 0); transform: translate(-1px, 3px); }\n 60% { clip-path: inset(25% 0 58% 0); transform: translate(3px, 1px); }\n 80% { clip-path: inset(54% 0 7% 0); transform: translate(-3px, -2px); }\n 100% { clip-path: inset(58% 0 43% 0); transform: translate(2px, -3px); }\n}\n\n@keyframes glitch-2 {\n 0% { clip-path: inset(65% 0 13% 0); transform: translate(3px, -1px); }\n 20% { clip-path: inset(15% 0 72% 0); transform: translate(-2px, 3px); }\n 40% { clip-path: inset(80% 0 5% 0); transform: translate(1px, -2px); }\n 60% { clip-path: inset(10% 0 65% 0); transform: translate(-3px, 1px); }\n 80% { clip-path: inset(35% 0 30% 0); transform: translate(2px, 2px); }\n 100% { clip-path: inset(2% 0 90% 0); transform: translate(-1px, -1px); }\n}\n\n@utility animate-glitch-text {\n position: relative;\n will-change: transform;\n\n &::before,\n &::after {\n content: attr(data-text);\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n will-change: transform, clip-path;\n }\n\n &::before {\n color: #ff00ff;\n animation: glitch-1 3s steps(2, end) infinite;\n }\n\n &::after {\n color: #00ffff;\n animation: glitch-2 3s steps(2, end) infinite reverse;\n }\n}\n\n/* Usage: <h1 class=\"animate-glitch-text\" data-text=\"GLITCH\">GLITCH</h1> */\n\n@media (prefers-reduced-motion: reduce) {\n .glitch-text::before,\n .glitch-text::after {\n animation: none;\n display: none;\n }\n}"
},
{
"label": "Framer Motion",
"language": "tsx",
"code": "import { motion } from \"framer-motion\";\n\n// Tip: respect user's motion preferences\n// import { useReducedMotion } from \"framer-motion\";\n// const reduced = useReducedMotion();\n// if (reduced) return <h1>{text}</h1>;\n\nfunction GlitchText({ text }: { text: string }) {\n const glitchVariants = {\n animate: {\n x: [0, -2, 1, -1, 3, -3, 2, 0],\n y: [0, 2, -1, 3, 1, -2, -3, 0],\n textShadow: [\n \"0 0 0 transparent\",\n \"-2px 2px 0 #ff00ff, 2px -2px 0 #00ffff\",\n \"1px -1px 0 #ff00ff, -1px 1px 0 #00ffff\",\n \"-3px 1px 0 #ff00ff, 3px -1px 0 #00ffff\",\n \"2px 2px 0 #ff00ff, -2px -2px 0 #00ffff\",\n \"0 0 0 transparent\",\n ],\n },\n };\n\n return (\n <motion.h1\n variants={glitchVariants}\n animate=\"animate\"\n transition={{\n duration: 3,\n ease: \"linear\",\n repeat: Infinity,\n times: [0, 0.15, 0.3, 0.45, 0.6, 0.75, 0.9, 1],\n }}\n >\n {text}\n </motion.h1>\n );\n}"
}
]
}