fix lightbox display modes (#4644)

This commit is contained in:
CJ 2024-03-05 03:37:39 +01:00 committed by GitHub
parent 2ca9e0f43a
commit 0626a7aea1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 50 additions and 18 deletions

View File

@ -98,8 +98,11 @@ export const LightboxImage: React.FC<IProps> = ({
const [moving, setMoving] = useState(false); const [moving, setMoving] = useState(false);
const [positionX, setPositionX] = useState(0); const [positionX, setPositionX] = useState(0);
const [positionY, setPositionY] = useState(0); const [positionY, setPositionY] = useState(0);
const [imageWidth, setImageWidth] = useState(width);
const [imageHeight, setImageHeight] = useState(height);
const [boxWidth, setBoxWidth] = useState(0); const [boxWidth, setBoxWidth] = useState(0);
const [boxHeight, setBoxHeight] = useState(0); const [boxHeight, setBoxHeight] = useState(0);
const dimensionsProvided = width > 0 && height > 0;
const mouseDownEvent = useRef<MouseEvent>(); const mouseDownEvent = useRef<MouseEvent>();
const resetPositionRef = useRef(resetPosition); const resetPositionRef = useRef(resetPosition);
@ -137,41 +140,62 @@ export const LightboxImage: React.FC<IProps> = ({
}, 250); }, 250);
}, [container]); }, [container]);
useEffect(() => {
if (dimensionsProvided) {
return;
}
let mounted = true;
const img = new Image();
function onLoad() {
if (mounted) {
setImageWidth(img.width);
setImageHeight(img.height);
}
}
img.onload = onLoad;
img.src = src;
return () => {
mounted = false;
};
}, [src, dimensionsProvided]);
const minMaxY = useCallback( const minMaxY = useCallback(
(appliedZoom: number) => { (appliedZoom: number) => {
let minY, maxY: number; let minY, maxY: number;
const inBounds = appliedZoom * height <= boxHeight; const inBounds = appliedZoom * imageHeight <= boxHeight;
// NOTE: I don't even know how these work, but they do // NOTE: I don't even know how these work, but they do
if (!inBounds) { if (!inBounds) {
if (height > boxHeight) { if (imageHeight > boxHeight) {
minY = minY =
(appliedZoom * height - height) / 2 - (appliedZoom * imageHeight - imageHeight) / 2 -
appliedZoom * height + appliedZoom * imageHeight +
boxHeight; boxHeight;
maxY = (appliedZoom * height - height) / 2; maxY = (appliedZoom * imageHeight - imageHeight) / 2;
} else { } else {
minY = (boxHeight - appliedZoom * height) / 2; minY = (boxHeight - appliedZoom * imageHeight) / 2;
maxY = (appliedZoom * height - boxHeight) / 2; maxY = (appliedZoom * imageHeight - boxHeight) / 2;
} }
} else { } else {
minY = Math.min((boxHeight - height) / 2, 0); minY = Math.min((boxHeight - imageHeight) / 2, 0);
maxY = minY; maxY = minY;
} }
return [minY, maxY]; return [minY, maxY];
}, },
[height, boxHeight] [imageHeight, boxHeight]
); );
const calculateInitialPosition = useCallback( const calculateInitialPosition = useCallback(
(appliedZoom: number) => { (appliedZoom: number) => {
// Center image from container's center // Center image from container's center
const newPositionX = Math.min((boxWidth - width) / 2, 0); const newPositionX = Math.min((boxWidth - imageWidth) / 2, 0);
let newPositionY: number; let newPositionY: number;
if (displayMode === GQL.ImageLightboxDisplayMode.FitXy) { if (displayMode === GQL.ImageLightboxDisplayMode.FitXy) {
newPositionY = Math.min((boxHeight - height) / 2, 0); newPositionY = Math.min((boxHeight - imageHeight) / 2, 0);
} else { } else {
// otherwise, align image with container // otherwise, align image with container
const [minY, maxY] = minMaxY(appliedZoom); const [minY, maxY] = minMaxY(appliedZoom);
@ -184,16 +208,24 @@ export const LightboxImage: React.FC<IProps> = ({
return [newPositionX, newPositionY]; return [newPositionX, newPositionY];
}, },
[displayMode, boxWidth, width, boxHeight, height, alignBottom, minMaxY] [
displayMode,
boxWidth,
imageWidth,
boxHeight,
imageHeight,
alignBottom,
minMaxY,
]
); );
useEffect(() => { useEffect(() => {
// don't set anything until we have the dimensions // don't set anything until we have the dimensions
if (!width || !height || !boxWidth || !boxHeight) { if (!imageWidth || !imageHeight || !boxWidth || !boxHeight) {
return; return;
} }
if (!scaleUp && width < boxWidth && height < boxHeight) { if (!scaleUp && imageWidth < boxWidth && imageHeight < boxHeight) {
setDefaultZoom(1); setDefaultZoom(1);
setPositionX(0); setPositionX(0);
setPositionY(0); setPositionY(0);
@ -202,8 +234,8 @@ export const LightboxImage: React.FC<IProps> = ({
// set initial zoom level based on options // set initial zoom level based on options
const newZoom = calculateDefaultZoom( const newZoom = calculateDefaultZoom(
width, imageWidth,
height, imageHeight,
boxWidth, boxWidth,
boxHeight, boxHeight,
displayMode, displayMode,
@ -223,8 +255,8 @@ export const LightboxImage: React.FC<IProps> = ({
scrollAttempts.current = -scrollAttemptsBeforeChange; scrollAttempts.current = -scrollAttemptsBeforeChange;
} }
}, [ }, [
width, imageWidth,
height, imageHeight,
boxWidth, boxWidth,
boxHeight, boxHeight,
displayMode, displayMode,