Initial commit: 79+ design patterns, LLM prompts, and assets
This commit is contained in:
commit
2b42a76d6d
112 files changed
+13652
No files matched your search
@@ -0,0 +1,414 @@
|
||||
---
|
||||
title: HyperFrames — Создание Reels из HTML
|
||||
created: 2026-06-12
|
||||
updated: 2026-06-12
|
||||
type: concept
|
||||
tags: [hyperframes, video, reels, gsap, tiktok]
|
||||
sources:
|
||||
- concepts/web-psychology.md
|
||||
- concepts/micro-interactions.md
|
||||
confidence: high
|
||||
---
|
||||
|
||||
# HyperFrames — Создание профессиональных Reels из HTML
|
||||
|
||||
> **Формула:** HTML + GSAP анимации + Edge-TTS = готовый Reels без видеоредакторов
|
||||
>
|
||||
> *Инструкция для LLM-агента: создавай Reels через HyperFrames — пиши HTML, линтируй, рендери MP4.*
|
||||
|
||||
---
|
||||
|
||||
## Фаза 0: Подготовка
|
||||
|
||||
### 0.1. Проверка окружения
|
||||
|
||||
```bash
|
||||
node --version # нужен 22+
|
||||
ffmpeg -version # нужен 6.1.1+
|
||||
npx hyperframes doctor # проверка окружения
|
||||
```
|
||||
|
||||
**Требования:** Node.js 22+, FFmpeg 6.1.1+, Chromium (скачивается автоматически при первом рендере).
|
||||
|
||||
### 0.2. Структура проекта
|
||||
|
||||
```
|
||||
reels-project/
|
||||
├── index.html # МАСТЕР: root-контейнер, без <template>
|
||||
├── compositions/
|
||||
│ ├── 01-hook.html # Хук (0–3s): решает, смотреть или нет
|
||||
│ ├── 02-intro.html # Интро (3–8s)
|
||||
│ ├── 03-content.html # Контент (8–20s)
|
||||
│ ├── 04-cta.html # CTA (20–30s): призыв к действию
|
||||
│ └── 05-outro.html # Финал (25–30s): логотип + подписка
|
||||
├── assets/
|
||||
│ ├── narration.mp3 # Озвучка (Edge-TTS предпочтительно)
|
||||
│ └── bg-music.mp3 # Фоновая музыка (тихо, -20dB)
|
||||
└── lib/
|
||||
└── gsap.min.js # Локальная копия GSAP (CDN = 404 в headless)
|
||||
```
|
||||
|
||||
### 0.3. Разрешение для Reels
|
||||
|
||||
**1080×1920 (портрет, 9:16)** — стандарт для Reels/TikTok/Shorts.
|
||||
|
||||
```css
|
||||
html, body { width: 1080px; height: 1920px; overflow: hidden; }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Фаза 1: Написание композиции
|
||||
|
||||
### 1.1. Базовая структура (inline, без вложенных сцен)
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
html, body { width: 1080px; height: 1920px; overflow: hidden; background: #0a0820; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="clip-text clip" data-track-index="2" data-start="0" data-type="text">
|
||||
Как создать <span class="accent">Reels</span>
|
||||
</div>
|
||||
<script src="lib/gsap.min.js"></script>
|
||||
<script>
|
||||
const tl = gsap.timeline({ paused: true });
|
||||
tl.from('.clip-text', { opacity: 0, y: 100, duration: 0.8, ease: 'power3.out' }, 0);
|
||||
tl.set({}, {}, 10);
|
||||
window.__timelines = window.__timelines || {};
|
||||
window.__timelines['reels-hook'] = { timeline: tl, paused: true };
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### 1.2. Правило трёх
|
||||
|
||||
Каждая композиция должна содержать:
|
||||
- ✅ **Root:** `data-composition-id` + `data-width` + `data-height`
|
||||
- ✅ **Timed Elements:** `class="clip"` + `data-start` + `data-duration` + `data-track-index`
|
||||
- ✅ **Animations:** `gsap.timeline({ paused: true })` + регистрация на `window.__timelines`
|
||||
|
||||
### 1.3. Обязательные атрибуты
|
||||
|
||||
| Атрибут | Обязательный | Описание |
|
||||
|---|---|---|
|
||||
| `class="clip"` | Да | Элемент — клип видео |
|
||||
| `data-start` | Да | Секунда начала |
|
||||
| `data-duration` | Да | Длительность в секундах |
|
||||
| `data-track-index` | Да | Трек/слой (уникальный для каждого клипа) |
|
||||
| `data-type` | Нет | Тип элемента (`text`, `audio`, `clip`) |
|
||||
|
||||
**НЕ НАДО:** `data-duration` на clip НЕ нужен — длительность управляется GSAP-таймлайном.
|
||||
|
||||
### 1.4. Цветовая схема (проверенная)
|
||||
|
||||
```css
|
||||
background: #0a0820; /* Глубокий тёмно-синий */
|
||||
text: #fff; /* Белый текст */
|
||||
accent: #00ff88; /* Зелёный акцент */
|
||||
secondary: #8800ff; /* Фиолетовый */
|
||||
muted: #888; /* Серый для подписей */
|
||||
```
|
||||
|
||||
### 1.5. Шрифты
|
||||
|
||||
```html
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700;900&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
|
||||
```
|
||||
|
||||
| Шрифт | Где |
|
||||
|-------|-----|
|
||||
| **Inter** | Заголовки, текст, CTA (мин 40px для мобильного) |
|
||||
| **JetBrains Mono** | Код, цифры, технические блоки |
|
||||
|
||||
---
|
||||
|
||||
## Фаза 2: Режиссура Reels
|
||||
|
||||
### 2.1. Золотое правило: Hook первые 3 секунды
|
||||
|
||||
> **В Reels зритель скроллит каждые 0.5 секунды. Первые 3 секунды = жизнь видео.**
|
||||
|
||||
**Лучшие паттерны хуков (ранг):**
|
||||
1. **Blur-in** — текст из размытия `blur(15px)` за 0.6s → `blur(0px)`
|
||||
2. **Крупный заголовок** — `font-size: 72px`, акцентный цвет, fade-up
|
||||
3. **Glitch** — `steps(1)` + RGB-сплит (для tech-аудитории)
|
||||
|
||||
```javascript
|
||||
// Blur-in хук (самый надёжный)
|
||||
tl.from('.hook-text', {
|
||||
opacity: 0, y: 60, filter: 'blur(15px)',
|
||||
duration: 0.6, ease: 'power3.out'
|
||||
}, 0);
|
||||
```
|
||||
|
||||
### 2.2. Каденция текста
|
||||
|
||||
> **1 фраза = 1 слайд. Средняя скорость русской речи: ~3 слова/сек.**
|
||||
|
||||
```
|
||||
Хук: "HTML в Reels за 30 сек" → 3s
|
||||
Интро: "Без видеоредакторов" → 3s
|
||||
Контент: "HyperFrames = HTML → MP4" → 4s
|
||||
Контент: "Пишите HTML, рендерите" → 4s
|
||||
CTA: "Подпишись для туториалов" → 3s
|
||||
Итого: 17s (минимум 20–30s для алгоритма)
|
||||
```
|
||||
|
||||
### 2.3. Оптимальная длина
|
||||
|
||||
| Длина | Назначение | Сцен |
|
||||
|---|---|---|
|
||||
| 15–20s | Вирусный хук, тизер | 3–4 |
|
||||
| 25–30s | Туториал (стандарт) | 5–7 |
|
||||
| 35–45s | Глубокий разбор | 8–10 |
|
||||
|
||||
### 2.4. Эффекты для Reels (ранжированы)
|
||||
|
||||
**Подходит:**
|
||||
- **Blur reveal** — универсальный, профессиональный
|
||||
- **Кинетическая типографика** — по слову, держит внимание
|
||||
- **Счётчик** — `onUpdate` обновляет `textContent`
|
||||
- **Lower Thirds** — имя + бейдж + описание
|
||||
- **SVG прогресс-кольцо** — метрики, проценты
|
||||
- **Пульсирующая CTA** — `boxShadow` yoyo-repeat
|
||||
|
||||
**НЕ подходит для Reels:**
|
||||
- Глитч — слишком агрессивный
|
||||
- 3D параллакс — отвлекает от текста
|
||||
- RGB-сплит — на мобильном barely заметен
|
||||
|
||||
### 2.5. Аудио = 50% успеха
|
||||
|
||||
```bash
|
||||
# Edge-TTS (предпочтительно)
|
||||
edge-tts --text "Текст озвучки" --voice ru-RU-DmitryNeural --write-media assets/narration.mp3
|
||||
|
||||
# Проверка длительности
|
||||
ffprobe -v error -show_entries format=duration \
|
||||
-of default=noprint_wrappers=1:nokey=1 assets/narration.mp3
|
||||
```
|
||||
|
||||
**Голоса:**
|
||||
| Голос | Тип |
|
||||
|-------|-----|
|
||||
| `ru-RU-DmitryNeural` | Мужской, нейтральный |
|
||||
| `ru-RU-SvetlanaNeural` | Женский, тёплый |
|
||||
| `ru-RU-SergeyNeural` | Мужской, энергичный |
|
||||
|
||||
---
|
||||
|
||||
## Фаза 3: Готовые паттерны (copy-paste)
|
||||
|
||||
### Паттерн 1: Счётчик
|
||||
|
||||
```html
|
||||
<div class="stat-number" style="font-size:100px;font-weight:900;color:#00ff88">0</div>
|
||||
```
|
||||
|
||||
```javascript
|
||||
let counter = { val: 0 };
|
||||
tl.to(counter, {
|
||||
val: 10000,
|
||||
duration: 2,
|
||||
ease: 'power2.out',
|
||||
onUpdate: () => {
|
||||
document.querySelector('.stat-number').textContent =
|
||||
Math.floor(counter.val).toLocaleString();
|
||||
}
|
||||
}, 0.5);
|
||||
```
|
||||
|
||||
### Паттерн 2: Lower Thirds
|
||||
|
||||
```html
|
||||
<div class="lower-third" style="position:fixed;bottom:300px;left:60px">
|
||||
<div class="lt-name" style="font-size:40px;font-weight:700;color:#fff">HYPERFRAMES</div>
|
||||
<div class="lt-line" style="width:100px;height:4px;background:#00ff88;margin-top:8px"></div>
|
||||
<div class="lt-desc" style="font-size:24px;color:#888;margin-top:8px">HTML → MP4</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
```javascript
|
||||
tl.from('.lt-name', { x: -40, opacity: 0, duration: 0.4, ease: 'power2.out' }, 0.3);
|
||||
tl.from('.lt-line', { scaleX: 0, transformOrigin: 'left', duration: 0.3 }, 0.5);
|
||||
tl.from('.lt-desc', { x: -30, opacity: 0, duration: 0.4, ease: 'power2.out' }, 0.6);
|
||||
```
|
||||
|
||||
### Паттерн 3: SVG прогресс-кольцо
|
||||
|
||||
```html
|
||||
<svg width="160" height="160" viewBox="0 0 180 180">
|
||||
<circle cx="90" cy="90" r="80" fill="none" stroke="#222" stroke-width="8"/>
|
||||
<circle class="ring" cx="90" cy="90" r="80" fill="none" stroke="#00ff88" stroke-width="8"
|
||||
stroke-dasharray="502" stroke-dashoffset="502" stroke-linecap="round"
|
||||
transform="rotate(-90 90 90)"/>
|
||||
</svg>
|
||||
```
|
||||
|
||||
```javascript
|
||||
tl.to('.ring', { strokeDashoffset: 0, duration: 2, ease: 'power2.out' }, 0.5);
|
||||
```
|
||||
|
||||
### Паттерн 4: Пульсирующая CTA
|
||||
|
||||
```html
|
||||
<div class="cta-button" style="
|
||||
margin: 0 auto; padding: 24px 48px;
|
||||
background: #00ff88; color: #000;
|
||||
font-size: 36px; font-weight: 900;
|
||||
border-radius: 16px;
|
||||
">ПОДПИШИСЬ</div>
|
||||
```
|
||||
|
||||
```javascript
|
||||
tl.to('.cta-button', {
|
||||
boxShadow: '0 0 40px rgba(0,255,136,0.6)',
|
||||
duration: 0.3, yoyo: true, repeat: 3
|
||||
}, 1);
|
||||
```
|
||||
|
||||
### Паттерн 5: Кинетическая типографика
|
||||
|
||||
```html
|
||||
<div style="overflow:hidden">
|
||||
<span class="word" style="font-size:70px;font-weight:900;color:#fff;display:inline-block">КАЖДОЕ</span>
|
||||
<span class="word" style="font-size:70px;font-weight:900;color:#00ff88;display:inline-block">СЛОВО</span>
|
||||
</div>
|
||||
```
|
||||
|
||||
```javascript
|
||||
document.querySelectorAll('.word').forEach((word, i) => {
|
||||
tl.from(word, {
|
||||
y: 80, opacity: 0, filter: 'blur(15px)',
|
||||
duration: 0.6, ease: 'power3.out'
|
||||
}, i * 0.25);
|
||||
});
|
||||
```
|
||||
|
||||
### Паттерн 6: Детерминированные частицы (canvas)
|
||||
|
||||
```javascript
|
||||
function mulberry32(a) {
|
||||
return function() {
|
||||
a |= 0; a = a + 0x6D2B79F5 | 0;
|
||||
var t = Math.imul(a ^ a >>> 15, 1 | a);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
}
|
||||
}
|
||||
const rng = mulberry32(42); // всегда одинаковый результат
|
||||
```
|
||||
|
||||
> **НИКОГДА** `Math.random()` в canvas — рендер будет не детерминированным.
|
||||
|
||||
---
|
||||
|
||||
## Фаза 4: Рендер и экспорт
|
||||
|
||||
### 4.1. Команды
|
||||
|
||||
```bash
|
||||
npx hyperframes lint # ОБЯЗАТЕЛЬНО: проверка
|
||||
npx hyperframes preview # Порт 3003, HMR
|
||||
npx hyperframes render --quality high --workers 1 --output reels.mp4
|
||||
```
|
||||
|
||||
### 4.2. Параметры рендера
|
||||
|
||||
| Параметр | Значение | Описание |
|
||||
|---|---|---|
|
||||
| `--quality` | `draft`, `standard`, `high` | draft = без аудио, standard/high = с аудио |
|
||||
| `--workers` | `1` | Для тяжёлых композиций — ТОЛЬКО 1 |
|
||||
| `-f` | `30` | FPS. 30 достаточно для Reels |
|
||||
|
||||
### 4.3. Микширование narration
|
||||
|
||||
```bash
|
||||
# Без перекодирования видео (мгновенно)
|
||||
ffmpeg -y -i reels.mp4 -i assets/narration.mp3 \
|
||||
-c:v copy -c:a aac -b:a 192k -shortest \
|
||||
-map 0:v:0 -map 1:a:0 \
|
||||
-movflags +faststart \
|
||||
reels-final.mp4
|
||||
```
|
||||
|
||||
### 4.4. Проверка результата
|
||||
|
||||
```bash
|
||||
# Поток
|
||||
ffprobe -v error -show_entries stream=codec_type,codec_name reels-final.mp4
|
||||
# Ожидаемо: video/h264 + audio/aac
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Фаза 5: Типичные ошибки
|
||||
|
||||
### Ошибка 1: Видео обрезается короче narration
|
||||
**Решение:** добавить `tl.set({}, {}, DURATION)` в конец таймлайна.
|
||||
|
||||
### Ошибка 2: `gsap_infinite_repeat`
|
||||
**Причина:** `repeat: -1` ломает детерминированный рендер.
|
||||
**Решение:** `repeat: N` (конечное число).
|
||||
|
||||
### Ошибка 3: Canvas в screenshot mode
|
||||
**Причина:** raw `requestAnimationFrame()` в inline `<script>`.
|
||||
**Решение:** `setInterval` или вынести в `canvas.js`.
|
||||
|
||||
### Ошибка 4: `root_composition_missing_html_wrapper`
|
||||
**Причина:** комментарий перед `<!DOCTYPE html>`.
|
||||
**Решение:** `<!DOCTYPE html>` — строго первая строка.
|
||||
|
||||
### Ошибка 5: Перекрывающиеся клипы
|
||||
**Решение:** каждый `.clip` — уникальный `data-track-index`.
|
||||
|
||||
### Ошибка 6: CSS `transform` + GSAP `y`/`x`
|
||||
**Решение:** `xPercent`/`yPercent` вместо CSS `transform`.
|
||||
|
||||
### Ошибка 7: CDN GSAP = 404
|
||||
**Решение:** локальная `lib/gsap.min.js`.
|
||||
|
||||
---
|
||||
|
||||
## Фаза 6: Чек-лист перед публикацией
|
||||
|
||||
- [ ] Хук в первые 3 секунды (blur-in / крупный текст)
|
||||
- [ ] Длитель narration = длительность GSAP-таймлайна
|
||||
- [ ] `npx hyperframes lint` — без ошибок
|
||||
- [ ] `npx hyperframes preview` — каждый слайд визуально проверен
|
||||
- [ ] `--workers 1` для тяжёлых композиций
|
||||
- [ ] FFmpeg микширование: `-c:v copy -c:a aac`
|
||||
- [ ] `ffprobe` — два потока (h264 + aac)
|
||||
- [ ] Размер < 100MB (лимит Instagram)
|
||||
- [ ] Разрешение 1080×1920 (портрет)
|
||||
- [ ] Текст читается на мобильном (мин 40px)
|
||||
|
||||
---
|
||||
|
||||
## Готовые блоки
|
||||
|
||||
```bash
|
||||
npx hyperframes add flash-through-white # Переход через вспышку
|
||||
npx hyperframes add warm-grain # Зерно плёнки
|
||||
npx hyperframes add instagram-follow # Анимация подписки
|
||||
npx hyperframes add swiss-grid # Швейцарская сетка
|
||||
npx hyperframes add lower-third # Нижний титр
|
||||
```
|
||||
|
||||
## GSAP Easing
|
||||
|
||||
| Easing | Эффект | Применение |
|
||||
|--------|--------|-----------|
|
||||
| `power2.out`, `power3.out` | Плавное замедление | Появление текста |
|
||||
| `back.out(1.7)` | Пружинящее | CTA-кнопки |
|
||||
| `sine.inOut` | Мягкий синус | Фоновые элементы |
|
||||
| `circ.inOut` | Медленное начало/конец | Элегантные переходы |
|
||||
| `steps(1)` | Глитч | Резкие кадры |
|
||||
Reference in new issue
Block a user