ui
This commit is contained in:
@@ -17,6 +17,8 @@ const ensureDocumentRoot = () => {
|
||||
return document.body;
|
||||
};
|
||||
|
||||
const CLICK_DELAY_MS = 240;
|
||||
|
||||
const PreviewZoomOverlay = ({
|
||||
open = false,
|
||||
display = null,
|
||||
@@ -34,6 +36,7 @@ const PreviewZoomOverlay = ({
|
||||
const previouslyFocusedRef = useRef(null);
|
||||
const visibilityTimerRef = useRef(null);
|
||||
const displayTimerRef = useRef(null);
|
||||
const clickTimerRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (display?.url) {
|
||||
@@ -86,12 +89,20 @@ const PreviewZoomOverlay = ({
|
||||
if (displayTimerRef.current) {
|
||||
cancelAnimationFrame(displayTimerRef.current);
|
||||
}
|
||||
if (clickTimerRef.current) {
|
||||
clearTimeout(clickTimerRef.current);
|
||||
clickTimerRef.current = null;
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setIsNativeScale(false);
|
||||
setNaturalSize({ width: null, height: null });
|
||||
focusRef.current = null;
|
||||
if (clickTimerRef.current) {
|
||||
clearTimeout(clickTimerRef.current);
|
||||
clickTimerRef.current = null;
|
||||
}
|
||||
const scrollEl = scrollRef.current;
|
||||
if (scrollEl) {
|
||||
scrollEl.scrollLeft = 0;
|
||||
@@ -198,6 +209,45 @@ const PreviewZoomOverlay = ({
|
||||
|
||||
const effectiveDisplay = activeDisplay;
|
||||
const navVisible = Boolean(effectiveDisplay?.canGoPrev || effectiveDisplay?.canGoNext);
|
||||
|
||||
const toggleZoomAtPoint = (clientX, clientY) => {
|
||||
const img = imageRef.current;
|
||||
setIsNativeScale((current) => {
|
||||
if (!current && img) {
|
||||
const rect = img.getBoundingClientRect();
|
||||
const xRatio = rect.width > 0 ? (clientX - rect.left) / rect.width : 0.5;
|
||||
const yRatio = rect.height > 0 ? (clientY - rect.top) / rect.height : 0.5;
|
||||
focusRef.current = {
|
||||
xRatio: clamp(xRatio, 0, 1),
|
||||
yRatio: clamp(yRatio, 0, 1),
|
||||
};
|
||||
} else {
|
||||
focusRef.current = null;
|
||||
}
|
||||
return !current;
|
||||
});
|
||||
};
|
||||
|
||||
const handleImagePointerDown = (event) => {
|
||||
event.stopPropagation();
|
||||
if (event.button && event.button !== 0) {
|
||||
return;
|
||||
}
|
||||
if (event.pointerType === 'touch' && event.isPrimary === false) {
|
||||
return;
|
||||
}
|
||||
if (clickTimerRef.current) {
|
||||
clearTimeout(clickTimerRef.current);
|
||||
clickTimerRef.current = null;
|
||||
toggleZoomAtPoint(event.clientX, event.clientY);
|
||||
return;
|
||||
}
|
||||
|
||||
clickTimerRef.current = setTimeout(() => {
|
||||
clickTimerRef.current = null;
|
||||
onClose();
|
||||
}, CLICK_DELAY_MS);
|
||||
};
|
||||
const stageClassName = [
|
||||
'preview-zoom__stage',
|
||||
]
|
||||
@@ -225,11 +275,13 @@ const PreviewZoomOverlay = ({
|
||||
height: naturalSize.height ? `${naturalSize.height}px` : 'auto',
|
||||
maxWidth: 'none',
|
||||
maxHeight: 'none',
|
||||
touchAction: 'manipulation',
|
||||
}
|
||||
: {
|
||||
cursor: 'zoom-in',
|
||||
maxWidth: '95vw',
|
||||
maxHeight: '95vh',
|
||||
touchAction: 'manipulation',
|
||||
};
|
||||
|
||||
return createPortal(
|
||||
@@ -263,26 +315,7 @@ const PreviewZoomOverlay = ({
|
||||
height: event.currentTarget.naturalHeight || null,
|
||||
});
|
||||
}}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
if (!isNativeScale) {
|
||||
const img = imageRef.current;
|
||||
if (img) {
|
||||
const rect = img.getBoundingClientRect();
|
||||
const xRatio = rect.width > 0 ? (event.clientX - rect.left) / rect.width : 0.5;
|
||||
const yRatio = rect.height > 0 ? (event.clientY - rect.top) / rect.height : 0.5;
|
||||
focusRef.current = {
|
||||
xRatio: clamp(xRatio, 0, 1),
|
||||
yRatio: clamp(yRatio, 0, 1),
|
||||
};
|
||||
} else {
|
||||
focusRef.current = null;
|
||||
}
|
||||
} else {
|
||||
focusRef.current = null;
|
||||
}
|
||||
setIsNativeScale((current) => !current);
|
||||
}}
|
||||
onPointerDown={handleImagePointerDown}
|
||||
style={imageStyle}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -2482,7 +2482,7 @@ button.danger:hover:not([disabled]) {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: var(--detail-panel-width);
|
||||
width: min(100vw, var(--detail-panel-width));
|
||||
min-height: 100vh;
|
||||
height: 100%;
|
||||
height: 100%;
|
||||
|
||||
Reference in New Issue
Block a user