mirror of
https://github.com/immich-app/immich.git
synced 2025-07-07 18:24:10 -04:00
fix(web): Improve zoom behavior in photo-viewer. (#18803)
* Fix an issue where clicking the zoom-button after having zoomed in would not zoom completely out, but leave the image in the zoomed-in state. The new behavior properly zoomes the image completely out after clicking the zoom-button. * Revert to the default setting for `wheelZoomRatio` as the previous setting of 0.2 was borderline unusable on a trackpad. This could probably be moved to a user setting if needed. * Add a keyboard shortcut 'z' to toggle image zoom.
This commit is contained in:
parent
a53d033622
commit
5589616921
@ -1,15 +1,12 @@
|
|||||||
import { photoZoomState, zoomed } from '$lib/stores/zoom-image.store';
|
import { photoZoomState } from '$lib/stores/zoom-image.store';
|
||||||
import { useZoomImageWheel } from '@zoom-image/svelte';
|
import { useZoomImageWheel } from '@zoom-image/svelte';
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
|
|
||||||
export { zoomed } from '$lib/stores/zoom-image.store';
|
|
||||||
|
|
||||||
export const zoomImageAction = (node: HTMLElement) => {
|
export const zoomImageAction = (node: HTMLElement) => {
|
||||||
const { createZoomImage, zoomImageState, setZoomImageState } = useZoomImageWheel();
|
const { createZoomImage, zoomImageState, setZoomImageState } = useZoomImageWheel();
|
||||||
|
|
||||||
createZoomImage(node, {
|
createZoomImage(node, {
|
||||||
maxZoom: 10,
|
maxZoom: 10,
|
||||||
wheelZoomRatio: 0.2,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const state = get(photoZoomState);
|
const state = get(photoZoomState);
|
||||||
@ -17,10 +14,7 @@ export const zoomImageAction = (node: HTMLElement) => {
|
|||||||
setZoomImageState(state);
|
setZoomImageState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsubscribes = [
|
const unsubscribes = [photoZoomState.subscribe(setZoomImageState), zoomImageState.subscribe(photoZoomState.set)];
|
||||||
zoomed.subscribe((state) => setZoomImageState({ currentZoom: state ? 2 : 1 })),
|
|
||||||
zoomImageState.subscribe((state) => photoZoomState.set(state)),
|
|
||||||
];
|
|
||||||
return {
|
return {
|
||||||
destroy() {
|
destroy() {
|
||||||
for (const unsubscribe of unsubscribes) {
|
for (const unsubscribe of unsubscribes) {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { shortcuts } from '$lib/actions/shortcut';
|
import { shortcuts } from '$lib/actions/shortcut';
|
||||||
import { zoomImageAction, zoomed } from '$lib/actions/zoom-image';
|
import { zoomImageAction } from '$lib/actions/zoom-image';
|
||||||
import FaceEditor from '$lib/components/asset-viewer/face-editor/face-editor.svelte';
|
import FaceEditor from '$lib/components/asset-viewer/face-editor/face-editor.svelte';
|
||||||
import BrokenAsset from '$lib/components/assets/broken-asset.svelte';
|
import BrokenAsset from '$lib/components/assets/broken-asset.svelte';
|
||||||
|
import { castManager } from '$lib/managers/cast-manager.svelte';
|
||||||
import { photoViewerImgElement, type TimelineAsset } from '$lib/stores/assets-store.svelte';
|
import { photoViewerImgElement, type TimelineAsset } from '$lib/stores/assets-store.svelte';
|
||||||
import { isFaceEditMode } from '$lib/stores/face-edit.svelte';
|
import { isFaceEditMode } from '$lib/stores/face-edit.svelte';
|
||||||
import { boundingBoxesArray } from '$lib/stores/people.store';
|
import { boundingBoxesArray } from '$lib/stores/people.store';
|
||||||
@ -23,7 +24,6 @@
|
|||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
|
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
|
||||||
import { NotificationType, notificationController } from '../shared-components/notification/notification';
|
import { NotificationType, notificationController } from '../shared-components/notification/notification';
|
||||||
import { castManager } from '$lib/managers/cast-manager.svelte';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
asset: AssetResponseDto;
|
asset: AssetResponseDto;
|
||||||
@ -65,7 +65,6 @@
|
|||||||
currentPositionX: 0,
|
currentPositionX: 0,
|
||||||
currentPositionY: 0,
|
currentPositionY: 0,
|
||||||
});
|
});
|
||||||
$zoomed = false;
|
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
$boundingBoxesArray = [];
|
$boundingBoxesArray = [];
|
||||||
@ -108,7 +107,10 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
zoomToggle = () => {
|
zoomToggle = () => {
|
||||||
$zoomed = $zoomed ? false : true;
|
photoZoomState.set({
|
||||||
|
...$photoZoomState,
|
||||||
|
currentZoom: $photoZoomState.currentZoom > 1 ? 1 : 2,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
@ -206,6 +208,7 @@
|
|||||||
use:shortcuts={[
|
use:shortcuts={[
|
||||||
{ shortcut: { key: 'c', ctrl: true }, onShortcut: onCopyShortcut, preventDefault: false },
|
{ shortcut: { key: 'c', ctrl: true }, onShortcut: onCopyShortcut, preventDefault: false },
|
||||||
{ shortcut: { key: 'c', meta: true }, onShortcut: onCopyShortcut, preventDefault: false },
|
{ shortcut: { key: 'c', meta: true }, onShortcut: onCopyShortcut, preventDefault: false },
|
||||||
|
{ shortcut: { key: 'z' }, onShortcut: zoomToggle, preventDefault: false },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
{#if imageError}
|
{#if imageError}
|
||||||
|
@ -2,4 +2,3 @@ import type { ZoomImageWheelState } from '@zoom-image/core';
|
|||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
export const photoZoomState = writable<ZoomImageWheelState>();
|
export const photoZoomState = writable<ZoomImageWheelState>();
|
||||||
export const zoomed = writable<boolean>();
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user