feat(photos): добавить пресеты кривой и починить переключение фото
- PCHIP для предпросмотра и серверного рендера - пресеты всех каналов в профиле, импорт и экспорт - мерж настроек auth без потери разделов - сохранение вкладки и правок текущего фото при переключении
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# Proposal
|
||||
|
||||
## Why
|
||||
|
||||
Тоновая кривая сейчас ведёт себя не как инструмент из Lightroom: крайние узлы не
|
||||
существуют до первых кликов, линия строится по прямым сегментам, а готовых
|
||||
пресетов контраста и пользовательских пресетов нет. Пользователь не может быстро
|
||||
применить типовой контраст или сохранить свою кривую. Дополнительно
|
||||
`PATCH /auth/me/preferences` заменяет весь объект настроек, поэтому хранение
|
||||
пресетов в профиле без мержа затирало бы другие разделы.
|
||||
|
||||
## What Changes
|
||||
|
||||
- **Кривая.** Крайние узлы `(0,0)` и `(1,1)` существуют сразу и являются обычными
|
||||
точками; первый клик добавляет точку между ними. Крайние узлы двигаются по x и
|
||||
y, вне них кривая постоянна («полки», как на скрине). Линия и рендер используют
|
||||
плавную монотонную кубическую интерполяцию (PCHIP): SVG-путь и LUT в Go/TS.
|
||||
«Сбросить» возвращает линейную кривую.
|
||||
- **Встроенные пресеты.** `Линейный`, `Средний контраст`, `Сильный контраст` —
|
||||
каждый описывает все четыре канала: контраст задаётся кривой RGB, каналы
|
||||
R/G/B остаются линейными. Подпись показывает активный пресет; при ручной
|
||||
правке любого канала — `Пользовательский`.
|
||||
- **Пользовательские пресеты.** Пресет описывает кривые всех каналов
|
||||
(`name`, `channels: { rgb, red, green, blue }`). Сохранение текущих кривых
|
||||
всех каналов, применение заменяет все четыре кривые, переименование и
|
||||
удаление. Хранение в `users.preferences.curve_presets` (профиль пользователя),
|
||||
приватно для пользователя.
|
||||
- **Мерж настроек.** `PATCH /auth/me/preferences` принимает `photo_info` и
|
||||
`curve_presets` по отдельности, мержит переданные разделы с сохранёнными,
|
||||
валидирует и возвращает полный merged-объект. Сохранение «Сведений» больше не
|
||||
затирает пресеты, и наоборот.
|
||||
- **Импорт/экспорт.** JSON-файл `{ version: 1, presets: [...] }`: экспорт
|
||||
пользовательских пресетов, импорт с добавлением в профиль (при совпадении имени
|
||||
— перезапись).
|
||||
- **Совместимость.** Миграций схемы нет: пресеты лежат в JSON-блобе
|
||||
`preferences`. Старые пресеты формата `{ channel, points }` конвертируются в
|
||||
четыре канала при чтении и перезаписываются при следующем сохранении.
|
||||
Существующие сохранённые кривые начнут интерполироваться плавно, поэтому их
|
||||
визуальный результат может немного измениться.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
Нет — поведение входит в существующие способности `photos` и `auth`.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `photos`: добавляются требования «Тоновая кривая» (крайние узлы, плавная
|
||||
интерполяция, встроенные пресеты, сброс) и «Пользовательские пресеты кривой»
|
||||
(пресет из четырёх каналов, сохранение/применение/переименование/удаление,
|
||||
импорт/экспорт).
|
||||
- `auth`: требование «Хранение пользовательских настроек интерфейса»
|
||||
расширяется мержем разделов и хранением пользовательских пресетов кривой;
|
||||
добавляется сценарий «сохранение одного раздела не затирает другие».
|
||||
|
||||
## Impact
|
||||
|
||||
- `backend/internal/auth/handlers.go` — `preferencesPayload` с `curve_presets`,
|
||||
мерж разделов, валидация имени и кривых всех четырёх каналов.
|
||||
- `backend/internal/auth/store.go` / `sqlite_store.go` — без изменений схемы;
|
||||
запись merged-JSON через существующий `UpdatePreferences`.
|
||||
- `backend/internal/photos/edit.go` — `curveEval`/`curveLUT` переходят на PCHIP;
|
||||
тесты Go на гладкость/LUT.
|
||||
- `frontend/src/lib/edit.ts` — PCHIP в `buildCurveLUT`, типы и нормализация
|
||||
пресетов, точки кривой.
|
||||
- `frontend/src/lib/components/PhotoEditPanel.svelte` — узлы-углы, плавный SVG-путь,
|
||||
меню пресетов, сохранение/переименование/удаление, импорт/экспорт.
|
||||
- `frontend/src/lib/types.ts`, `stores/auth.svelte.ts`, `api.ts` — тип
|
||||
`Preferences.curve_presets`, сохранение через существующий endpoint.
|
||||
- Новые вспомогательные модули: меню/диалоги пресетов, импорт/экспорт JSON.
|
||||
- Тесты: `edit_test.go`, `edit.test.ts`, тесты мержа/валидации preferences,
|
||||
e2e сохранения пресетов в профиле.
|
||||
Reference in New Issue
Block a user