# Pattern Animations — 7 типов процедурных анимаций
> Основано на реализациях из [patterngen-oss](https://github.com/halfof8/patterngen-oss).
> 7 анимационных типов для SVG-паттернов, рендерящихся через Canvas 2D с таймлайном.
## Обзор
Каждый паттерн — это SVG-файл 40×40 px, который анимируется одним из 7 типов.
Рендер происходит на Canvas 2D с 4× масштабированием (EXPORT_SCALE = 4).
Базовый кадр 1920×1080, сетка 20 px, FPS = 24.
## Таймлайн
```
Фаза 1 (0 — durationMs): Title reveal (half-reveal с easing)
Фаза 2 (durationMs — 2×): Patterns reveal + squares reveal (staggered)
Фаза 3 (2× — 4× durationMs): Patterns hold + dots pulsation (loop 4s)
Цикл: repeat cycle = 4 × durationMs
```
---
## 1. Dots — fade-in с stagger
Каждый SVG-элемент проявляется индивидуально с рандомной задержкой.
**Механика:**
```
dotP = max(0, min(1, (progress - stagger * 0.6) / 0.4))
globalAlpha = dotP
```
**Использование:**
- Мягкое проявление множества мелких элементов
- Звёздные/точечные паттерны, частицы, текстуры
- Элементы с `stagger` из SVG (случайный при парсинге)
**Параметры:**
- `stagger` определяет задержку: 0 = мгновенно, 5 = максимальный разброс
- Визуально: элементы появляются поочерёдно, создавая «волну»
---
## 2. Capsule — рост из центра по длинной оси
Каждый элемент масштабируется от центра вдоль своей более длинной оси.
**Механика:**
```
elP = max(0, min(1, (progress - stagger * 0.3) / 0.7))
if (w >= h) {
// горизонтальный: ширина растёт, высота стоит
animW = w * elP
animX = cx - animW / 2
} else {
// вертикальный: высота растёт, ширина стоит
animH = h * elP
animY = cy - animH / 2
}
```
**Использование:**
- Анимация линий, полос, разделителей
- Эффект «заполнения» вдоль направления
- Элементы с rotation поддерживаются (через rotate transform)
---
## 3. Circle — pie-fill clockwise reveal
Полное SVG-изображение проявляется секторально, как таймер.
**Механика:**
```
cx = size / 2
cy = size / 2
startAngle = -PI / 2
endAngle = startAngle + PI * 2 * progress
ctx.arc(cx, cy, size, startAngle, endAngle)
ctx.drawImage(img, 0, 0, size, size)
```
**Использование:**
- Круговые паттерны, диаграммы, радары
- Прогресс-индикаторы, loading-анимации
- Полное изображение, не по-элементно
---
## 4. Arrow — slide up снизу
Полное изображение физически сдвигается вверх из-за нижнего края.
**Механика:**
```
offset = size * (1 - progress)
ctx.drawImage(img, 0, offset, size, size)
```
**Использование:**
- Элементы «влетают» снизу
- Эффект подъёма, выдвижения
- Подходит для контрастных паттернов на тёмном фоне
---
## 5. Square — scale down 1.6× → 1×
Изображение масштабируется от 1.6× до 1× (на 60% больше до нормального).
**Механика:**
```
s = 1 + (1 - progress) * 0.6
cx = size / 2
cy = size / 2
ctx.translate(cx, cy)
ctx.scale(s, s)
ctx.translate(-cx, -cy)
ctx.drawImage(img, 0, 0, size, size)
```
**Использование:**
- Резкий акцент, «взрывное» проявление
- Привлечение внимания к паттерну
- Квадратные/крестообразные элементы
---
## 6. Stripes — slide-in слева направо
Каждая полоса (элемент) сдвигается сверху вниз, сортировка по X.
**Механика:**
```
sorted = shapes.sort((a, b) => a.x - b.x)
stripeStart = (i / n) * 0.5
stripeP = max(0, min(1, (progress - stripeStart) / 0.5))
slideOffset = (1 - stripeP) * -size
ctx.translate(0, slideOffset)
```
**Использование:**
- Полосатые паттерны, штрих-код текстуры
- Горизонтальные линии, решётки
- Эффект «сканирования» слева направо
---
## 7. Cross — scale down 1.6× → 1×
Тот же алгоритм, что и `square`, но для крестообразных элементов.
Разница исключительно в семантике и визуальном контексте.
**Механика:**
```
// identical to square
s = 1 + (1 - progress) * 0.6
ctx.scale(s, s)
```
---
## Easing функции
| Название | Формула |
|---------------|---------|
| `linear` | `t` |
| `easeIn` | `t²` |
| `easeOut` | `t(2-t)` |
| `easeInOut` | `2t²` при t<0.5, `-1+(4-2t)t` при t≥0.5 |
| `easeInCubic` | `t³` |
| `easeOutCubic`| `1-(1-t)³` |
| `easeInOutCubic` | `4t³` при t<0.5, `1-(-2t+2)³/2` при t≥0.5 |
---
## SVG Spec
Каждый SVG-паттерн должен соответствовать формату:
```xml
```
**Правила:**
1. Размер: 40×40 px (viewBox 0 0 40 40)
2. Фон: `` (переокрашивается в runtime)
3.Foreground: `fill="black"` и/или `stroke="black"` (переокрашивается)
4. Тег `` игнорируется при парсинге
5. Вложенные `` обрабатываются рекурсивно
6. Анимация определяется типом анимации, не структурой SVG
**Поддерживаемые теги:** ``, ``, ``
**Transform:** `rotate(angle, ox, oy)` — угол поворота и точка вращения.
---
## Референсы кода
- `src/engine/animations.ts` — 7 switch-касов для каждого animType
- `src/engine/timeline.ts` — фаза titles → patterns → dots (цикл 4× duration)
- `src/engine/easing.ts` — 7 easing функций
- `src/core/patterns.ts` — парсинг SVG, colorizeSvg, svgToImage
- `src/export/exporter.ts` — экспорт PNG-секвенций (titles, patterns, dots)
- `src/types.ts` — PatternAnimType, SvgShapeInfo, PatternDef