1- import { Box , Fade , IconButton , Tooltip } from "@mui/material" ;
1+ import { Box , Fade , IconButton } from "@mui/material" ;
22
33import ZoomInIcon from "@mui/icons-material/ZoomIn" ;
44import ZoomOutIcon from "@mui/icons-material/ZoomOut" ;
@@ -10,7 +10,6 @@ import React, {
1010 PropsWithChildren ,
1111 useRef ,
1212 useState ,
13- useEffect ,
1413 } from "react" ;
1514import { TransformWrapper , TransformComponent } from "react-zoom-pan-pinch" ;
1615
@@ -32,56 +31,44 @@ export const ImageZoomable: React.FC<ImageZoomableWrapperProps> = ({ src, alt })
3231 const fullscreen = ( ) => {
3332 if ( ImageZoomableRef . current ) {
3433 if ( isFullscreen ) {
35- document . exitFullscreen ( ) ;
36- } else {
37- ImageZoomableRef . current . requestFullscreen ( )
38- . catch ( ( err ) => {
39- console . error ( `Error in enabling fullscreen mode: ${ err . message } ` ) ;
40- } ) ;
41- }
42- }
43- }
44-
45- useEffect ( ( ) => {
46- window . onresize = ( ) => {
47- setIsFullScreen ( ( document . fullscreenElement != null ) ? true : false ) ;
48- if ( document . fullscreenElement ) {
49-
50- // when entered fullscreen, set image position to flex-centered for better display
51- const ele = document . fullscreenElement as HTMLElement
52- ele . style . display = 'flex' ;
53- ele . style . alignItems = 'center' ;
54- ele . style . justifyContent = 'center' ;
55- ele . style . flexFlow = 'column-reverse' ;
34+ setIsFullScreen ( false ) ;
35+ let ele_overlay = ImageZoomableRef . current . getElementsByClassName ( "zoom-overlay" ) [ 0 ] as HTMLElement ;
36+ ele_overlay . style . opacity = "0" ;
37+ ele_overlay . style . transition = "opacity .15s ease-in-out" ;
5638
57- // when entered fullscreen, unset 'position:absolute' zoom button group for better display
58- const ele2 = ele . querySelector ( ".ZoomButtonGroup" ) as HTMLElement ;
59- ele2 . style . position = 'unset' ;
39+ ImageZoomableRef . current . parentElement ! . style . height = "unset" ;
40+ ImageZoomableRef . current . parentElement ! . style . border = "none" ;
6041
6142 } else {
62- if ( ImageZoomableRef . current ) {
63-
64- // exited fullscreen and back to normal position
65- ImageZoomableRef . current . style . display = 'block' ;
6643
67- // exited fullscreen and restore 'position:absolute' of zoom button group
68- const ele2 = ImageZoomableRef . current . querySelector ( ".ZoomButtonGroup" ) as HTMLElement ;
69- ele2 . style . position = 'absolute' ;
70- }
44+ setIsFullScreen ( true ) ;
45+ let ele_overlay = ImageZoomableRef . current . getElementsByClassName ( "zoom-overlay" ) [ 0 ] as HTMLElement ;
46+ ele_overlay . style . opacity = "1" ;
47+ ele_overlay . style . transition = "opacity .3s ease-in-out" ;
48+
49+ ImageZoomableRef . current . parentElement ! . style . height = "50px" ;
50+ ImageZoomableRef . current . parentElement ! . style . border = "1px grey dashed" ;
51+
7152 }
7253 }
73- } )
54+ }
7455
7556 return (
7657 < Box
7758 className = "ImageZoomableContainer"
7859 ref = { ImageZoomableRef }
60+ sx = { {
61+ position : ( isFullscreen ? "fixed" : "inherit" ) ,
62+ zIndex : ( isFullscreen ? "10001" : "inherit" )
63+ } }
7964 onMouseEnter = { ( ) => {
8065 contextCursor = "grab" ;
8166 setIsHovered ( true ) ;
8267 } }
8368 onMouseLeave = { ( ) => {
84- setIsHovered ( false ) ;
69+ if ( ! isFullscreen ) {
70+ setIsHovered ( false ) ;
71+ }
8572 } }
8673 onMouseDown = { ( ) => {
8774 setIsDragging ( true ) ;
@@ -101,6 +88,7 @@ export const ImageZoomable: React.FC<ImageZoomableWrapperProps> = ({ src, alt })
10188 } , 4000 ) ;
10289 } }
10390 >
91+
10492 < TransformWrapper
10593 initialScale = { 1 }
10694 initialPositionX = { 0 }
@@ -112,34 +100,37 @@ export const ImageZoomable: React.FC<ImageZoomableWrapperProps> = ({ src, alt })
112100 < Box
113101 className = "ZoomButtonGroup"
114102 sx = { {
115- position : ' absolute' ,
116- float : ' left' ,
117- zIndex : 99 ,
118- backgroundColor : ' rgb(229,229,229)' ,
103+ position : ( isFullscreen ? "fixed" : " absolute" ) ,
104+ float : " left" ,
105+ zIndex : ( isFullscreen ? 99999 : 99 ) ,
106+ backgroundColor : " rgb(229,229,229)" ,
119107 borderRadius : 18 ,
120- marginTop : '.5rem' ,
121- marginLeft : '.5rem' ,
108+ marginTop : ".5rem" ,
109+ marginLeft : ".5rem" ,
110+ transform : ( isFullscreen ? "translate(-50%,-50%)" : "inherit" ) ,
111+ left : ( isFullscreen ? "50%" : "inherit" ) ,
112+ top : ( isFullscreen ? "95%" : "inherit" )
122113 } } >
123114 < IconButton
124- aria-label = ' btn-zoomin'
115+ aria-label = " btn-zoomin"
125116 onClick = { ( ) => zoomIn ( ) }
126117 >
127118 < ZoomInIcon fontSize = { contextIconSize } />
128119 </ IconButton >
129120 < IconButton
130- aria-label = ' btn-zoomout'
121+ aria-label = " btn-zoomout"
131122 onClick = { ( ) => zoomOut ( ) }
132123 >
133124 < ZoomOutIcon fontSize = { contextIconSize } />
134125 </ IconButton >
135126 < IconButton
136- aria-label = ' btn-zoomreset'
127+ aria-label = " btn-zoomreset"
137128 onClick = { ( ) => resetTransform ( ) }
138129 >
139130 < AutorenewIcon fontSize = { contextIconSize } />
140131 </ IconButton >
141132 < IconButton
142- aria-label = { isFullscreen ? ( ' btn-fullscreen-exit' ) : ( ' btn-fullscreen' ) }
133+ aria-label = { isFullscreen ? " btn-fullscreen-exit" : " btn-fullscreen" }
143134 onClick = { ( ) => fullscreen ( ) }
144135 >
145136 { isFullscreen ? (
@@ -149,12 +140,32 @@ export const ImageZoomable: React.FC<ImageZoomableWrapperProps> = ({ src, alt })
149140 </ IconButton >
150141 </ Box >
151142 </ Fade >
152- < TransformComponent contentStyle = { { cursor : contextCursor } } >
143+ < TransformComponent
144+ contentStyle = { { cursor : contextCursor } }
145+ wrapperStyle = { {
146+ position : ( isFullscreen ? "fixed" : "inherit" ) ,
147+ zIndex : ( isFullscreen ? "99999" : "inherit" ) ,
148+ left : ( isFullscreen ? "50%" : "inherit" ) ,
149+ top : ( isFullscreen ? "50%" : "inherit" ) ,
150+ transform : ( isFullscreen ? "translate(-50%,-50%) scale(1.6)" : "inherit" ) ,
151+ transition : "transform .3s cubic-bezier(.2,0,.2,1)" ,
152+ } } >
153153 < img src = { src } alt = { alt } />
154154 </ TransformComponent >
155155 </ React . Fragment >
156156 ) }
157157 </ TransformWrapper >
158+ < Box
159+ className = "zoom-overlay"
160+ sx = { {
161+ backgroundColor : "rgba(0,0,0,0.7)" ,
162+ opacity : "0" ,
163+ position : "fixed" ,
164+ zIndex : "99998" ,
165+ inset : "0" ,
166+ pointerEvents : "none"
167+ } }
168+ />
158169 </ Box >
159170 ) ;
160171} ;
0 commit comments