Prechádzať zdrojové kódy

feat(web): add zoom to photo viewer (#2577)

* feat(web): add zoom to photo viewer

* reduce asset viewer next/prev button div width

* add wrap to block statement
Manuel Taberna 2 rokov pred
rodič
commit
e7122d7a72

+ 38 - 0
web/package-lock.json

@@ -8,6 +8,7 @@
 			"name": "immich-web",
 			"version": "1.0.0",
 			"dependencies": {
+				"@zoom-image/svelte": "^0.1.0",
 				"axios": "^0.27.2",
 				"copy-image-clipboard": "^2.1.2",
 				"handlebars": "^4.7.7",
@@ -4030,6 +4031,30 @@
 				"url": "https://opencollective.com/typescript-eslint"
 			}
 		},
+		"node_modules/@zoom-image/core": {
+			"version": "0.14.0",
+			"resolved": "https://registry.npmjs.org/@zoom-image/core/-/core-0.14.0.tgz",
+			"integrity": "sha512-uNHjWzGtsif2MnbuYlGe+TAyHeHqPAJIJ09/gTRH/9DcEYiO7z1bLisVYtSXu2KDTbbtGYM5UnTKdLMmuDng3w==",
+			"funding": {
+				"type": "github",
+				"url": "https://github.com/sponsors/willnguyen1312"
+			}
+		},
+		"node_modules/@zoom-image/svelte": {
+			"version": "0.1.0",
+			"resolved": "https://registry.npmjs.org/@zoom-image/svelte/-/svelte-0.1.0.tgz",
+			"integrity": "sha512-HGB9ZBsaEMplHiZZ8r/mkrHAumun9caeVamNgX0v17hI7a71C3dXKuKrwAiIOllDYKihm1e5RYUCc2C7UKFtsg==",
+			"dependencies": {
+				"@zoom-image/core": "0.14.0"
+			},
+			"funding": {
+				"type": "github",
+				"url": "https://github.com/sponsors/willnguyen1312"
+			},
+			"peerDependencies": {
+				"svelte": "^3.0.0"
+			}
+		},
 		"node_modules/abab": {
 			"version": "2.0.6",
 			"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -14451,6 +14476,19 @@
 				"eslint-visitor-keys": "^3.3.0"
 			}
 		},
+		"@zoom-image/core": {
+			"version": "0.14.0",
+			"resolved": "https://registry.npmjs.org/@zoom-image/core/-/core-0.14.0.tgz",
+			"integrity": "sha512-uNHjWzGtsif2MnbuYlGe+TAyHeHqPAJIJ09/gTRH/9DcEYiO7z1bLisVYtSXu2KDTbbtGYM5UnTKdLMmuDng3w=="
+		},
+		"@zoom-image/svelte": {
+			"version": "0.1.0",
+			"resolved": "https://registry.npmjs.org/@zoom-image/svelte/-/svelte-0.1.0.tgz",
+			"integrity": "sha512-HGB9ZBsaEMplHiZZ8r/mkrHAumun9caeVamNgX0v17hI7a71C3dXKuKrwAiIOllDYKihm1e5RYUCc2C7UKFtsg==",
+			"requires": {
+				"@zoom-image/core": "0.14.0"
+			}
+		},
 		"abab": {
 			"version": "2.0.6",
 			"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",

+ 1 - 0
web/package.json

@@ -57,6 +57,7 @@
 	},
 	"type": "module",
 	"dependencies": {
+		"@zoom-image/svelte": "^0.1.0",
 		"axios": "^0.27.2",
 		"copy-image-clipboard": "^2.1.2",
 		"handlebars": "^4.7.7",

+ 2 - 2
web/src/lib/components/asset-viewer/asset-viewer.svelte

@@ -325,7 +325,7 @@
 
 	{#if showNavigation}
 		<div
-			class={`row-start-2 row-span-end col-start-1 col-span-2 flex place-items-center hover:cursor-pointer w-3/4 mb-[60px] ${
+			class={`row-start-2 row-span-end col-start-1 flex place-items-center hover:cursor-pointer w-1/4 mb-[60px] ${
 				asset.type === AssetTypeEnum.Video ? '' : 'z-[999]'
 			}`}
 			on:mouseenter={() => {
@@ -377,7 +377,7 @@
 
 	{#if showNavigation}
 		<div
-			class={`row-start-2 row-span-full col-start-3 col-span-2 flex justify-end place-items-center hover:cursor-pointer w-3/4 justify-self-end mb-[60px] ${
+			class={`row-start-2 row-span-full col-start-4 flex justify-end place-items-center hover:cursor-pointer w-1/4 justify-self-end mb-[60px] ${
 				asset.type === AssetTypeEnum.Video ? '' : 'z-[500]'
 			}`}
 			on:click={navigateAssetForward}

+ 18 - 7
web/src/lib/components/asset-viewer/photo-viewer.svelte

@@ -7,9 +7,11 @@
 		notificationController,
 		NotificationType
 	} from '../shared-components/notification/notification';
+	import { useZoomImageWheel } from '@zoom-image/svelte';
 
 	export let asset: AssetResponseDto;
 	export let publicSharedKey = '';
+	let imgElement: HTMLDivElement;
 
 	let assetData: string;
 
@@ -70,6 +72,13 @@
 			});
 		}
 	};
+
+	const { createZoomImage: createZoomImageWheel } = useZoomImageWheel();
+	$: if (imgElement) {
+		createZoomImageWheel(imgElement, {
+			wheelZoomRatio: 0.06
+		});
+	}
 </script>
 
 <svelte:window on:keydown={handleKeypress} on:copyImage={doCopy} />
@@ -81,12 +90,14 @@
 	{#await loadAssetData()}
 		<LoadingSpinner />
 	{:then assetData}
-		<img
-			transition:fade={{ duration: 150 }}
-			src={assetData}
-			alt={asset.id}
-			class="object-contain h-full transition-all"
-			draggable="false"
-		/>
+		<div bind:this={imgElement} class="h-full w-full">
+			<img
+				transition:fade={{ duration: 150 }}
+				src={assetData}
+				alt={asset.id}
+				class="object-contain h-full w-full"
+				draggable="false"
+			/>
+		</div>
 	{/await}
 </div>