From 91bb0f5167614247638c1072363c5a784761d577 Mon Sep 17 00:00:00 2001 From: Nam Nguyen Date: Wed, 4 Sep 2024 14:27:37 -0300 Subject: [PATCH] =?UTF-8?q?Fix=20zoom=20move=20not=20working=20on=20multi-?= =?UTF-8?q?fingers=20usage=20=E2=9C=A8=20(#318)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/weak-spiders-tie.md | 5 ++ packages/core/src/createZoomImageMove.ts | 48 ++++++++++++------- packages/core/src/utils.ts | 5 +- size.json | 60 ++++++++++++------------ 4 files changed, 67 insertions(+), 51 deletions(-) create mode 100644 .changeset/weak-spiders-tie.md diff --git a/.changeset/weak-spiders-tie.md b/.changeset/weak-spiders-tie.md new file mode 100644 index 00000000..121744c5 --- /dev/null +++ b/.changeset/weak-spiders-tie.md @@ -0,0 +1,5 @@ +--- +"@zoom-image/core": patch +--- + +Fix zoom move not working on multi-fingers usage ✨ diff --git a/packages/core/src/createZoomImageMove.ts b/packages/core/src/createZoomImageMove.ts index 564c7081..dc0dda21 100644 --- a/packages/core/src/createZoomImageMove.ts +++ b/packages/core/src/createZoomImageMove.ts @@ -19,6 +19,7 @@ export type ZoomImageMoveState = { } export function createZoomImageMove(container: HTMLElement, options: ZoomImageMoveOptions = {}) { + let activePointerId: number | null = null const sourceImgElement = getSourceImage(container) const finalOptions: Omit, "zoomImageProps" | "disableScrollLock"> = { zoomFactor: options.zoomFactor ?? 4, @@ -46,29 +47,41 @@ export function createZoomImageMove(container: HTMLElement, options: ZoomImageMo zoomedImg.oncontextmenu = () => false } - function handlePointerEnter(event: PointerEvent) { - container.appendChild(zoomedImg) - zoomedImg.style.display = "block" - const zoomedImgWidth = sourceImgElement.clientWidth * zoomFactor - const zoomedImgHeight = sourceImgElement.clientHeight * zoomFactor - zoomedImg.style.width = `${zoomedImgWidth}px` - zoomedImg.style.height = `${zoomedImgHeight}px` - imageLoader.createZoomImage(zoomedImg, zoomImageSource, store) - - processZoom(event) + const checkValidPointer = (event: PointerEvent) => { + return activePointerId && event.pointerId === activePointerId + } - event.pointerType !== "mouse" && disableScroll() + function handlePointerEnter(event: PointerEvent) { + if (activePointerId === null) { + activePointerId = event.pointerId + container.appendChild(zoomedImg) + zoomedImg.style.display = "block" + const zoomedImgWidth = sourceImgElement.clientWidth * zoomFactor + const zoomedImgHeight = sourceImgElement.clientHeight * zoomFactor + zoomedImg.style.width = `${zoomedImgWidth}px` + zoomedImg.style.height = `${zoomedImgHeight}px` + imageLoader.createZoomImage(zoomedImg, zoomImageSource, store) + + processZoom(event) + + event.pointerType !== "mouse" && disableScroll() + } } function handlePointerMove(event: PointerEvent) { - processZoom(event) + if (checkValidPointer(event)) { + processZoom(event) + } } - function resetZoomedImg() { - container.contains(zoomedImg) && container.removeChild(zoomedImg) - zoomedImg.style.display = "none" - zoomedImg.style.transform = "none" - enableScroll() + function resetZoomedImg(event: PointerEvent) { + if (checkValidPointer(event)) { + container.contains(zoomedImg) && container.removeChild(zoomedImg) + zoomedImg.style.display = "none" + zoomedImg.style.transform = "none" + enableScroll() + activePointerId = null + } } const calculatePositionX = (newPositionX: number) => { @@ -102,7 +115,6 @@ export function createZoomImageMove(container: HTMLElement, options: ZoomImageMo container.addEventListener("pointerenter", handlePointerEnter, { signal }) container.addEventListener("pointermove", handlePointerMove, { signal }) container.addEventListener("pointerleave", resetZoomedImg, { signal }) - container.addEventListener("touchend", resetZoomedImg, { signal }) container.addEventListener( "touchstart", (event) => { diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index e20bfca7..b5437f0d 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -16,11 +16,10 @@ function preventDefaultForScrollKeys(event: KeyboardEvent) { } } -let controller: AbortController | undefined +const controller = new AbortController() +const signal = controller.signal export function disableScroll() { - controller = new AbortController() - const { signal } = controller window.addEventListener("DOMMouseScroll", preventDefault, { signal }) window.addEventListener("wheel", preventDefault, { passive: false, signal }) window.addEventListener("touchmove", preventDefault, { passive: false, signal }) diff --git a/size.json b/size.json index 70311289..7919ead6 100644 --- a/size.json +++ b/size.json @@ -1,53 +1,53 @@ { "@zoom-image/core": { - "createZoomImageWheel": "2.09 KB", + "createZoomImageWheel": "2.1 KB", "createZoomImageHover": "1.28 KB", - "createZoomImageMove": "983 B", - "createZoomImageClick": "936 B", + "createZoomImageMove": "1 KB", + "createZoomImageClick": "943 B", "cropImage": "386 B", - "makeCalculateZoom": "132 B", - "makeCalculatePercentage": "124 B" + "makeCalculateZoom": "171 B", + "makeCalculatePercentage": "153 B" }, "@zoom-image/react": { - "useZoomImageWheel": "2.37 KB", - "useZoomImageHover": "1.55 KB", - "useZoomImageMove": "1.22 KB", - "useZoomImageClick": "1.17 KB" + "useZoomImageWheel": "2.38 KB", + "useZoomImageHover": "1.56 KB", + "useZoomImageMove": "1.26 KB", + "useZoomImageClick": "1.18 KB" }, "@zoom-image/preact": { - "useZoomImageWheel": "3.26 KB", + "useZoomImageWheel": "3.27 KB", "useZoomImageHover": "2.46 KB", - "useZoomImageMove": "2.14 KB", - "useZoomImageClick": "2.1 KB" + "useZoomImageMove": "2.19 KB", + "useZoomImageClick": "2.11 KB" }, "@zoom-image/qwik": { "useZoomImageWheel": "2.51 KB", - "useZoomImageHover": "1.66 KB", - "useZoomImageMove": "1.32 KB", - "useZoomImageClick": "1.28 KB" + "useZoomImageHover": "1.67 KB", + "useZoomImageMove": "1.37 KB", + "useZoomImageClick": "1.29 KB" }, "@zoom-image/solid": { - "useZoomImageWheel": "3.55 KB", - "useZoomImageHover": "2.74 KB", - "useZoomImageMove": "2.44 KB", - "useZoomImageClick": "2.39 KB" + "useZoomImageWheel": "3.56 KB", + "useZoomImageHover": "2.75 KB", + "useZoomImageMove": "2.48 KB", + "useZoomImageClick": "2.4 KB" }, "@zoom-image/svelte": { - "useZoomImageWheel": "2.56 KB", + "useZoomImageWheel": "2.57 KB", "useZoomImageHover": "1.75 KB", - "useZoomImageMove": "1.44 KB", - "useZoomImageClick": "1.38 KB" + "useZoomImageMove": "1.48 KB", + "useZoomImageClick": "1.39 KB" }, "@zoom-image/vue": { - "useZoomImageWheel": "2.35 KB", - "useZoomImageHover": "1.53 KB", - "useZoomImageMove": "1.2 KB", - "useZoomImageClick": "1.16 KB" + "useZoomImageWheel": "2.36 KB", + "useZoomImageHover": "1.54 KB", + "useZoomImageMove": "1.25 KB", + "useZoomImageClick": "1.17 KB" }, "@zoom-image/angular": { - "ZoomImageClickService": "3.94 KB", - "ZoomImageHoverService": "3.94 KB", - "ZoomImageWheelService": "3.94 KB", - "ZoomImageMoveService": "3.94 KB" + "ZoomImageClickService": "3.97 KB", + "ZoomImageHoverService": "3.97 KB", + "ZoomImageMoveService": "3.97 KB", + "ZoomImageWheelService": "3.97 KB" } }