返回动效库
文字高级

故障文字

文字以数字故障风格闪烁和偏移,带有赛博朋克美学的视觉冲击力。

持续播放3s

交互预览

动效定义与代码

{
  "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}"
    }
  ]
}