|
2 | 2 | import { shortcuts } from '$lib/actions/shortcut'; |
3 | 3 | import { zoomImageAction } from '$lib/actions/zoom-image'; |
4 | 4 | import FaceEditor from '$lib/components/asset-viewer/face-editor/face-editor.svelte'; |
| 5 | + import OcrBoundingBox from '$lib/components/asset-viewer/ocr-bounding-box.svelte'; |
5 | 6 | import BrokenAsset from '$lib/components/assets/broken-asset.svelte'; |
6 | 7 | import { assetViewerFadeDuration } from '$lib/constants'; |
7 | 8 | import { castManager } from '$lib/managers/cast-manager.svelte'; |
8 | 9 | import type { TimelineAsset } from '$lib/managers/timeline-manager/types'; |
9 | 10 | import { photoViewerImgElement } from '$lib/stores/assets-store.svelte'; |
10 | 11 | import { isFaceEditMode } from '$lib/stores/face-edit.svelte'; |
| 12 | + import { ocrStore } from '$lib/stores/ocr.svelte'; |
11 | 13 | import { boundingBoxesArray } from '$lib/stores/people.store'; |
12 | | - import { ocrDataArray, showOcrOverlay } from '$lib/stores/ocr.store'; |
13 | 14 | import { alwaysLoadOriginalFile } from '$lib/stores/preferences.store'; |
14 | 15 | import { SlideshowLook, SlideshowState, slideshowLookCssMapping, slideshowStore } from '$lib/stores/slideshow.store'; |
15 | 16 | import { photoZoomState } from '$lib/stores/zoom-image.store'; |
16 | 17 | import { getAssetOriginalUrl, getAssetThumbnailUrl, handlePromiseError } from '$lib/utils'; |
17 | 18 | import { canCopyImageToClipboard, copyImageToClipboard, isWebCompatibleImage } from '$lib/utils/asset-utils'; |
18 | 19 | import { handleError } from '$lib/utils/handle-error'; |
19 | | - import { getBoundingBox } from '$lib/utils/people-utils'; |
20 | 20 | import { getOcrBoundingBoxes } from '$lib/utils/ocr-utils'; |
| 21 | + import { getBoundingBox } from '$lib/utils/people-utils'; |
21 | 22 | import { cancelImageUrl } from '$lib/utils/sw-messaging'; |
22 | 23 | import { getAltText } from '$lib/utils/thumbnail-util'; |
23 | 24 | import { toTimelineAsset } from '$lib/utils/timeline-util'; |
|
74 | 75 | }); |
75 | 76 |
|
76 | 77 | let ocrBoxes = $derived( |
77 | | - $showOcrOverlay && $photoViewerImgElement |
78 | | - ? getOcrBoundingBoxes($ocrDataArray, $photoZoomState, $photoViewerImgElement) |
79 | | - : [] |
| 78 | + ocrStore.showOverlay && $photoViewerImgElement |
| 79 | + ? getOcrBoundingBoxes(ocrStore.data, $photoZoomState, $photoViewerImgElement) |
| 80 | + : [], |
80 | 81 | ); |
81 | 82 |
|
| 83 | + let isOcrActive = $derived(ocrStore.showOverlay); |
| 84 | +
|
82 | 85 | const preload = (targetSize: AssetMediaSize | 'original', preloadAssets?: TimelineAsset[]) => { |
83 | 86 | for (const preloadAsset of preloadAssets || []) { |
84 | 87 | if (preloadAsset.isImage) { |
|
138 | 141 | if ($photoZoomState.currentZoom > 1) { |
139 | 142 | return; |
140 | 143 | } |
| 144 | +
|
| 145 | + if (ocrStore.showOverlay) { |
| 146 | + return; |
| 147 | + } |
| 148 | +
|
141 | 149 | if (onNextAsset && event.detail.direction === 'left') { |
142 | 150 | onNextAsset(); |
143 | 151 | } |
| 152 | +
|
144 | 153 | if (onPreviousAsset && event.detail.direction === 'right') { |
145 | 154 | onPreviousAsset(); |
146 | 155 | } |
|
240 | 249 | </div> |
241 | 250 | {:else if !imageError} |
242 | 251 | <div |
243 | | - use:zoomImageAction |
| 252 | + use:zoomImageAction={{ disabled: isOcrActive }} |
244 | 253 | {...useSwipe(onSwipe)} |
245 | 254 | class="h-full w-full" |
246 | 255 | transition:fade={{ duration: haveFadeTransition ? assetViewerFadeDuration : 0 }} |
|
269 | 278 | style="top: {boundingbox.top}px; left: {boundingbox.left}px; height: {boundingbox.height}px; width: {boundingbox.width}px;" |
270 | 279 | ></div> |
271 | 280 | {/each} |
272 | | - <!-- OCR bounding boxes --> |
273 | | - {#if $showOcrOverlay && ocrBoxes.length > 0} |
274 | | - <svg class="absolute top-0 left-0 w-full h-full pointer-events-none" style="overflow: visible;"> |
275 | | - {#each ocrBoxes as ocrBox (ocrBox.id)} |
276 | | - {@const points = ocrBox.points} |
277 | | - {@const pathData = `M ${points[0].x} ${points[0].y} L ${points[1].x} ${points[1].y} L ${points[2].x} ${points[2].y} L ${points[3].x} ${points[3].y} Z`} |
278 | | - <path |
279 | | - d={pathData} |
280 | | - fill="rgba(59, 130, 246, 0.2)" |
281 | | - stroke="rgb(59, 130, 246)" |
282 | | - stroke-width="2" |
283 | | - /> |
284 | | - {/each} |
285 | | - </svg> |
| 281 | + |
| 282 | + {#if ocrStore.showOverlay} |
286 | 283 | {#each ocrBoxes as ocrBox (ocrBox.id)} |
287 | | - {@const points = ocrBox.points} |
288 | | - {@const centerX = (points[0].x + points[1].x + points[2].x + points[3].x) / 4} |
289 | | - {@const centerY = (points[0].y + points[1].y + points[2].y + points[3].y) / 4} |
290 | | - <div |
291 | | - class="absolute pointer-events-none text-white text-sm font-semibold px-2 py-1 rounded shadow-lg" |
292 | | - style="left: {centerX}px; top: {centerY}px; transform: translate(-50%, -50%); background-color: rgba(59, 130, 246, 0.9); max-width: 200px; word-break: break-word;" |
293 | | - > |
294 | | - {ocrBox.text} |
295 | | - </div> |
| 284 | + <OcrBoundingBox {ocrBox} /> |
296 | 285 | {/each} |
297 | 286 | {/if} |
298 | 287 | </div> |
|
0 commit comments