Skip to main content
Содержание гайда

Содержание гайда

Время на изучение: 14 мин
#automation#animated#video#scroll#creative-coding#frontend
Средний14 мин

Анимированные скролл-сайты с видео: практическое руководство

Как создавать кинематографичные сайты с покадровой прокруткой видео (эффект Apple): нарезка кадров в WebP, сглаживание LERP на Canvas, dwell-remap и дизайн-система Precision Editorial.

Опубликовано:

Animated Video Scroll — это техника создания кинематографичных одностраничных сайтов, где прокрутка страницы напрямую управляет покадровым воспроизведением видео. Когда пользователь прокручивает страницу колесом мыши или свайпом на смартфоне, видеоряд плавно меняется кадр за кадром, синхронизируясь с ритмом чтения и появлением текста.

Этот визуальный прием стал фирменным знаком презентаций продуктов Apple, Tesla, Porsche и ведущих мировых дизайн-студий.

Важно

Эта техника не является встраиванием обычного видеоплеера и не использует тяжелые GIF-файлы. В ее основе лежит покадровая последовательность оптимизированных WebP-изображений, аппаратно отрисовываемых на элементе <canvas> через WebGL или 2D Context с нулевой задержкой отклика на скролл.


1. Что такое скролл-сайт с видео и его преимущества

Фоновое автовоспроизведение видео имеет два критических недостатка: оно не учитывает внимание пользователя и вызывает быстрый разряд аккумулятора на мобильных устройствах.

Сайт с управлением видео через скролл решает эти проблемы:

  • Полный контроль внимания: Пользователь сам определяет темп изучения продукта. Остановка на абзаце фиксирует ракурс камеры в нужной точке.
  • Мгновенный отклик без буферизации: Видео заранее разбивается на оптимизированные кадры WebP, избавляя браузер от тяжелого декодирования контейнеров MP4 при быстром скролле.
  • Синхронизация повествования: Заголовки, спецификации и числовые метрики появляются строго в момент демонстрации соответствующего узла или детали.

Матрица применимости

Тип продуктаПочему подходит скролл-видеоКлючевой акцент в кадре
Автомобили и техникаПодчеркивает аэродинамику, шасси и отделку салонаПлавное движение камеры вдоль кузова, смена ракурсов
Премиальная электроникаДемонстрирует прецизионную сборку и обработку материаловРазборка на компоненты (exploded view), макросъемка
Архитектура и девелопментПередает объем, масштаб и естественное освещениеПролет через фасад во внутренние интерьеры
Fashion и ювелирные изделияРаскрывает текстуру тканей и игру света на металлеТонкое скольжение света по граням изделия

2. Архитектура и структура файлов навыка

Пайплайн разработки построен как модульная инженерная система. Каждый файл папки навыка отвечает за свой изолированный этап:

text
animated-sites-engine/ ├── SKILL.md # Сценарная инструкция: от анализа видео до верстки ├── visual-system.md # Дизайн-система Precision Editorial и правила сетки ├── extract_frames.py # Python-утилита нарезки и сжатия кадров в WebP └── evals.json # Бенчмарки и критерии автоматической проверки качества

1. SKILL.md — главное руководство и сценарный алгоритм

Регламентирует сквозной цикл разработки: от анализа исходного ролика через ffprobe до деления на смысловые главы, расчета высоты скролла и сборки готового шаблона.

2. visual-system.md — справочник системы Precision Editorial

Устанавливает строгие эстетические стандарты: отказ от клише (неоновых подсветок, размытых стеклянных плашек, шрифта Playfair), готовая палитра «Trackline» для инженерных тем и 5 схем компоновки контента.

3. extract_frames.py — скрипт экстракции и сжатия кадров

Консольная утилита на Python. Автоматически считывает метаданные видео через ffprobe, рассчитывает оптимальное число кадров, нарезает отдельные потоки для Desktop и Mobile в формате WebP и формирует manifest.json.

4. evals.json — сценарии верификации качества

Содержит эталонный тестовый сценарий (на примере ролика с Porsche GT3), проверяющий плавность LERP, поведение canvas при ресайзе, доступность с клавиатуры и общий вес ассетов.


3. Механика воспроизведения: Canvas, LERP и Dwell-Remap

В основе работы лежит элемент <canvas>, зафиксированный на весь экран (position: fixed). Прокрутка страницы пересчитывается в относительный прогресс от 0.0 до 1.0, определяющий отображаемый номер кадра.

text
Позиция скролла (0.0 — 1.0) │ ▼ ┌───────────────────────┐ │ Dwell-Remap │ ──► Искусственное замедление у центров глав └──────────┬────────────┘ │ ▼ ┌───────────────────────┐ │ LERP-фильтр │ ──► targetFrame плавно догоняет текущий скролл └──────────┬────────────┘ │ ▼ ┌───────────────────────┐ │ HTML5 2D Canvas │ ──► ctx.drawImage(loadedImages[frameIndex], ...) └───────────────────────┘

1. Сглаживание через LERP (Linear Interpolation)

Прямое переключение кадров по событиям скролла приводит к дерганой анимации на колесах мыши с дискретным шагом.

Для кинематографичной плавности применяется линейная интерполяция: отрисовываемый кадр (currentFrame) плавно догоняет целевой (targetFrame).

javascript
let currentFrame = 0; let targetFrame = 0; const lerpFactor = 0.075; // Коэффициент сглаживания (0.05 — 0.1) function renderLoop() { // Плавно приближаем текущий кадр к целевому currentFrame += (targetFrame - currentFrame) * lerpFactor; const frameToDraw = Math.round(currentFrame); drawCanvasFrame(frameToDraw); requestAnimationFrame(renderLoop); } window.addEventListener("scroll", () => { const maxScroll = document.documentElement.scrollHeight - window.innerHeight; const progress = Math.min(Math.max(window.scrollY / maxScroll, 0), 1); targetFrame = progress * (totalFrames - 1); }, { passive: true });

2. Замедление у глав (Dwell-Remap)

Чтобы посетитель успевал прочитать заголовок и ключевую мысль без необходимости ювелирно удерживать колесо мыши, применяется Dwell-Remap. Скорость смены кадров искусственно снижается около центров глав, сохраняя нормальную скорость на переходах.

javascript
function applyDwellRemap(rawProgress, chapterPoints = [0.2, 0.5, 0.8], dwellWidth = 0.08, strength = 0.45) { let remapped = rawProgress; for (const center of chapterPoints) { const distance = Math.abs(rawProgress - center); if (distance < dwellWidth) { // Плавное косинусоидальное замедление const factor = Math.cos((distance / dwellWidth) * (Math.PI / 2)); const delta = (rawProgress - center) * (1 - factor * strength); remapped = center + delta; break; } } return Math.min(Math.max(remapped, 0), 1); }

3. Прогрессивная загрузка кадров

Чтобы исключить белые вспышки canvas и не заставлять пользователя ждать загрузки всех 120+ кадров, применяется двухступенчатая схема:

  1. Критический приоритет: Мгновенно подгружаются первые 5 кадров и опорные кадры каждой главы.
  2. Фоновая очередь: Остальные кадры догружаются небольшими пачками через requestIdleCallback. Если запрошенный кадр еще в пути, canvas показывает ближайший доступный соседний кадр.

4. Пошаговый процесс разработки: от видео к коду

Производственный пайплайн состоит из семи последовательных шагов:

Шаг 1. Анализ ролика через ffprobe

Перед началом верстки извлекаются технические параметры исходного файла:

bash
ffprobe -v error -select_streams v:0 \ -show_entries stream=width,height,duration,r_frame_rate,codec_name \ -of default=noprint_wrappers=1 input.mp4

Формируется контактный лист из 6 опорных кадров для анализа движения камеры, положения объекта и наличия свободного пространства (negative space) под текст.

Шаг 2. Формулирование дизайн-концепции

Фиксируется четкий план:

  • Главный герой: Что находится в фокусе внимания.
  • Целевая эмоция: Инженерная строгость, спокойная роскошь, скорость или минимализм.
  • Шрифтовая пара: Характерный заголовочный гротеск и моноширинный акцент.
  • Фирменный прием: Телеметрия, переменная ширина начертания, счетчик микрокадров.

Шаг 3. Нарезка и оптимизация кадров

Количество кадров и высота прокрутки страницы определяются хронометражем исходного ролика:

Длительность видеоКоличество кадровРекомендуемая высота скроллаЦелевой вес ассетов (WebP)
0–5 секунд60–80 кадров450–550vh4–7 МБ
5–15 секунд90–130 кадров600–750vh8–12 МБ
15–30 секунд130–180 кадров750–900vh10–15 МБ
30+ секунд180–200 кадров900–1000vh12–16 МБ

Запуск нарезки через Python-утилиту:

bash
python3 extract_frames.py \ --input ./raw/porsche-gt3.mp4 \ --output ./public/frames \ --desktop-frames 120 \ --mobile-frames 80 \ --quality 62

Шаг 4. Сценарий по главам

Материал делится на 4–6 смысловых глав:

  1. Глава 1: Введение (0–15%) — Название модели, силуэт в контровом свете.
  2. Глава 2: Аэродинамика (20–40%) — Геометрия антикрыла и диффузора.
  3. Глава 3: Силовая установка (45–65%) — Шасси и показатели мощности.
  4. Глава 4: Финал и действие (75–100%) — Полный ракурс и кнопка тест-драйва.

Шаг 5. Композиция слоев вокруг видео

Текст не должен перекрывать движущийся объект. Положение блоков динамически смещается от левой к правой колонке в зависимости от траектории камеры.

Шаг 6. Сборка на основе стартового шаблона

В готовый HTML5-шаблон переносятся токены стилей, сгенерированный манифест кадров и текстовые главы.

Шаг 7. Проверка и арт-дирекшн

Совет

Всегда проверяйте результат через локальный сервер (python3 -m http.server), а не открытием file:///. Политика CORS в браузерах блокирует асинхронную загрузку WebP-кадров при прямом открытии файлов с диска.


5. Визуальная система: типографика и палитра Trackline

Стиль Precision Editorial требует отказа от декоративного мусора в пользу строгой швейцарской сетки и приборной эстетики.

Типографические пары

  • Заголовки: Archivo (Black, плотный трекинг -0.03em)
  • Основной текст: Archivo (Regular, 15px)
  • Телеметрия и шильдики: IBM Plex Mono (Medium, 11px, Uppercase)
  • Подходит для: Автомобили, авиация, тяжелая инженерия, часы.

Цветовая палитра «Trackline»

Палитра вдохновлена асфальтом гоночного трека, карбоном и контрольными лампами приборов:

css
:root { /* Базовые поверхности */ --color-carbon: #080a09; /* Глубокий матовый черный (основной фон) */ --color-paper: #f1f0e9; /* Теплый матовый белый (основной текст) */ --color-alloy: #a8aca8; /* Анодированный алюминий (второстепенный текст) */ --color-track: #414541; /* Графитовый асфальт (линии сетки, разделители) */ /* Сигнальные акценты */ --color-petrol: #12372d; /* Глубокий гоночный петролеум (фон карточек) */ --color-signal: #d9381e; /* Гоночный красный (активные состояния, алерты) */ --color-heritage: #c5a059; /* Золотистый оттенок (индикатор прогресса) */ }
Примечание

Сигнальные цвета (--color-signal и --color-heritage) наносятся точечно — не более чем на 3% площади экрана.


6. Композиция слоев, движение и фирменные приемы

Страница формируется из трех наложенных друг на друга визуальных слоев:

text
┌─────────────────────────────────────────────────────────────┐ │ 3. Слой интерфейса: прогресс-бар, статус главы, кнопки │ ├─────────────────────────────────────────────────────────────┤ │ 2. Информационный слой: заголовок, описание, телеметрия │ ├─────────────────────────────────────────────────────────────┤ │ 1. Canvas-слой: полноэкранное видео со сглаживанием LERP │ └─────────────────────────────────────────────────────────────┘

5 схем компоновки контента

Схема компоновкиПоложение контентаОптимальный сценарий
Masthead StatementКрупный заголовок по центру экранаВводный экран в начале страницы
Side Margin AnnotationУзкая колонка (3–4 cols) слева или справаОбъект движется в противоположной части кадра
Split StatementЗаголовок слева, параметры справаОбъект стабильно зафиксирован по центру
Telemetry DockГоризонтальная плашка внизу экранаДемонстрация характеристик, мощности и скорости
Final CalloutКарточка с единственным целевым действиемФинальный экран после завершения видеоряда

Принципы анимации DOM-элементов

Так как видео на canvas уже обеспечивает мощную динамику, оверлеи анимируются сдержанно:

  • Появление через маску: Текст поднимается из контейнера с overflow: hidden.
  • Смещение: Не более 16–24px по вертикали.
  • Тайминги: 600–800ms с кривой cubic-bezier(0.16, 1, 0.3, 1).
  • Никаких размытий: Свойство filter: blur() запрещено — оно перегружает GPU и разрушает 60 FPS.

7. Антипаттерны: отказ от устаревших штампов

Большинство типовых видеолендингов страдают от одних и тех же дизайнерских ошибок. Избавьтесь от них:

Устаревший штампПочему это плохоПрофессиональная альтернатива
Playfair Display + тонкий гротескШаблон «псевдороскоши»Прецизионные гротески: Archivo, Roboto Flex
Glassmorphism (матовое стекло)Размывает видео, перегружает видеокартуКонтрастный чистый текст в свободном пространстве кадра
Плавающие частицы и пыльОтвлекают внимание от реального продуктаЧистый canvas без искусственного визуального мусора
Фиолетово-синий неоновый градиентАссоциируется с шаблонными криптосайтамиНатуральные оттенки, взятые из кадров видео
Кастомный курсор с задержкойСоздает ощущение лага интерфейсаСистемный курсор с понятными интерактивными ховерами

8. Производительность, доступность (A11y) и адаптивность

1. Ограничение Device Pixel Ratio (DPR)

На мобильных экранах с DPR 3.0 рендеринг полноэкранного canvas перегревает устройство. Ограничьте DPR значением 2.0:

javascript
// Ограничиваем DPR значением 2.0 const dpr = Math.min(window.devicePixelRatio || 1, 2); canvas.width = window.innerWidth * dpr; canvas.height = window.innerHeight * dpr; ctx.scale(dpr, dpr);

2. Пауза рендеринга для скрытых вкладок

Останавливайте анимационный цикл при переключении вкладки:

javascript
document.addEventListener("visibilitychange", () => { if (document.hidden) { cancelAnimationFrame(animationFrameId); } else { requestAnimationFrame(renderLoop); } });

3. Поддержка режима уменьшенной анимации (prefers-reduced-motion)

Важно

Если в операционной системе включен режим prefers-reduced-motion: reduce, замените непрерывную смену кадров на статичный постер высокого разрешения.

css
@media (prefers-reduced-motion: reduce) { .scroll-container { height: auto !important; } canvas { display: none !important; } .static-hero-fallback { display: block !important; } }

9. Практический воркшоп: создание и запуск проекта

Шаг 1. Нарезка кадров

Поместите видео в рабочую папку и выполните команду:

bash
mkdir my-scroll-site && cd my-scroll-site python3 extract_frames.py --input sample.mp4 --output ./frames --desktop-frames 120

Скрипт создаст файл frames/manifest.json:

json
{ "totalFrames": 120, "desktop": { "pathPattern": "frames/desktop/frame-%04d.webp", "width": 1920, "height": 1080, "totalWeightMb": 9.4 }, "recommendedScrollVh": 700 }

Шаг 2. Структура файлов готового проекта

text
my-scroll-site/ ├── index.html # Разметка и контейнер canvas ├── styles.css # Токены стилей и медиазапросы ├── app.js # Цикл LERP, dwell-remap и обработчики скролла └── frames/ ├── desktop/ # frame-0001.webp ... frame-0120.webp ├── mobile/ # frame-0001.webp ... frame-0080.webp └── manifest.json # Метаданные и размеры

Шаг 3. Запуск локального сервера

bash
python3 -m http.server 3000

Откройте http://localhost:3000 и проверьте синхронизацию глав с прокруткой.


10. Итоговый чек-лист готовности скролл-сайта

Инженерия и производительность

  • Вес кадров для десктопа не превышает 12 МБ (мобильные — до 5 МБ).
  • Первые 5 кадров имеют директиву <link rel="preload">.
  • Коэффициент DPR ограничен значением 2.0.
  • Цикл requestAnimationFrame засыпает при неактивной вкладке.

UX и доступность

  • LERP обеспечивает плавный ход кадров без рывков.
  • Dwell-Remap позволяет комфортно прочесть текст каждой главы.
  • Реализован статичный постер для prefers-reduced-motion.
  • Кликабельные элементы имеют размер не менее 44×44px.

Дизайн и эстетика

  • Выбрана строгая инженерная шрифтовая пара.
  • Текст не закрывает ключевой объект в кадре.
  • Палитра интерфейса сформирована из цветов самого видео.
  • В конце страницы размещен единственный ясный призыв к действию (CTA).
Этот гайд полностью бесплатный. Если он сэкономил вам вечер — вы можете поддержать развитие проекта.
Поддержать автора