Convert zoom controls into hook
This commit is contained in:
parent
5139abcdba
commit
2195379b74
@ -23,6 +23,7 @@ import ShareModals from '@/share/ShareModals';
|
||||
|
||||
import '../site/globals.css';
|
||||
import '../site/sonner.css';
|
||||
import '../site/viewerjs.css';
|
||||
|
||||
const ibmPlexMono = IBM_Plex_Mono({
|
||||
subsets: ['latin'],
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import Viewer from 'viewerjs';
|
||||
import 'viewerjs/dist/viewer.css';
|
||||
import { clsx } from 'clsx/lite';
|
||||
import FullscreenButton from '../FullscreenButton';
|
||||
|
||||
export default function ImageZoomControls({
|
||||
children,
|
||||
enableImageActions = false,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
enableImageActions?: boolean;
|
||||
className?: string;
|
||||
}) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const viewerRef = useRef<Viewer | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (containerRef.current && enableImageActions) {
|
||||
viewerRef.current = new Viewer(containerRef.current, {
|
||||
inline: false,
|
||||
button: true,
|
||||
navbar: false,
|
||||
title: false,
|
||||
toolbar: {
|
||||
zoomIn: 1,
|
||||
zoomOut: 1,
|
||||
reset: 1,
|
||||
tooltip: 1,
|
||||
},
|
||||
});
|
||||
return () => {
|
||||
viewerRef.current?.destroy();
|
||||
};
|
||||
}
|
||||
}, [enableImageActions]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<style jsx global>{`
|
||||
.viewer-canvas {
|
||||
background-color: black !important;
|
||||
}
|
||||
.viewer-reset::before {
|
||||
content: '1:1';
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
bottom: -9px;
|
||||
letter-spacing: -2px;
|
||||
background-image: none;
|
||||
}
|
||||
`}</style>
|
||||
<div
|
||||
className={clsx(className, enableImageActions && 'cursor-zoom-in')}
|
||||
ref={containerRef}
|
||||
>
|
||||
{children}
|
||||
{enableImageActions && (
|
||||
<FullscreenButton imageRef={containerRef} />
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
29
src/components/image/useImageZoomControls.ts
Normal file
29
src/components/image/useImageZoomControls.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { RefObject, useEffect, useRef } from 'react';
|
||||
import Viewer from 'viewerjs';
|
||||
|
||||
export default function useImageZoomControls(
|
||||
imageRef: RefObject<HTMLDivElement | null>,
|
||||
isEnabled?: boolean,
|
||||
) {
|
||||
const viewerRef = useRef<Viewer | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (imageRef.current && isEnabled) {
|
||||
viewerRef.current = new Viewer(imageRef.current, {
|
||||
inline: false,
|
||||
button: true,
|
||||
navbar: false,
|
||||
title: false,
|
||||
toolbar: {
|
||||
zoomIn: 1,
|
||||
zoomOut: 1,
|
||||
reset: 1,
|
||||
tooltip: 1,
|
||||
},
|
||||
});
|
||||
return () => {
|
||||
viewerRef.current?.destroy();
|
||||
};
|
||||
}
|
||||
}, [imageRef, isEnabled]);
|
||||
}
|
||||
@ -113,7 +113,7 @@ export default function PhotoDetailPage({
|
||||
shouldShareSimulation={simulation !== undefined}
|
||||
shouldScrollOnShare={false}
|
||||
includeFavoriteInAdminMenu={includeFavoriteInAdminMenu}
|
||||
enableImageActions={ZOOM_CONTROLS_ENABLED}
|
||||
shouldShowZoomControls={ZOOM_CONTROLS_ENABLED}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
|
||||
@ -36,7 +36,7 @@ import { useRef } from 'react';
|
||||
import useOnVisible from '@/utility/useOnVisible';
|
||||
import PhotoDate from './PhotoDate';
|
||||
import { useAppState } from '@/state/AppState';
|
||||
import ImageZoomControls from '@/components/image/ImageZoomControls';
|
||||
import useImageZoomControls from '@/components/image/useImageZoomControls';
|
||||
|
||||
export default function PhotoLarge({
|
||||
photo,
|
||||
@ -55,9 +55,9 @@ export default function PhotoLarge({
|
||||
shouldShareCamera,
|
||||
shouldShareSimulation,
|
||||
shouldShareFocalLength,
|
||||
shouldShowZoomControls,
|
||||
includeFavoriteInAdminMenu,
|
||||
onVisible,
|
||||
enableImageActions = false,
|
||||
}: {
|
||||
photo: Photo
|
||||
className?: string
|
||||
@ -76,11 +76,12 @@ export default function PhotoLarge({
|
||||
shouldShareSimulation?: boolean
|
||||
shouldShareFocalLength?: boolean
|
||||
shouldScrollOnShare?: boolean
|
||||
shouldShowZoomControls?: boolean
|
||||
includeFavoriteInAdminMenu?: boolean
|
||||
onVisible?: () => void
|
||||
enableImageActions?: boolean
|
||||
}) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const refZoomControls = useRef<HTMLDivElement>(null);
|
||||
|
||||
const tags = sortTags(photo.tags, primaryTag);
|
||||
|
||||
@ -92,6 +93,8 @@ export default function PhotoLarge({
|
||||
|
||||
useOnVisible(ref, onVisible);
|
||||
|
||||
useImageZoomControls(refZoomControls, shouldShowZoomControls);
|
||||
|
||||
const { arePhotosMatted, isUserSignedIn } = useAppState();
|
||||
|
||||
const hasTitle =
|
||||
@ -146,9 +149,9 @@ export default function PhotoLarge({
|
||||
arePhotosMatted && 'h-[90%]',
|
||||
arePhotosMatted && matteContentWidthForAspectRatio(),
|
||||
)}>
|
||||
<ImageZoomControls
|
||||
enableImageActions={enableImageActions}
|
||||
className="flex relative items-center justify-center h-full"
|
||||
<div
|
||||
ref={refZoomControls}
|
||||
className={clsx(shouldShowZoomControls && 'cursor-zoom-in')}
|
||||
>
|
||||
<ImageLarge
|
||||
className={clsx(arePhotosMatted && 'h-full')}
|
||||
@ -161,7 +164,7 @@ export default function PhotoLarge({
|
||||
blurCompatibilityMode={doesPhotoNeedBlurCompatibility(photo)}
|
||||
priority={priority}
|
||||
/>
|
||||
</ImageZoomControls>
|
||||
</div>
|
||||
</div>
|
||||
</Link>}
|
||||
contentSide={
|
||||
|
||||
16
src/site/viewerjs.css
Normal file
16
src/site/viewerjs.css
Normal file
@ -0,0 +1,16 @@
|
||||
@import 'viewerjs/dist/viewer.css';
|
||||
|
||||
.viewer-canvas {
|
||||
background-color: black !important;
|
||||
}
|
||||
.viewer-reset::before {
|
||||
content: '1:1';
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
bottom: -9px;
|
||||
letter-spacing: -2px;
|
||||
background-image: none;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user