← каталог
Glitch Text
Глитч-надпись: слои-каналы в псевдоэлементах порезаны clip-path и дёргаются step-end всплесками. Дискретные прыжки, между всплесками — чистый текст.
cssautobasic0reduced-motion ✓
🎛 Настройки — крути и копируй
Пропсы
Разобрано из кода записи: обязательные — без «?», у остальных показано значение по умолчанию.
| Проп | Тип | По умолчанию | Что это |
|---|---|---|---|
| text? | string | "ПОМЕХИ В КАНАЛЕ" | Текст надписи (он же уходит в data-атрибут для слоёв-каналов). |
| period? | number | 3.2 | Секунд на цикл (в цикле два коротких всплеска). |
| color? | string | "oklch(0.93 0.01 265)" | Цвет базовой надписи. |
Установка
npx shadcn@latest add https://motiva.pages.dev/r/glitch-text.jsonЧто нужно в проекте до установки
components.jsonв корне — с алиасами в форме"components": "@/components". Нет файла — CLI не поймёт, куда класть.- Алиас
@объявлен дважды:"paths": {"@/*": ["./src/*"]}в корневомtsconfig.json(в Vite он часто содержит толькоreferences— тогда CLI создаёт папку@) иresolve.aliasв конфиге сборщика. - Токены подключены один раз на приложение:
import "@/styles/motiva-tokens.css"— они приезжают вместе с записью. Без них секция потеряет цвета, ритм и тему. - Своя типографика не должна спорить: если у вас на обёртке
text-align: center, он протечёт внутрь блоков. - Проект без TypeScript? Всё равно нужен минимальный
tsconfig.jsonсpathsи"tsx": trueвcomponents.json: CLI грузит tsconfig безусловно, а с"tsx": falseидёт заjsconfig.jsonи падает так же. Приехавший рядом.tsxможно не трогать — вам нужен.vanilla.js.
Экспорт
Код
import type { CSSProperties } from "react";
export interface GlitchTextProps {
/** Текст надписи (он же уходит в data-атрибут для слоёв-каналов). */
text?: string;
/** Секунд на цикл (в цикле два коротких всплеска). */
period?: number;
/** Цвет базовой надписи. */
color?: string;
}
/**
* Глитч-надпись: два слоя-канала (::before/::after с content: attr(data-text))
* сдвинуты в стороны и порезаны полосами clip-path. Весь «шум» — окна в процентах
* ОДНОГО цикла с step-end: значения прыгают, а не плывут, — глитч дискретен по природе.
* Вне всплесков слои полностью скрыты, видна чистая надпись.
* Reduced-motion / data-shot — слои спрятаны, остаётся обычный текст.
*/
export function GlitchText({ text = "ПОМЕХИ В КАНАЛЕ", period = 3.2, color = "oklch(0.93 0.01 265)" }: GlitchTextProps = {}) {
return (
<span
className="gt"
data-text={text}
style={
{
position: "relative",
display: "inline-block",
color,
fontWeight: 800,
letterSpacing: "0.02em",
whiteSpace: "nowrap",
"--gt-period": `${period}s`,
} as CSSProperties
}
>
<style>{`
.gt::before, .gt::after {
content: attr(data-text);
position: absolute; inset: 0;
opacity: 0;
animation-duration: var(--gt-period);
animation-iteration-count: infinite;
/* прыжки, а не переходы: глитч дискретен по природе */
animation-timing-function: step-end;
}
.gt::before { color: oklch(0.65 0.25 25); animation-name: gt-a; }
.gt::after { color: oklch(0.75 0.15 195); animation-name: gt-b; }
/* два всплеска на цикл; между ними слои скрыты целиком */
@keyframes gt-a {
0%, 34% { opacity: 0; }
35% { opacity: 0.85; clip-path: inset(8% -2% 62% -2%); transform: translate(-3px, -1px); }
38% { clip-path: inset(48% -2% 22% -2%); transform: translate(3px, 1px); }
41% { clip-path: inset(72% -2% 4% -2%); transform: translate(-2px, 0); }
44%, 79% { opacity: 0; }
80% { opacity: 0.85; clip-path: inset(28% -2% 52% -2%); transform: translate(2px, 1px); }
83% { clip-path: inset(60% -2% 12% -2%); transform: translate(-3px, -1px); }
86%, 100% { opacity: 0; }
}
@keyframes gt-b {
0%, 35% { opacity: 0; }
36% { opacity: 0.85; clip-path: inset(55% -2% 18% -2%); transform: translate(3px, 1px); }
39% { clip-path: inset(12% -2% 70% -2%); transform: translate(-3px, -1px); }
42% { clip-path: inset(38% -2% 40% -2%); transform: translate(2px, 0); }
45%, 80% { opacity: 0; }
81% { opacity: 0.85; clip-path: inset(66% -2% 8% -2%); transform: translate(-2px, 1px); }
84% { clip-path: inset(18% -2% 58% -2%); transform: translate(3px, -1px); }
87%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .gt::before, .gt::after { display: none; } }
`}</style>
{text}
</span>
);
}
Похожие эффекты
лицензия: MITавтор: Motivaисточник: оригинал (Motiva); идея-референс — ReactBits Glitch Text (MIT + Commons Clause: только идея)v1.0.0