Add fullscreen toggle to large images
This commit is contained in:
parent
b74f83694b
commit
416a45bd2f
54
src/components/FullscreenButton.tsx
Normal file
54
src/components/FullscreenButton.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, RefObject } from 'react';
|
||||
import { MdFullscreen, MdFullscreenExit } from 'react-icons/md';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import { useAppState } from '@/state/AppState';
|
||||
import LoaderButton from './primitives/LoaderButton';
|
||||
|
||||
export default function FullscreenButton({
|
||||
className,
|
||||
imageRef,
|
||||
}: {
|
||||
className?: string;
|
||||
imageRef: RefObject<HTMLImageElement | null>;
|
||||
}) {
|
||||
const { isFullscreen, setIsFullscreen } = useAppState();
|
||||
|
||||
const toggleFullscreen = async () => {
|
||||
if (!document.fullscreenElement) {
|
||||
await imageRef.current?.requestFullscreen();
|
||||
setIsFullscreen && setIsFullscreen(true);
|
||||
} else {
|
||||
await document.exitFullscreen();
|
||||
setIsFullscreen && setIsFullscreen(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === 'f' || event.key === 'F') {
|
||||
toggleFullscreen();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', handleKeyDown);
|
||||
return () => {
|
||||
document.removeEventListener('keydown', handleKeyDown);
|
||||
};
|
||||
}, [toggleFullscreen]);
|
||||
|
||||
return (
|
||||
<LoaderButton
|
||||
title="Toggle Fullscreen"
|
||||
className={clsx(
|
||||
className,
|
||||
'text-medium absolute bottom-2 right-2 bg-white p-2 rounded'
|
||||
)}
|
||||
icon={isFullscreen ? <MdFullscreenExit size={18} /> : <MdFullscreen size={18} />}
|
||||
spinnerColor='light-gray'
|
||||
styleAs='link'
|
||||
onClick={toggleFullscreen}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -13,6 +13,7 @@ export default function ImageLarge(props: ImageProps) {
|
||||
blurCompatibilityLevel: blurCompatibilityMode ? 'high' : 'none',
|
||||
width: IMAGE_WIDTH_LARGE,
|
||||
height: Math.round(IMAGE_WIDTH_LARGE / aspectRatio),
|
||||
allowFullscreen: true,
|
||||
}} />
|
||||
);
|
||||
};
|
||||
|
||||
@ -6,10 +6,12 @@ import { useAppState } from '@/state/AppState';
|
||||
import { clsx} from 'clsx/lite';
|
||||
import Image, { ImageProps } from 'next/image';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import FullscreenButton from '../FullscreenButton';
|
||||
|
||||
export default function ImageWithFallback(props: ImageProps & {
|
||||
blurCompatibilityLevel?: 'none' | 'low' | 'high'
|
||||
imgClassName?: string
|
||||
allowFullscreen?: boolean
|
||||
}) {
|
||||
const {
|
||||
className,
|
||||
@ -17,6 +19,7 @@ export default function ImageWithFallback(props: ImageProps & {
|
||||
blurDataURL,
|
||||
blurCompatibilityLevel = 'low',
|
||||
imgClassName = 'object-cover h-full',
|
||||
allowFullscreen,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
@ -104,6 +107,7 @@ export default function ImageWithFallback(props: ImageProps & {
|
||||
onLoad,
|
||||
onError,
|
||||
}} />
|
||||
</div>
|
||||
{allowFullscreen && <FullscreenButton imageRef={imgRef} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user