- 74 brands: airbnb, stripe, apple, figma, linear, vercel, etc. - 147 files: DESIGN.md + README.md per brand (~2.1 MB) - Each DESIGN.md contains structured brand analysis (colors, typography, components) - Updated 00-overview.md with new design-systems directory
214 lines
7.1 KiB
Markdown
214 lines
7.1 KiB
Markdown
# 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
|
||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none">
|
||
<rect width="40" height="40" fill="white"/>
|
||
<!-- foreground shapes -->
|
||
<circle cx="20" cy="20" r="14" fill="black"/>
|
||
<rect x="10" y="10" width="20" height="20" rx="4" fill="black" stroke="black"/>
|
||
</svg>
|
||
```
|
||
|
||
**Правила:**
|
||
1. Размер: 40×40 px (viewBox 0 0 40 40)
|
||
2. Фон: `<rect width="40" height="40" fill="white"/>` (переокрашивается в runtime)
|
||
3.Foreground: `fill="black"` и/или `stroke="black"` (переокрашивается)
|
||
4. Тег `<defs>` игнорируется при парсинге
|
||
5. Вложенные `<g>` обрабатываются рекурсивно
|
||
6. Анимация определяется типом анимации, не структурой SVG
|
||
|
||
**Поддерживаемые теги:** `<rect>`, `<circle>`, `<path>`
|
||
|
||
**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
|