From a29dc703b630d01ef41cc253003b9bf9d0ec682a Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Wed, 3 Jun 2026 03:55:18 +0000 Subject: [PATCH] refactor(web): expose scaled image dimensions from AdaptiveImage Change-Id: Iae105fb749525739ba8df5b944a73ea66a6a6964 --- web/src/lib/components/AdaptiveImage.svelte | 22 +++++++++++++++++-- .../asset-viewer/PhotoViewer.svelte | 11 ++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/web/src/lib/components/AdaptiveImage.svelte b/web/src/lib/components/AdaptiveImage.svelte index 04136c721c3f0..3ecb68c346a26 100644 --- a/web/src/lib/components/AdaptiveImage.svelte +++ b/web/src/lib/components/AdaptiveImage.svelte @@ -74,6 +74,8 @@ onError?: () => void; ref?: HTMLDivElement; imgRef?: HTMLImageElement; + imgNaturalSize?: Size; + imgScaledSize?: Size; backdrop?: Snippet; overlays?: Snippet; }; @@ -82,6 +84,10 @@ ref = $bindable(), // eslint-disable-next-line no-useless-assignment imgRef = $bindable(), + // eslint-disable-next-line no-useless-assignment + imgNaturalSize = $bindable(), + // eslint-disable-next-line no-useless-assignment + imgScaledSize = $bindable(), asset, sharedLink, objectFit = 'contain', @@ -149,10 +155,22 @@ return { width: 1, height: 1 }; }); + $effect(() => { + imgNaturalSize = imageDimensions; + }); + + const scaledDimensions = $derived.by(() => { + const scaleFn = objectFit === 'cover' ? scaleToCover : scaleToFit; + return scaleFn(imageDimensions, container); + }); + + $effect(() => { + imgScaledSize = scaledDimensions; + }); + const { insetInlineStart, top, displayWidth, displayHeight, rasterWidth, rasterHeight, rasterScale } = $derived.by( () => { - const scaleFn = objectFit === 'cover' ? scaleToCover : scaleToFit; - const { width, height } = scaleFn(imageDimensions, container); + const { width, height } = scaledDimensions; if (maxRasterPixels === 0) { return { insetInlineStart: (container.width - width) / 2 + 'px', diff --git a/web/src/lib/components/asset-viewer/PhotoViewer.svelte b/web/src/lib/components/asset-viewer/PhotoViewer.svelte index 37844a5459a1d..fac8bfb47bbcc 100644 --- a/web/src/lib/components/asset-viewer/PhotoViewer.svelte +++ b/web/src/lib/components/asset-viewer/PhotoViewer.svelte @@ -13,7 +13,7 @@ import { SlideshowLook, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store'; import { handlePromiseError } from '$lib/utils'; import { canCopyImageToClipboard, copyImageToClipboard } from '$lib/utils/asset-utils'; - import { getNaturalSize, scaleToFit, type Size } from '$lib/utils/container-utils'; + import type { Size } from '$lib/utils/container-utils'; import { handleError } from '$lib/utils/handle-error'; import { getOcrBoundingBoxes } from '$lib/utils/ocr-utils'; import { getBoundingBox, type BoundingBox } from '$lib/utils/people-utils'; @@ -67,13 +67,9 @@ height: containerHeight, }); - const overlaySize = $derived.by((): Size => { - if (!assetViewerManager.imgRef || !visibleImageReady) { - return { width: 0, height: 0 }; - } + let scaledDimensions = $state({ width: 0, height: 0 }); - return scaleToFit(getNaturalSize(assetViewerManager.imgRef), { width: containerWidth, height: containerHeight }); - }); + const overlaySize = $derived(visibleImageReady ? scaledDimensions : { width: 0, height: 0 }); const highlightedBoxes = $derived(getBoundingBox(assetViewerManager.highlightedFaces, overlaySize)); const isHighlighting = $derived(highlightedBoxes.length > 0); @@ -235,6 +231,7 @@ onReady?.(); }} bind:imgRef={assetViewerManager.imgRef} + bind:imgScaledSize={scaledDimensions} bind:ref={adaptiveImage} > {#snippet backdrop()}