From ae7da1b018ccbccba1ea8ef67b7cf86bb1dc21df Mon Sep 17 00:00:00 2001 From: danielchim Date: Thu, 15 Jun 2023 13:55:17 +0800 Subject: [PATCH] fix: image preview (#2786) Co-authored-by: himself65 --- .../image-preview-modal/hooks/use-zoom.tsx | 62 ++++++++----- .../image-preview-modal/index.css.ts | 2 +- .../components/image-preview-modal/index.tsx | 86 +++++++++---------- 3 files changed, 80 insertions(+), 70 deletions(-) diff --git a/packages/component/src/components/image-preview-modal/hooks/use-zoom.tsx b/packages/component/src/components/image-preview-modal/hooks/use-zoom.tsx index db1538472c..d51ffc6d81 100644 --- a/packages/component/src/components/image-preview-modal/hooks/use-zoom.tsx +++ b/packages/component/src/components/image-preview-modal/hooks/use-zoom.tsx @@ -10,7 +10,7 @@ export const useZoomControls = ({ zoomRef, imageRef, }: UseZoomControlsProps) => { - const [currentScale, setCurrentScale] = useState(0.5); + const [currentScale, setCurrentScale] = useState(1); const [isZoomedBigger, setIsZoomedBigger] = useState(false); const [isDragging, setIsDragging] = useState(false); const [mouseX, setMouseX] = useState(0); @@ -35,28 +35,60 @@ export const useZoomControls = ({ const zoomOut = useCallback(() => { const image = imageRef.current; - if (image && currentScale > 0.5) { + if (image && currentScale > 0.2) { const newScale = currentScale - 0.1; setCurrentScale(newScale); image.style.width = `${image.naturalWidth * newScale}px`; image.style.height = `${image.naturalHeight * newScale}px`; - if (!isZoomedBigger) { + const zoomedWidth = image.naturalWidth * newScale; + const zoomedHeight = image.naturalHeight * newScale; + const containerWidth = window.innerWidth; + const containerHeight = window.innerHeight; + if (zoomedWidth > containerWidth || zoomedHeight > containerHeight) { image.style.transform = `translate(0px, 0px)`; + setImagePos({ x: 0, y: 0 }); } } - }, [imageRef, currentScale, isZoomedBigger]); + }, [imageRef, currentScale]); + + const checkZoomSize = useCallback(() => { + const { current: zoomArea } = zoomRef; + if (zoomArea) { + const image = zoomArea.querySelector('img'); + if (image) { + const zoomedWidth = image.naturalWidth * currentScale; + const zoomedHeight = image.naturalHeight * currentScale; + const containerWidth = window.innerWidth; + const containerHeight = window.innerHeight; + setIsZoomedBigger( + zoomedWidth > containerWidth || zoomedHeight > containerHeight + ); + } + } + }, [currentScale, zoomRef]); const resetZoom = useCallback(() => { const image = imageRef.current; if (image) { - const newScale = 0.5; + const viewportWidth = window.innerWidth; + const viewportHeight = window.innerHeight; + const margin = 0.2; + + const availableWidth = viewportWidth * (1 - margin); + const availableHeight = viewportHeight * (1 - margin); + + const widthRatio = availableWidth / image.naturalWidth; + const heightRatio = availableHeight / image.naturalHeight; + + const newScale = Math.min(widthRatio, heightRatio); setCurrentScale(newScale); image.style.width = `${image.naturalWidth * newScale}px`; image.style.height = `${image.naturalHeight * newScale}px`; - image.style.transform = `translate(0px, 0px)`; + image.style.transform = 'translate(0px, 0px)'; setImagePos({ x: 0, y: 0 }); + checkZoomSize(); } - }, [imageRef]); + }, [checkZoomSize, imageRef]); const handleDragStart = useCallback( (event: ReactMouseEvent) => { @@ -138,22 +170,6 @@ export const useZoomControls = ({ } }, [isDragging, dragEndImpl]); - const checkZoomSize = useCallback(() => { - const { current: zoomArea } = zoomRef; - if (zoomArea) { - const image = zoomArea.querySelector('img'); - if (image) { - const zoomedWidth = image.naturalWidth * currentScale; - const zoomedHeight = image.naturalHeight * currentScale; - const containerWidth = window.innerWidth; - const containerHeight = window.innerHeight; - setIsZoomedBigger( - zoomedWidth > containerWidth || zoomedHeight > containerHeight - ); - } - } - }, [currentScale, zoomRef]); - useEffect(() => { const handleScroll = (event: WheelEvent) => { const { deltaY } = event; diff --git a/packages/component/src/components/image-preview-modal/index.css.ts b/packages/component/src/components/image-preview-modal/index.css.ts index 30d405ac18..98bcbfcb75 100644 --- a/packages/component/src/components/image-preview-modal/index.css.ts +++ b/packages/component/src/components/image-preview-modal/index.css.ts @@ -49,7 +49,7 @@ export const imagePreviewModalGoStyle = style({ export const imageNavigationControlStyle = style({ display: 'flex', height: '100%', - zIndex: 0, + zIndex: 2, justifyContent: 'space-between', alignItems: 'center', }); diff --git a/packages/component/src/components/image-preview-modal/index.tsx b/packages/component/src/components/image-preview-modal/index.tsx index cff3c410a5..5150bc0397 100644 --- a/packages/component/src/components/image-preview-modal/index.tsx +++ b/packages/component/src/components/image-preview-modal/index.tsx @@ -105,6 +105,7 @@ const ImagePreviewModalImpl = ( if (!url) { return null; } + const nextImageHandler = (blockId: string | null) => { assertExists(blockId); const workspace = props.workspace; @@ -120,12 +121,6 @@ const ImagePreviewModalImpl = ( ); if (nextBlock) { setBlockId(nextBlock.id); - const image = imageRef.current; - resetZoom(); - if (image) { - image.style.width = '50%'; // Reset the width to its original size - image.style.height = 'auto'; // Reset the height to maintain aspect ratio - } } }; @@ -143,12 +138,6 @@ const ImagePreviewModalImpl = ( ); if (prevBlock) { setBlockId(prevBlock.id); - const image = imageRef.current; - if (image) { - resetZoom(); - image.style.width = '50%'; // Reset the width to its original size - image.style.height = 'auto'; // Reset the height to maintain aspect ratio - } } }; @@ -173,12 +162,6 @@ const ImagePreviewModalImpl = ( ); if (prevBlock) { setBlockId(prevBlock.id); - const image = imageRef.current; - resetZoom(); - if (image) { - image.style.width = '100%'; // Reset the width to its original size - image.style.height = 'auto'; // Reset the height to maintain aspect ratio - } } } else if ( page @@ -278,33 +261,43 @@ const ImagePreviewModalImpl = ( }; return ( -
-
- { - assertExists(blockId); - previousImageHandler(blockId); - }} - > - ❮ - - { - assertExists(blockId); - nextImageHandler(blockId); - }} - > - ❯ - -
+
+ event.target === event.currentTarget ? props.onClose() : null + } + > + {!isZoomedBigger ? ( +
+ { + assertExists(blockId); + previousImageHandler(blockId); + }} + > + ❮ + + { + assertExists(blockId); + nextImageHandler(blockId); + }} + > + ❯ + +
+ ) : ( + <> + )}
{isZoomedBigger ? null : (

{caption}

@@ -356,6 +349,7 @@ const ImagePreviewModalImpl = ( className={imageBottomContainerStyle} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} + onClick={event => event.stopPropagation()} > {isZoomedBigger && caption !== '' ? (

{caption}