mirror of
https://github.com/samsonjs/immich.git
synced 2026-04-27 15:07:45 +00:00
feat: zoom image improvements for reactive prop handlings (#25286)
This commit is contained in:
parent
2b4e4051f0
commit
ca0d4b283a
2 changed files with 40 additions and 25 deletions
|
|
@ -1,48 +1,42 @@
|
||||||
import { photoZoomState } from '$lib/stores/zoom-image.store';
|
import { photoZoomState } from '$lib/stores/zoom-image.store';
|
||||||
import { useZoomImageWheel } from '@zoom-image/svelte';
|
import { createZoomImageWheel } from '@zoom-image/core';
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
|
|
||||||
export const zoomImageAction = (node: HTMLElement, options?: { disabled?: boolean }) => {
|
export const zoomImageAction = (node: HTMLElement, options?: { disabled?: boolean }) => {
|
||||||
const { createZoomImage, zoomImageState, setZoomImageState } = useZoomImageWheel();
|
const state = get(photoZoomState);
|
||||||
|
const zoomInstance = createZoomImageWheel(node, {
|
||||||
createZoomImage(node, {
|
|
||||||
maxZoom: 10,
|
maxZoom: 10,
|
||||||
|
initialState: state,
|
||||||
});
|
});
|
||||||
|
|
||||||
const state = get(photoZoomState);
|
const unsubscribes = [
|
||||||
if (state) {
|
photoZoomState.subscribe((state) => zoomInstance.setState(state)),
|
||||||
setZoomImageState(state);
|
zoomInstance.subscribe(({ state }) => {
|
||||||
}
|
photoZoomState.set(state);
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
// Store original event handlers so we can prevent them when disabled
|
const stopIfDisabled = (event: Event) => {
|
||||||
const wheelHandler = (event: WheelEvent) => {
|
|
||||||
if (options?.disabled) {
|
if (options?.disabled) {
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const pointerDownHandler = (event: PointerEvent) => {
|
node.addEventListener('wheel', stopIfDisabled, { capture: true });
|
||||||
if (options?.disabled) {
|
node.addEventListener('pointerdown', stopIfDisabled, { capture: true });
|
||||||
event.stopImmediatePropagation();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add handlers at capture phase with higher priority
|
|
||||||
node.addEventListener('wheel', wheelHandler, { capture: true });
|
|
||||||
node.addEventListener('pointerdown', pointerDownHandler, { capture: true });
|
|
||||||
|
|
||||||
const unsubscribes = [photoZoomState.subscribe(setZoomImageState), zoomImageState.subscribe(photoZoomState.set)];
|
|
||||||
|
|
||||||
|
node.style.overflow = 'visible';
|
||||||
return {
|
return {
|
||||||
update(newOptions?: { disabled?: boolean }) {
|
update(newOptions?: { disabled?: boolean }) {
|
||||||
options = newOptions;
|
options = newOptions;
|
||||||
},
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
node.removeEventListener('wheel', wheelHandler, { capture: true });
|
|
||||||
node.removeEventListener('pointerdown', pointerDownHandler, { capture: true });
|
|
||||||
for (const unsubscribe of unsubscribes) {
|
for (const unsubscribe of unsubscribes) {
|
||||||
unsubscribe();
|
unsubscribe();
|
||||||
}
|
}
|
||||||
|
node.removeEventListener('wheel', stopIfDisabled, { capture: true });
|
||||||
|
node.removeEventListener('pointerdown', stopIfDisabled, { capture: true });
|
||||||
|
zoomInstance.cleanup();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,25 @@
|
||||||
import type { ZoomImageWheelState } from '@zoom-image/core';
|
import type { ZoomImageWheelState } from '@zoom-image/core';
|
||||||
import { writable } from 'svelte/store';
|
import { derived, writable } from 'svelte/store';
|
||||||
|
|
||||||
export const photoZoomState = writable<ZoomImageWheelState>();
|
export const photoZoomState = writable<ZoomImageWheelState>({
|
||||||
|
currentRotation: 0,
|
||||||
|
currentZoom: 1,
|
||||||
|
enable: true,
|
||||||
|
currentPositionX: 0,
|
||||||
|
currentPositionY: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const photoZoomTransform = derived(
|
||||||
|
photoZoomState,
|
||||||
|
($state) => `translate(${$state.currentPositionX}px,${$state.currentPositionY}px) scale(${$state.currentZoom})`,
|
||||||
|
);
|
||||||
|
|
||||||
|
export const resetZoomState = () => {
|
||||||
|
photoZoomState.set({
|
||||||
|
currentRotation: 0,
|
||||||
|
currentZoom: 1,
|
||||||
|
enable: true,
|
||||||
|
currentPositionX: 0,
|
||||||
|
currentPositionY: 0,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue