mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
fix: image preview (#2786)
Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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',
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user