--- name: motion/staggered-reveal title: Staggered Element Reveal description: Cascading entrance animations where elements appear sequentially. Used on Linear, Raycast, Linear.app hero sections. tags: [motion, gsap, scrolltrigger, entrance, stagger] source: linear.app, raycast.com, godly.website top 50 --- # Staggered Element Reveal ## Что это Последовательное появление элементов с нарастающей задержкой. Создаёт ощущение "потока" и профессионализма. Элементы появляются не все сразу, а каскадом с интервалом. ## Где используется - Hero-секции Linear, Raycast, Resend - Feature-блоки с иконками - Списки преимуществ - Карточки с услугами ## Ключевые параметры | Параметр | Значение | Почему | |----------|----------|--------| | `stagger` | `0.08–0.12` | Оптимальный ритм — не слишком быстро, не медленно | | `duration` | `0.6–0.8s` | Достаточное время для заметности | | `ease` | `power3.out` | Плавное замедление, ощущение "приземления" | | `delay` | `0.2–0.3` | Задержка перед началом каскада | | `from opacity` | `0.8` | Не полная прозрачность, чтобы не было "прыжка" | | `from translateY` | `20–30px` | Элементы "влетают" снизу | ## Референсы ### Linear Hero ``` 1. Logo появляется → 0.3s задержка 2. H1 появляется (line by line) → stagger 0.1s 3. Подзаголовок → 0.4s задержка 4. CTA кнопка → 0.6s задержка 5. Декоративные элементы → 0.8s задержка ``` ### Resend Feature Grid ``` - Карточки появляются с задержкой 0.08s друг за другом - Каждая карточка: fade + slide up 15px - Hover на карточку: scale 1.02 + shadow ``` ## Реализация ```javascript // GSAP + ScrollTrigger import gsap from 'gsap'; import { ScrollTrigger } from 'gsap/ScrollTrigger'; gsap.registerPlugin(ScrollTrigger); // 1. Базовый stagger-ревеал gsap.from('.stagger-item', { opacity: 0, y: 30, duration: 0.7, stagger: 0.08, ease: 'power3.out', delay: 0.3, scrollTrigger: { trigger: '.stagger-section', start: 'top 80%', toggleActions: 'play none none none' } }); // 2. Stagger для карточек gsap.from('.feature-card', { opacity: 0, y: 25, scale: 0.97, duration: 0.6, stagger: 0.06, ease: 'power2.out', scrollTrigger: { trigger: '.features-grid', start: 'top 85%' } }); // 3. Stagger для текстовых строк gsap.from('.hero-line', { opacity: 0, y: 40, duration: 0.8, stagger: 0.12, ease: 'power3.out', delay: 0.2 }); // 4. Line-by-line reveal для заголовка const lines = document.querySelectorAll('.hero h1 .line'); gsap.from(lines, { opacity: 0, y: 50, rotateX: -15, duration: 0.8, stagger: 0.15, ease: 'power3.out', delay: 0.3 }); ``` ## CSS подготовка ```css .stagger-item { /* Начальное состояние до анимации */ opacity: 0; transform: translateY(30px); will-change: opacity, transform; } /* Альтернатива: CSS-only для простых случаев */ @keyframes fadeUp { from { opacity: 0; transform: translateY(25px); } to { opacity: 1; transform: translateY(0); } } .stagger-item { opacity: 0; animation: fadeUp 0.6s ease forwards; } .stagger-item:nth-child(1) { animation-delay: 0.1s; } .stagger-item:nth-child(2) { animation-delay: 0.18s; } .stagger-item:nth-child(3) { animation-delay: 0.26s; } .stagger-item:nth-child(4) { animation-delay: 0.34s; } .stagger-item:nth-child(5) { animation-delay: 0.42s; } .stagger-item:nth-child(6) { animation-delay: 0.5s; } ``` ## Anti-patterns (Чего НЕ делать) | ❌ Плохо | ✅ Хорошо | |----------|-----------| | `stagger: 0.02` — слишком быстро, "мигание" | `stagger: 0.08` — чёткий ритм | | `stagger: 0.3` — слишком медленно, скучно | `stagger: 0.06–0.12` — оптимально | | Все элементы `opacity: 0 → 1` | `opacity: 0.8 → 1` + `y: 20 → 0` | | Без `will-change` | `will-change: opacity, transform` | | Без `stagger` (все сразу) | Каскадное появление | ## Performance ```javascript // ✅ GPU accelerated gsap.from('.item', { opacity: 0, y: 20, transform: 'translateY(20px)' }); // ❌ Bad — заставляет layout gsap.from('.item', { marginLeft: '20px' }); gsap.from('.item', { top: '20px', left: '20px' }); ``` ## Validation (CV Service) ```bash # После рендеринга страницы curl -s -X POST http://localhost:8001/design/analyze-dom \ -H "Content-Type: application/json" \ -d '{"html": "...", "full_analysis": false}' | python3 -m json.tool ``` Проверить: - `performance` score > 8 — анимации только на `transform` и `opacity` - `ux_heuristics` score > 6 — анимации не мешают навигации - `wcag_compliance` — анимация имеет `prefers-reduced-motion` фоллбэк ```css @media (prefers-reduced-motion: reduce) { .stagger-item { opacity: 1 !important; transform: none !important; animation: none !important; } } ```