251 lines
11 KiB
Markdown
251 lines
11 KiB
Markdown
# SVG Редактор — Полный функционал
|
||
|
||
**URL:** https://images.wadevelop.ru/svgeditor
|
||
**Файл:** /mnt/webdata/www/images.wadevelop.ru/public/svgeditor.html (2099 строк)
|
||
**API:** server.js — 3 эндпоинта
|
||
|
||
---
|
||
|
||
## Интерфейс (как фоторедактор /editor)
|
||
|
||
- **Тулбар** (44px) — горизонтальная панель инструментов сверху
|
||
- **Панель опций** (36px) — контекстная, показывает настройки активного инструмента
|
||
- **Вкладки** (30px) — несколько документов одновременно
|
||
- **Viewport** — тёмный фон (#2c2c30), белый SVG-холст по центру
|
||
- **Статус-бар** (28px) — размер холста, зум, координаты, кол-во элементов
|
||
- **Сайдбар** (56px) — навигация по сервисам (как во всех страницах)
|
||
|
||
---
|
||
|
||
## Инструменты рисования
|
||
|
||
| Инструмент | Клавиша | Описание |
|
||
|------------|---------|----------|
|
||
| Выделение | V | Клик для выделения, drag для перемещения |
|
||
| Прямоугольник | R | Shift — квадрат |
|
||
| Эллипс | O | Shift — круг |
|
||
| Линия | L | Shift — snap к 45° |
|
||
| Перо | P | Клик по точкам, замыкание на первую точку (красный кружок), двойной клик — открытый путь |
|
||
| Текст | T | Клик → ввод текста, двойной клик — редактирование |
|
||
|
||
### После рисования:
|
||
- Автопереключение на Выделение (V)
|
||
- Элемент сразу выделен с хэндлами
|
||
- Панель свойств открывается автоматически
|
||
|
||
---
|
||
|
||
## Выделение и трансформация
|
||
|
||
- **Клик** на элемент → выделение + 8 хэндлов (для rect/ellipse/text/group)
|
||
- **Клик** на линию → 2 хэндла на концах
|
||
- **Drag за хэндл** → ресайз (для всех типов, включая группы и AI иконки)
|
||
- **Drag за тело** → перемещение
|
||
- **Стрелки** ←↑→↓ — перемещение на 1px, Shift+стрелки — на 10px
|
||
- **Маркиз** — клик на пустое место + drag → пунктирная рамка, выделяет верхний элемент в области
|
||
- **Proximity selection** — тонкие элементы (линии, outline иконки) ловятся в радиусе 12px
|
||
- **Уже выделенный элемент** — повторный клик внутри его bounds не сбрасывает выделение
|
||
- Хэндлы прячутся при `elementFromPoint` чтобы не блокировать клик
|
||
|
||
---
|
||
|
||
## Панель опций (контекстная)
|
||
|
||
### При рисовании (rect/circle/line/path):
|
||
- Заливка — цвет + вкл/выкл (✓/✗)
|
||
- Непрозрачность — слайдер 0-100%
|
||
- Обводка — цвет + вкл/выкл
|
||
- Толщина обводки — число
|
||
|
||
### При выделении элемента:
|
||
- Те же контролы с текущими значениями элемента
|
||
- Изменения применяются сразу
|
||
|
||
### При инструменте Текст:
|
||
- Размер шрифта
|
||
- Цвет
|
||
|
||
---
|
||
|
||
## Панель свойств (правая, автопоказ)
|
||
|
||
- Позиция: X, Y (CX, CY для эллипса, X1/Y1 для линии)
|
||
- Размер: W, H (RX, RY для эллипса)
|
||
- Стиль: Fill (цвет), Stroke (цвет), Stroke-width, Opacity
|
||
- Текст: Font-size
|
||
- Появляется автоматически при выделении
|
||
- Скрывается при снятии выделения
|
||
- Кнопка × для закрытия
|
||
|
||
---
|
||
|
||
## Система слоёв
|
||
|
||
- **Слой 1** создаётся автоматически (каждый слой = `<g data-layer="true">`)
|
||
- Все новые объекты создаются на **активном слое**
|
||
- Кнопка **«+ Новый слой»** внизу панели
|
||
- **Активный слой** подсвечен синим с полоской слева
|
||
- Клик по слою → делает его активным
|
||
- Каждый слой: видимость (👁), удаление (×)
|
||
- Объекты внутри слоя: клик для выделения, × для удаления
|
||
- Группы отмечены 📁 с количеством детей
|
||
- Минимум 1 слой (нельзя удалить последний)
|
||
- Очистка холста пересоздаёт Слой 1
|
||
|
||
---
|
||
|
||
## Группировка
|
||
|
||
| Действие | Клавиша | Описание |
|
||
|----------|---------|----------|
|
||
| Группировать | Ctrl+G | Все объекты активного слоя → `<g data-name="Группа">` |
|
||
| Разгруппировать | Ctrl+Shift+G | Выделенная группа → отдельные элементы в слой |
|
||
|
||
- Слои (`data-layer`) защищены от разгруппировки
|
||
- Группа двигается/масштабируется как единый объект
|
||
- В панели слоёв группа показана как 📁
|
||
|
||
---
|
||
|
||
## Контекстное меню (правая кнопка)
|
||
|
||
- Копировать (Ctrl+C)
|
||
- Вырезать (Ctrl+X)
|
||
- Вставить (Ctrl+V)
|
||
- Дублировать (Ctrl+D)
|
||
- Удалить (Del)
|
||
- На передний план
|
||
- На задний план
|
||
- Группировать (Ctrl+G)
|
||
- Разгруппировать (Ctrl+Shift+G)
|
||
|
||
Пункты автоматически деактивируются когда неприменимы.
|
||
|
||
---
|
||
|
||
## Вкладки
|
||
|
||
- **Новый** — первая вкладка по умолчанию
|
||
- **+** — новая вкладка (Ctrl+T)
|
||
- **×** — закрыть вкладку (минимум 1)
|
||
- Каждая вкладка сохраняет: SVG-содержимое, размер холста, историю undo/redo
|
||
|
||
---
|
||
|
||
## Импорт / Экспорт
|
||
|
||
| Действие | Клавиша | Формат |
|
||
|----------|---------|--------|
|
||
| Импорт SVG | Ctrl+O | .svg файл |
|
||
| Экспорт SVG | Ctrl+S | .svg с CSS-классами (st0, st1...) |
|
||
| Экспорт PNG | — | .png 800×600 (или текущий размер холста) |
|
||
| Оптимизировать | — | Очистка через /api/svg-optimize |
|
||
| Drag & Drop | — | Перетаскивание .svg файла на холст |
|
||
|
||
### Экспорт SVG:
|
||
- Inline-атрибуты → CSS-классы в `<style>` блоке
|
||
- Одинаковые стили → один класс (`st0`, `st1`, ...)
|
||
- `data-name`, `data-layer` удаляются
|
||
- Positioning styles (left, top, width, height) удаляются
|
||
- Чистый SVG без мусора
|
||
|
||
---
|
||
|
||
## AI Генератор иконок
|
||
|
||
- Кнопка ✨ в тулбаре → модальное окно
|
||
- **45 иконок**: home, user, search, heart, star, settings, mail, phone, lock, bell, clock, cloud, download, upload, trash, plus, minus, check, close, arrow-left/right/up/down, menu, globe, link, eye, sun, moon, code, terminal, database, wifi, bookmark, share, cart, file, folder, camera и др.
|
||
- **Поиск** по названию (EN и RU)
|
||
- **Стили**: Контур / Заливка / Дуотон
|
||
- **Размеры**: 24, 32, 48, 64, 128 px
|
||
- **Цвет**: произвольный
|
||
- Иконка добавляется в центр холста на активный слой
|
||
|
||
---
|
||
|
||
## Навигация по холсту
|
||
|
||
| Действие | Способ |
|
||
|----------|--------|
|
||
| Зум | Колесо мыши / кнопки +/- |
|
||
| Зум по размеру | Ctrl+0 |
|
||
| Панорамирование | Space + drag / средняя кнопка мыши |
|
||
| Координаты | Отображаются в статус-баре в реальном времени |
|
||
|
||
---
|
||
|
||
## Горячие клавиши
|
||
|
||
| Клавиша | Действие |
|
||
|---------|----------|
|
||
| V | Выделение |
|
||
| R | Прямоугольник |
|
||
| O | Эллипс |
|
||
| L | Линия |
|
||
| P | Перо |
|
||
| T | Текст |
|
||
| Del / Backspace | Удалить выделенное |
|
||
| Ctrl+Z | Отменить |
|
||
| Ctrl+Shift+Z | Повторить |
|
||
| Ctrl+C | Копировать |
|
||
| Ctrl+V | Вставить |
|
||
| Ctrl+X | Вырезать |
|
||
| Ctrl+D | Дублировать |
|
||
| Ctrl+S | Экспорт SVG |
|
||
| Ctrl+O | Импорт SVG |
|
||
| Ctrl+N | Новый холст |
|
||
| Ctrl+T | Новая вкладка |
|
||
| Ctrl+G | Группировать |
|
||
| Ctrl+Shift+G | Разгруппировать |
|
||
| Ctrl+0 | Зум по размеру |
|
||
| ←↑→↓ | Перемещение на 1px |
|
||
| Shift+←↑→↓ | Перемещение на 10px |
|
||
| Escape | Снять выделение / отменить путь |
|
||
| Shift (при рисовании) | Квадрат / круг / snap линии к 45° |
|
||
| Space+drag | Панорамирование |
|
||
|
||
---
|
||
|
||
## Undo / Redo
|
||
|
||
- До 30 шагов истории
|
||
- Сохраняется innerHTML SVG
|
||
- История привязана к вкладке
|
||
|
||
---
|
||
|
||
## Серверные API
|
||
|
||
### GET /svgeditor
|
||
Отдаёт `public/svgeditor.html`
|
||
|
||
### POST /api/svg-optimize
|
||
Очистка SVG: удаление комментариев, XML declaration, metadata, пустых групп, data-* атрибутов, округление чисел до 2 знаков, минификация пробелов.
|
||
- Вход: `{ svg: string }`
|
||
- Выход: `{ svg: string, saved: number }` (процент экономии)
|
||
|
||
### POST /api/svg-ai
|
||
Генерация SVG-иконки по ключевому слову.
|
||
- Вход: `{ keyword, style, size, color }`
|
||
- Выход: `{ svg: string, keyword: string }`
|
||
|
||
---
|
||
|
||
## Новый холст (Ctrl+N)
|
||
|
||
Модальное окно с настройками:
|
||
- Ширина / Высота (100-4000 px)
|
||
- Пресеты: 1920×1080, 1080×1080, 800×600, 512×512, 24×24, 48×48
|
||
|
||
---
|
||
|
||
## Технические детали
|
||
|
||
- Единый HTML-файл (2099 строк), все CSS/JS inline
|
||
- SVG DOM manipulation (не Canvas)
|
||
- Шрифты: JetBrains Mono + Manrope (из /vendor/fonts.css)
|
||
- Нет внешних зависимостей кроме vendor-файлов
|
||
- IIFE-обёртка для изоляции переменных
|
||
- `requestAnimationFrame` для корректного позиционирования хэндлов
|
||
- `getScreenCTM()` / `getBoundingClientRect()` для визуальных координат с учётом transform
|