fix: image preview (#2786)

Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
danielchim
2023-06-15 13:55:17 +08:00
committed by GitHub
parent 3819342ff2
commit ae7da1b018
3 changed files with 80 additions and 70 deletions

View File

@@ -10,7 +10,7 @@ export const useZoomControls = ({
zoomRef,
imageRef,
}: UseZoomControlsProps) => {
const [currentScale, setCurrentScale] = useState<number>(0.5);
const [currentScale, setCurrentScale] = useState<number>(1);
const [isZoomedBigger, setIsZoomedBigger] = useState<boolean>(false);
const [isDragging, setIsDragging] = useState<boolean>(false);
const [mouseX, setMouseX] = useState<number>(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;

View File

@@ -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',
});

View File

@@ -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 (
<div data-testid="image-preview-modal" className={imagePreviewModalStyle}>
<div className={imageNavigationControlStyle}>
<span
className={imagePreviewModalGoStyle}
style={{
left: 0,
}}
onClick={() => {
assertExists(blockId);
previousImageHandler(blockId);
}}
>
</span>
<span
className={imagePreviewModalGoStyle}
style={{
right: 0,
}}
onClick={() => {
assertExists(blockId);
nextImageHandler(blockId);
}}
>
</span>
</div>
<div
data-testid="image-preview-modal"
className={imagePreviewModalStyle}
onClick={event =>
event.target === event.currentTarget ? props.onClose() : null
}
>
{!isZoomedBigger ? (
<div className={imageNavigationControlStyle}>
<span
className={imagePreviewModalGoStyle}
style={{
left: 0,
}}
onClick={() => {
assertExists(blockId);
previousImageHandler(blockId);
}}
>
</span>
<span
className={imagePreviewModalGoStyle}
style={{
right: 0,
}}
onClick={() => {
assertExists(blockId);
nextImageHandler(blockId);
}}
>
</span>
</div>
) : (
<></>
)}
<div className={imagePreviewModalContainerStyle}>
<div
className={clsx('zoom-area', { 'zoomed-bigger': isZoomedBigger })}
@@ -322,7 +315,7 @@ const ImagePreviewModalImpl = (
onMouseUp={handleDragEnd}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
width={'50%'}
onLoad={resetZoom}
/>
{isZoomedBigger ? null : (
<p className={imagePreviewModalCaptionStyle}>{caption}</p>
@@ -356,6 +349,7 @@ const ImagePreviewModalImpl = (
className={imageBottomContainerStyle}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={event => event.stopPropagation()}
>
{isZoomedBigger && caption !== '' ? (
<p className={captionStyle}>{caption}</p>