feat(web): вкладка «Редактирование» с инструментом «Свет»

В правой панели фото появилась вкладка «Редактирование» с инструментом «Свет»:
ползунки экспозиции, контраста, светов, теней, белых и чёрных и точечная кривая
с выбором канала. Правки сохраняются автоматически, переключатель «Сброс»
удаляет параметры правок и отредактированную версию фото.

Редактирование неразрушающее: параметры хранятся в метаданных фото, а
отредактированная версия рендерится в фоне отдельным объектом (edit, edit_thumb,
edit_medium, edit_preview) рядом с исходными вариантами. Оригинал не меняется,
скачивание отдаёт исходный файл. Сетка, просмотр и обложки альбомов показывают
отредактированную версию, когда она отрендерена.
This commit is contained in:
iu
2026-10-20 23:06:24 +03:00
parent afaaaab5f0
commit 0548b1ab5e
32 changed files with 1954 additions and 24 deletions
+10 -5
View File
@@ -1,6 +1,7 @@
<script lang="ts">
import Icon from './Icon.svelte';
import { grid } from '$lib/stores/grid.svelte';
import { photoMediumUrl, photoPreviewUrl, photoThumbUrl } from '$lib/edit';
import { isPanoTag } from '$lib/pano';
import type { Photo } from '$lib/types';
@@ -38,11 +39,15 @@
// Offer every variant the photo actually has; the backend generates the
// medium variant asynchronously, so an incomplete set must still render.
// When the photo is edited, the edited variants are shown.
function srcsetFor(photo: Photo): string {
const parts: string[] = [];
if (photo.thumb_url) parts.push(`${photo.thumb_url} 200w`);
if (photo.medium_url) parts.push(`${photo.medium_url} 800w`);
if (photo.preview_url) parts.push(`${photo.preview_url} 1200w`);
const thumb = photoThumbUrl(photo);
const medium = photoMediumUrl(photo);
const preview = photoPreviewUrl(photo);
if (thumb) parts.push(`${thumb} 200w`);
if (medium) parts.push(`${medium} 800w`);
if (preview) parts.push(`${preview} 1200w`);
return parts.join(', ');
}
@@ -106,9 +111,9 @@
ondragstart={(e) => onDragStart?.(i, e)}
oncontextmenu={(e) => onContextMenu?.(i, e)}
>
{#if photo.thumb_url}
{#if photoThumbUrl(photo)}
<img
src={photo.thumb_url}
src={photoThumbUrl(photo)}
srcset={srcsetFor(photo)}
{sizes}
alt={photo.original_filename}