Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feat: enhanced zoom and full screen image preview experience of doc site #464

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
972554d
import plugin
curiousRay Jan 9, 2024
d1c9f67
rename and test
curiousRay Jan 9, 2024
07c885a
implemented basic function
curiousRay Jan 9, 2024
f49edea
correct initial position
curiousRay Jan 10, 2024
3caa429
styling the toolbar
curiousRay Jan 10, 2024
6c49ab3
add toggle state
curiousRay Jan 10, 2024
0613a70
implemented basic fullscreen feature
curiousRay Jan 11, 2024
9db8bc9
styling the image zoom bar icons
curiousRay Jan 11, 2024
6bcfb76
add transit animation for image zoom bar
curiousRay Jan 11, 2024
f9026a8
add grab cursor style
curiousRay Jan 11, 2024
30f3dbb
fix image zoom bar hover
curiousRay Jan 11, 2024
1f8c29d
fix bug when user exit fullscreen mode via Esc/F11
curiousRay Jan 11, 2024
7fd9194
optimize fade transition for touch devices
curiousRay Jan 11, 2024
e967236
chores
curiousRay Jan 11, 2024
dd23c0b
set layout of fullscreen
curiousRay Jan 11, 2024
f2d0204
optimize the display of fullscreen-image
curiousRay Jan 12, 2024
ef8e1e8
add blank line
curiousRay Jan 12, 2024
ee69280
add grey overlay when click into fullscreen
curiousRay Feb 21, 2024
fd3e496
use context element
curiousRay Feb 21, 2024
a941358
add imagebox
curiousRay Feb 22, 2024
9ca4c13
adjust position of imagebox
curiousRay Feb 23, 2024
b6edb27
adjust style of buttongroupbox
curiousRay Feb 23, 2024
f0f84c7
refactor styling
curiousRay Feb 23, 2024
82ce998
add animation
curiousRay Feb 23, 2024
f693591
fix bug when opacity's fadeout animation doesn't fire
curiousRay Feb 23, 2024
57c32cd
modify style of overlay
curiousRay Feb 23, 2024
e84afa4
add placeholder of doc context during image fullscreen
curiousRay Feb 23, 2024
a3b0f33
chores: remove commenting
curiousRay Feb 23, 2024
d8105b9
Merge pull request #1 from curiousRay/203-zoom-image-improved
curiousRay Feb 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"react-i18next": "^11.15.3",
"react-icons": "^4.3.1",
"react-redux": "^7.2.6",
"react-zoom-pan-pinch": "^3.3.0",
"redux": "^4.1.2",
"rehype-katex": "5.0.0",
"remark-math": "3.0.1",
Expand Down
3 changes: 3 additions & 0 deletions src/components/Layout/MDXContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { useTotalContributors } from "components/Avatar/Contributors";
import replaceInternalHref from "utils/anchor";
import { Pre } from "components/MDXComponents/Pre";

import { ImageZoomable } from "components/MDXComponents/ImageZoomable";

export default function MDXContent(props: {
data: any;
className?: string;
Expand Down Expand Up @@ -79,6 +81,7 @@ export default function MDXContent(props: {
...MDXConponents,
Link,
pre: Pre,
img: ImageZoomable,
}}
>
<MDXRenderer>{data}</MDXRenderer>
Expand Down
171 changes: 171 additions & 0 deletions src/components/MDXComponents/ImageZoomable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import { Box, Fade, IconButton} from "@mui/material";

import ZoomInIcon from "@mui/icons-material/ZoomIn";
import ZoomOutIcon from "@mui/icons-material/ZoomOut";
import AutorenewIcon from "@mui/icons-material/Autorenew";
import FullscreenIcon from "@mui/icons-material/Fullscreen";
import FullscreenExitIcon from "@mui/icons-material/FullscreenExit";

import React, {
PropsWithChildren,
useRef,
useState,
} from "react";
import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";

type ImageZoomableWrapperProps = PropsWithChildren<{
src: string;
alt: string;
}>

export const ImageZoomable: React.FC<ImageZoomableWrapperProps> = ({ src, alt }) => {

const [isFullscreen, setIsFullScreen] = useState(false);
const [isHovered, setIsHovered] = useState(false);
const [isDragging, setIsDragging] = useState(false);
const [isTouchMoving, setTouchMoving] = useState(false);
const ImageZoomableRef = useRef<HTMLDivElement>(null);
const contextIconSize = isFullscreen ? ("medium") : ("small");
var contextCursor = isDragging ? ("grabbing") : ("grab");

const fullscreen = () => {
if (ImageZoomableRef.current) {
if (isFullscreen) {
setIsFullScreen(false);
let ele_overlay = ImageZoomableRef.current.getElementsByClassName("zoom-overlay")[0] as HTMLElement;
ele_overlay.style.opacity = "0";
ele_overlay.style.transition = "opacity .15s ease-in-out";

ImageZoomableRef.current.parentElement!.style.height = "unset";
ImageZoomableRef.current.parentElement!.style.border = "none";

} else {

setIsFullScreen(true);
let ele_overlay = ImageZoomableRef.current.getElementsByClassName("zoom-overlay")[0] as HTMLElement;
ele_overlay.style.opacity = "1";
ele_overlay.style.transition = "opacity .3s ease-in-out";

ImageZoomableRef.current.parentElement!.style.height = "50px";
ImageZoomableRef.current.parentElement!.style.border = "1px grey dashed";

}
}
}

return (
<Box
className="ImageZoomableContainer"
ref={ImageZoomableRef}
sx={{
position: (isFullscreen ? "fixed" : "inherit"),
zIndex: (isFullscreen ? "10001" : "inherit")
}}
onMouseEnter={() => {
contextCursor = "grab";
setIsHovered(true);
}}
onMouseLeave={() => {
if (!isFullscreen) {
setIsHovered(false);
}
}}
onMouseDown={() => {
setIsDragging(true);
contextCursor = "grabbing";
}}
onMouseUp={() => {
setIsDragging(false);
contextCursor = "grab";
}}
onTouchMove={() => {
setTouchMoving(true);
}}
onTouchStart={()=>{
setTouchMoving(true);
setTimeout(() => {
setTouchMoving(false);
}, 4000);
}}
>

<TransformWrapper
initialScale={1}
initialPositionX={0}
initialPositionY={0}
>
{({ zoomIn, zoomOut, resetTransform, ...rest }) => (
<React.Fragment>
<Fade in={isHovered || isTouchMoving}>
<Box
className="ZoomButtonGroup"
sx={{
position: (isFullscreen ? "fixed" : "absolute"),
float: "left",
zIndex: (isFullscreen ? 99999 : 99),
backgroundColor: "rgb(229,229,229)",
borderRadius: 18,
marginTop: ".5rem",
marginLeft: ".5rem",
transform: (isFullscreen ? "translate(-50%,-50%)" : "inherit"),
left: (isFullscreen ? "50%" : "inherit"),
top: (isFullscreen ? "95%" : "inherit")
}}>
<IconButton
aria-label="btn-zoomin"
onClick={() => zoomIn()}
>
<ZoomInIcon fontSize={contextIconSize}/>
</IconButton>
<IconButton
aria-label="btn-zoomout"
onClick={() => zoomOut()}
>
<ZoomOutIcon fontSize={contextIconSize}/>
</IconButton>
<IconButton
aria-label="btn-zoomreset"
onClick={() => resetTransform()}
>
<AutorenewIcon fontSize={contextIconSize}/>
</IconButton>
<IconButton
aria-label= { isFullscreen ? "btn-fullscreen-exit" : "btn-fullscreen" }
onClick={() => fullscreen()}
>
{ isFullscreen ? (
<FullscreenExitIcon fontSize={contextIconSize}/>) : (
<FullscreenIcon fontSize={contextIconSize}/>
) }
</IconButton>
</Box>
</Fade>
<TransformComponent
contentStyle={{ cursor: contextCursor }}
wrapperStyle={{
position: (isFullscreen ? "fixed" : "inherit"),
zIndex: (isFullscreen ? "99999" : "inherit"),
left: (isFullscreen ? "50%" : "inherit"),
top: (isFullscreen ? "50%" : "inherit"),
transform: (isFullscreen ? "translate(-50%,-50%) scale(1.6)" : "inherit"),
transition: "transform .3s cubic-bezier(.2,0,.2,1)",
}}>
<img src={src} alt={alt}/>
</TransformComponent>
</React.Fragment>
)}
</TransformWrapper>
<Box
className="zoom-overlay"
sx={{
backgroundColor: "rgba(0,0,0,0.7)",
opacity: "0",
position: "fixed",
zIndex: "99998",
inset: "0",
pointerEvents: "none"
}}
/>
</Box>
);
};
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11742,6 +11742,11 @@ react-transition-group@^4.4.5:
loose-envify "^1.4.0"
prop-types "^15.6.2"

react-zoom-pan-pinch@^3.3.0:
version "3.3.0"
resolved "https://registry.npmmirror.com/react-zoom-pan-pinch/-/react-zoom-pan-pinch-3.3.0.tgz#873648438c5244d89fcc2127614046928429cbe0"
integrity sha512-vy1h8aenDzXye+HRqANZaSA8IPHoqOiuDPFBkswoyPUH8uMfsmbeH6gFI4r4BhEJa0xIlcA+FbvhidRWKGUrOg==

react@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
Expand Down