fix(web): face editor respects detail panel bounds and preserves position on resize

This commit is contained in:
midzelis
2026-03-07 19:06:14 +00:00
parent 824be9f228
commit 82be0c1181
2 changed files with 44 additions and 15 deletions

View File

@@ -487,8 +487,6 @@
class="fixed start-0 top-0 grid size-full grid-cols-4 grid-rows-[64px_1fr] overflow-hidden bg-black"
use:focusTrap
bind:this={assetViewerHtmlElement}
bind:clientWidth={containerWidth}
bind:clientHeight={containerHeight}
>
<!-- Top navigation bar -->
{#if $slideshowState === SlideshowState.None && !assetViewerManager.isShowEditor}
@@ -530,7 +528,12 @@
{/if}
<!-- Asset Viewer -->
<div data-viewer-content class="z-[-1] relative col-start-1 col-span-4 row-start-1 row-span-full">
<div
data-viewer-content
class="z-[-1] relative col-start-1 col-span-4 row-start-1 row-span-full"
bind:clientWidth={containerWidth}
bind:clientHeight={containerHeight}
>
{#if viewerKind === 'StackVideoViewer'}
<VideoViewer
asset={previewStackedAsset!}

View File

@@ -31,6 +31,10 @@
let searchTerm = $state('');
let faceBoxPosition = $state({ left: 0, top: 0, width: 0, height: 0 });
let initialized = false;
let previousContentWidth = 0;
let previousOffsetX = 0;
let previousOffsetY = 0;
let filteredCandidates = $derived(
searchTerm
@@ -94,27 +98,49 @@
});
$effect(() => {
const { offsetX, offsetY } = imageContentMetrics;
const { offsetX, offsetY, contentWidth } = imageContentMetrics;
if (!canvas) {
if (!canvas || contentWidth === 0) {
return;
}
canvas.setDimensions({
width: containerWidth,
height: containerHeight,
});
if (!initialized) {
initialized = true;
canvas.setDimensions({ width: containerWidth, height: containerHeight });
if (!faceRect) {
if (faceRect) {
faceRect.set({ top: offsetY + 200, left: offsetX + 200 });
faceRect.setCoords();
}
previousContentWidth = contentWidth;
previousOffsetX = offsetX;
previousOffsetY = offsetY;
positionFaceSelector();
return;
}
faceRect.set({
top: offsetY + 200,
left: offsetX + 200,
});
canvas.setDimensions({ width: containerWidth, height: containerHeight });
faceRect.setCoords();
if (faceRect && previousContentWidth > 0) {
const scale = contentWidth / previousContentWidth;
const imageRelLeft = (faceRect.left - previousOffsetX) * scale;
const imageRelTop = (faceRect.top - previousOffsetY) * scale;
faceRect.set({
left: offsetX + imageRelLeft,
top: offsetY + imageRelTop,
scaleX: faceRect.scaleX * scale,
scaleY: faceRect.scaleY * scale,
});
faceRect.setCoords();
}
previousContentWidth = contentWidth;
previousOffsetX = offsetX;
previousOffsetY = offsetY;
canvas.renderAll();
positionFaceSelector();
});