mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-09-14 13:36:36 +00:00
9.1 KiB
9.1 KiB
План: раскладка «исходник слева — результат справа» + вставка изображения
СТАТУС: ВЫПОЛНЕН 2026-08-22.
Что сделано по этапам:
- A — общая MIME-валидация
isSupportedImage+unsupportedImageMessageвcore/io.ts;DropZoneпереведён на них ✔- B — постоянная двухпанельная раскладка: одна карточка-«сцена» с равными половинами «Исходник | Результат», кнопки внутри своих половин, параметры — отдельной карточкой ниже; контент сайта растянут на всю ширину окна ✔
- C — Ctrl+V:
<svelte:window onpaste>, поиск image-item в буфере, общая валидация; текстовые вставки не затрагиваются ✔- D — drag-замена: компонент
DropOverlayс вуалью-подсказкой и счётчикомdragenter/dragleaveпротив мерцания; тот же счётчик вDropZone✔- E — верификация: тесты 85/85, svelte-check 0 ошибок, статический билд с 11 страницами; ручной смоук-чеклист §5 пройден ✔
Отступления от исходного плана в ходе реализации: вместо пропа
overlayуDropZoneсделан отдельный компонент-обёрткаDropOverlay(drag-события ловит контент под курсором); раскладка доработана по ревью — одна карточка равных половин вместо двух независимых колонок, сайт без ограничения ширины.
1. Целевое поведение
- Постоянная двухпанельная раскладка страницы инструмента — отдельного состояния «страница загрузки» больше нет:
- Слева — исходник, панель есть всегда. Не загружено → пустое дроп-поле (drag&drop или клик). Загружено → превью исходника.
- Справа — результат: до загрузки —
EmptyState«Результат появится здесь»; во время обработки —EmptyState«Обработка…»; после — превью результата (для info-инструмента —InfoPanel).
- Ctrl+V — картинка из буфера обмена вставляется как исходник с любого места страницы.
- Замена перетаскиванием — новый файл, брошенный на левую панель с загруженной картинкой, заменяет исходник (с оверлеем-подсказкой во время перетаскивания).
- Кнопка «Заменить» под превью исходника (переносится туда текущая «Загрузить другое изображение»).
На мобильной ширине панели складываются в столбец: исходник сверху, результат снизу.
2. Изменения по файлам
Новые компоненты не вводим — EmptyState, Preview, DropZone покрывают всё. Меняем три файла:
core/io.ts— экспортisSupportedImage(file): boolean: общая MIME-проверка на базеACCEPTED_IMAGE_TYPES.DropZone.svelte— переходит наisSupportedImage; новый опциональный пропoverlay— режим «невидимая зона приёма поверх контента» для замены перетаскиванием.ToolPage.svelte— постоянная сетка из двух панелей;<svelte:window onpaste>; drag-оверлей левой панели; кнопки замены/сброса переезжают в левую панель; правая панель — три состояния черезEmptyState.
3. Этапы и проверки
- A. Общая валидация —
isSupportedImageвio.ts,DropZoneпереведён на неё. Проверка:pnpm check. - B. Раскладка — две постоянные колонки в ToolPage; правая панель через EmptyState; кнопки уходят в левую панель; обёртка
{#if !source}на всю страницу убирается. Проверка: визуальный осмотр всех инструментов,check/build. - C. Ctrl+V —
onpasteна окне → поиск image-item вclipboardData→ тот жеhandleFile; не-изображения игнорируются молча. Проверка: ручной смоук со скриншотом из буфера. - D. Drag-замена — оверлей DropZone(overlay) при dragover на левой панели; drop →
handleFileнового файла. Проверка: ручной смоук «бросить файл на загруженный исходник». - E. Итог — полный ручной смоук-чеклист (§5). Проверка:
test/check/buildзелёные.
4. Нюансы и решения
- Мерцание dragleave — классическая проблема оверлеев: используем счётчик
dragenter/dragleave, оверлей скрывается только когда счётчик обнулился и произошёлdrop/dragend. - Paste при фокусе в поле параметров — обрабатываем всегда: если в буфере именно изображение, пользователь очевидно хочет заменить исходник; текстовые вставки обработчик не трогает.
- Форматы буфера — скриншоты приходят как PNG, часть приложений отдаёт JPEG/WebP; все проходят общую
isSupportedImage. GIF/BMP из буфера редки, но тоже допустимы. - Info-инструменты — ведут себя так же: слева исходник, справа после загрузки появляется
InfoPanel. - Состояние ошибки — баннер остаётся сверху страницы; неудачная замена не сбрасывает старый исходник.
5. Чеклист ручного смоука
- Пустые обе панели → drag&drop файла слева → появился исходник и результат.
- Клик по пустой левой панели → выбор файла.
- Ctrl+V со скриншотом → исходник заменился, результат пересчитался.
- Drag файла на загруженную левую панель → оверлей виден, после drop — замена.
- Отмена перетаскивания (Esc / мимо) → оверлей скрылся, исходник не изменился.
- Бросок неподдерживаемого файла (например .txt) → баннер ошибки, старый исходник цел.
- Кнопка «Заменить» открывает выбор файла.
- png-info: работает та же схема, справа сводка.
- Мобильная ширина: панели в столбец, порядок исходник → результат.
- Все 11 инструментов отвечают на замену исходника корректным пересчётом.
6. Критерии готовности
- На странице инструмента нет состояния «только дропзона на всю страницу» — раскладка двухпанельная всегда.
- Загрузка работает тремя способами: клик, drag&drop (включая замену), Ctrl+V.
- Ошибочные файлы и отмена перетаскивания не портят текущий исходник.
test/check/buildзелёные; чеклист §5 пройден.
7. Что сознательно не делаем (граница скоупа этого плана)
- Множественная загрузка / пакетная обработка — вне скоупа этого плана.
- Камера/скриншот-инструменты захвата — только буфер обмена.
- Прогресс-бары декодирования — файлы читаются быстро, достаточно индикации «Обработка…».