mirror of
				https://github.com/KevinMidboe/immich.git
				synced 2025-10-29 17:40:28 +00:00 
			
		
		
		
	feat(web): load original image when zooming (#4040)
* feat(web): change max zoom from 4 to 10 * feat(web): load original image when zooming
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							52d0c5fc73
						
					
				
				
					commit
					bf3b38a7f2
				
			| @@ -6,12 +6,14 @@ | ||||
|   import { notificationController, NotificationType } from '../shared-components/notification/notification'; | ||||
|   import { useZoomImageWheel } from '@zoom-image/svelte'; | ||||
|   import { photoZoomState } from '$lib/stores/zoom-image.store'; | ||||
|   import { isWebCompatibleImage } from '$lib/utils/asset-utils'; | ||||
|  | ||||
|   export let asset: AssetResponseDto; | ||||
|   export let element: HTMLDivElement | undefined = undefined; | ||||
|  | ||||
|   let imgElement: HTMLDivElement; | ||||
|   let assetData: string; | ||||
|   let hasZoomed = false; | ||||
|   let copyImageToClipboard: (src: string) => Promise<Blob>; | ||||
|   let canCopyImagesToClipboard: () => boolean; | ||||
|  | ||||
| @@ -23,10 +25,10 @@ | ||||
|     canCopyImagesToClipboard = module.canCopyImagesToClipboard; | ||||
|   }); | ||||
|  | ||||
|   const loadAssetData = async () => { | ||||
|   const loadAssetData = async ({ loadOriginal }: { loadOriginal: boolean }) => { | ||||
|     try { | ||||
|       const { data } = await api.assetApi.serveFile( | ||||
|         { id: asset.id, isThumb: false, isWeb: true, key: api.getKey() }, | ||||
|         { id: asset.id, isThumb: false, isWeb: !loadOriginal, key: api.getKey() }, | ||||
|         { | ||||
|           responseType: 'blob', | ||||
|         }, | ||||
| @@ -37,7 +39,6 @@ | ||||
|       } | ||||
|  | ||||
|       assetData = URL.createObjectURL(data); | ||||
|       return assetData; | ||||
|     } catch { | ||||
|       // Do nothing | ||||
|     } | ||||
| @@ -87,10 +88,16 @@ | ||||
|  | ||||
|   zoomImageWheelState.subscribe((state) => { | ||||
|     photoZoomState.set(state); | ||||
|  | ||||
|     if (state.currentZoom > 1 && isWebCompatibleImage(asset) && !hasZoomed) { | ||||
|       hasZoomed = true; | ||||
|       loadAssetData({ loadOriginal: true }); | ||||
|     } | ||||
|   }); | ||||
|  | ||||
|   $: if (imgElement) { | ||||
|     createZoomImageWheel(imgElement, { | ||||
|       maxZoom: 10, | ||||
|       wheelZoomRatio: 0.2, | ||||
|     }); | ||||
|   } | ||||
| @@ -103,9 +110,9 @@ | ||||
|   transition:fade={{ duration: 150 }} | ||||
|   class="flex h-full select-none place-content-center place-items-center" | ||||
| > | ||||
|   {#await loadAssetData()} | ||||
|   {#await loadAssetData({ loadOriginal: false })} | ||||
|     <LoadingSpinner /> | ||||
|   {:then assetData} | ||||
|   {:then} | ||||
|     <div bind:this={imgElement} class="h-full w-full"> | ||||
|       <img | ||||
|         transition:fade={{ duration: 150 }} | ||||
|   | ||||
| @@ -173,3 +173,15 @@ export function getAssetRatio(asset: AssetResponseDto) { | ||||
|   } | ||||
|   return { width, height }; | ||||
| } | ||||
|  | ||||
| // list of supported image extensions from https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types excluding svg | ||||
| const supportedImageExtensions = new Set(['apng', 'avif', 'gif', 'jpg', 'jpeg', 'jfif', 'pjpeg', 'pjp', 'png', 'webp']); | ||||
|  | ||||
| /** | ||||
|  * Returns true if the asset is an image supported by web browsers, false otherwise | ||||
|  */ | ||||
| export function isWebCompatibleImage(asset: AssetResponseDto): boolean { | ||||
|   const imgExtension = getFilenameExtension(asset.originalPath); | ||||
|  | ||||
|   return supportedImageExtensions.has(imgExtension); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user