@@ -168,21 +168,23 @@ export default function PdfViewer({ url, name }: PdfViewerProps) {
168168 return ( ) => window . removeEventListener ( "resize" , calculateScale ) ;
169169 } , [ ] ) ;
170170
171- useEffect ( ( ) => {
172- const container = containerRef . current ;
173- if ( ! container ) return ;
174-
175- const handleWheel = ( e : WheelEvent ) => {
176- if ( e . ctrlKey ) { // ctrl+wheel is pinch zoom gesture
177- e . preventDefault ( ) ;
178- setScale ( ( prev ) => Math . max ( 0.1 , prev + ( e . deltaY < 0 ? 0.1 : - 0.1 ) ) ) ;
179- }
180- } ;
171+ useEffect ( ( ) => {
172+ const container = containerRef . current ;
173+ if ( ! container ) return ;
181174
182- container . addEventListener ( "wheel" , handleWheel , { passive : false } ) ;
183- return ( ) => container . removeEventListener ( "wheel" , handleWheel ) ;
184- } , [ ] ) ;
175+ const handleWheel = ( e : WheelEvent ) => {
176+ if ( e . ctrlKey ) {
177+ e . preventDefault ( ) ;
178+ const step = 0.02 ;
179+ setScale ( ( prev ) =>
180+ Math . max ( 0.25 , Math . min ( 3 , prev + ( e . deltaY < 0 ? step : - step ) ) ) ,
181+ ) ;
182+ }
183+ } ;
185184
185+ container . addEventListener ( "wheel" , handleWheel , { passive : false } ) ;
186+ return ( ) => container . removeEventListener ( "wheel" , handleWheel ) ;
187+ } , [ ] ) ;
186188
187189 return (
188190 < div className = "flex flex-col items-center p-3 md:p-0" >
@@ -227,63 +229,128 @@ useEffect(() => {
227229 </ div >
228230 ) ) }
229231 </ Document >
232+ { isFullscreen && (
233+ < div className = "fixed bottom-4 left-1/2 z-50 mt-4 flex -translate-x-1/2 flex-col items-center gap-4 rounded-lg bg-[#F3F5FF] p-4 shadow dark:bg-[#262635] sm:flex-row" >
234+ < div className = "flex items-center gap-2" >
235+ < Button
236+ onClick = { goToPreviousPage }
237+ disabled = { pageNumber <= 1 }
238+ className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-[#706b7a] disabled:opacity-50"
239+ >
240+ < FaLessThan />
241+ </ Button >
242+ < input
243+ type = "number"
244+ value = { pageNumber }
245+ onChange = { handlePageChange }
246+ min = { 1 }
247+ max = { numPages }
248+ className = "h-10 w-16 rounded border p-1 text-center [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
249+ />
250+ < span > of { numPages ?? 1 } </ span >
251+ < Button
252+ onClick = { goToNextPage }
253+ disabled = { pageNumber >= ( numPages ?? 1 ) }
254+ className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-[#706b7a] disabled:opacity-50"
255+ >
256+ < FaGreaterThan />
257+ </ Button >
258+ </ div >
259+
260+ < div className = "flex items-center gap-2" >
261+ < Button
262+ onClick = { zoomOut }
263+ disabled = { scale <= 0.25 }
264+ className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-gray-300"
265+ >
266+ < ZoomOut />
267+ </ Button >
268+ < span > { ( scale * 100 ) . toFixed ( 0 ) } %</ span >
269+ < Button
270+ onClick = { zoomIn }
271+ disabled = { scale >= 3 }
272+ className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-gray-300"
273+ >
274+ < ZoomIn />
275+ </ Button >
276+ < ShareButton />
277+ < Button
278+ onClick = { downloadPDF }
279+ className = "aspect-square h-10 w-10 p-0"
280+ >
281+ < Download />
282+ </ Button >
283+ < Button
284+ onClick = { toggleFullscreen }
285+ className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1]"
286+ >
287+ { isFullscreen ? < Minimize2 /> : < Maximize2 /> }
288+ </ Button >
289+ </ div >
290+ </ div >
291+ ) }
230292 </ div >
231293
232- < div className = "mt-4 flex flex-col items-center gap-4 rounded-lg bg-[#F3F5FF] p-4 shadow dark:bg-[#262635] sm:flex-row" >
233- < div className = "flex items-center gap-2" >
234- < Button
235- onClick = { goToPreviousPage }
236- disabled = { pageNumber <= 1 }
237- className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-[#706b7a] disabled:opacity-50"
238- >
239- < FaLessThan />
240- </ Button >
241- < input
242- type = "number"
243- value = { pageNumber }
244- onChange = { handlePageChange }
245- min = { 1 }
246- max = { numPages }
247- className = "h-10 w-16 rounded border p-1 text-center [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
248- />
249- < span > of { numPages ?? 1 } </ span >
250- < Button
251- onClick = { goToNextPage }
252- disabled = { pageNumber >= ( numPages ?? 1 ) }
253- className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-[#706b7a] disabled:opacity-50"
254- >
255- < FaGreaterThan />
256- </ Button >
257- </ div >
294+ { ! isFullscreen && (
295+ < div className = "mt-4 flex flex-col items-center gap-4 rounded-lg bg-[#F3F5FF] p-4 shadow dark:bg-[#262635] sm:flex-row" >
296+ < div className = "flex items-center gap-2" >
297+ < Button
298+ onClick = { goToPreviousPage }
299+ disabled = { pageNumber <= 1 }
300+ className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-[#706b7a] disabled:opacity-50"
301+ >
302+ < FaLessThan />
303+ </ Button >
304+ < input
305+ type = "number"
306+ value = { pageNumber }
307+ onChange = { handlePageChange }
308+ min = { 1 }
309+ max = { numPages }
310+ className = "h-10 w-16 rounded border p-1 text-center [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
311+ />
312+ < span > of { numPages ?? 1 } </ span >
313+ < Button
314+ onClick = { goToNextPage }
315+ disabled = { pageNumber >= ( numPages ?? 1 ) }
316+ className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-[#706b7a] disabled:opacity-50"
317+ >
318+ < FaGreaterThan />
319+ </ Button >
320+ </ div >
258321
259- < div className = "flex items-center gap-2" >
260- < Button
261- onClick = { zoomOut }
262- disabled = { scale <= 0.25 }
263- className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-gray-300"
264- >
265- < ZoomOut />
266- </ Button >
267- < span > { ( scale * 100 ) . toFixed ( 0 ) } %</ span >
268- < Button
269- onClick = { zoomIn }
270- disabled = { scale >= 3 }
271- className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-gray-300"
272- >
273- < ZoomIn />
274- </ Button >
275- < ShareButton />
276- < Button onClick = { downloadPDF } className = "aspect-square h-10 w-10 p-0" >
277- < Download />
278- </ Button >
279- < Button
280- onClick = { toggleFullscreen }
281- className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1]"
282- >
283- { isFullscreen ? < Minimize2 /> : < Maximize2 /> }
284- </ Button >
322+ < div className = "flex items-center gap-2" >
323+ < Button
324+ onClick = { zoomOut }
325+ disabled = { scale <= 0.25 }
326+ className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-gray-300"
327+ >
328+ < ZoomOut />
329+ </ Button >
330+ < span > { ( scale * 100 ) . toFixed ( 0 ) } %</ span >
331+ < Button
332+ onClick = { zoomIn }
333+ disabled = { scale >= 3 }
334+ className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1] disabled:bg-gray-300"
335+ >
336+ < ZoomIn />
337+ </ Button >
338+ < ShareButton />
339+ < Button
340+ onClick = { downloadPDF }
341+ className = "aspect-square h-10 w-10 p-0"
342+ >
343+ < Download />
344+ </ Button >
345+ < Button
346+ onClick = { toggleFullscreen }
347+ className = "h-10 w-10 rounded p-0 text-white transition hover:bg-[#6536c1]"
348+ >
349+ { isFullscreen ? < Minimize2 /> : < Maximize2 /> }
350+ </ Button >
351+ </ div >
285352 </ div >
286- </ div >
353+ ) }
287354 </ div >
288355 ) ;
289356}
0 commit comments