feat(ui): slider working for all aspect ratios

This commit is contained in:
psychedelicious
2024-05-31 13:42:19 +10:00
parent c2eef93476
commit 72bbcb2d94

View File

@ -1,5 +1,6 @@
import { Box, Flex, Icon } from '@invoke-ai/ui-library'; import { Box, Flex, Icon } from '@invoke-ai/ui-library';
import { useMeasure } from '@reactuses/core'; import { useMeasure } from '@reactuses/core';
import type { Dimensions } from 'features/canvas/store/canvasTypes';
import { memo, useCallback, useMemo, useRef } from 'react'; import { memo, useCallback, useMemo, useRef } from 'react';
import { PiCaretLeftBold, PiCaretRightBold } from 'react-icons/pi'; import { PiCaretLeftBold, PiCaretRightBold } from 'react-icons/pi';
import type { ImageDTO } from 'services/api/types'; import type { ImageDTO } from 'services/api/types';
@ -55,24 +56,32 @@ export const ImageSliderComparison = memo(({ firstImage, secondImage }: Props) =
[onMouseMove, onMouseUp, updateHandlePos] [onMouseMove, onMouseUp, updateHandlePos]
); );
const fittedSize = useMemo(() => { const fittedSize = useMemo<Dimensions>(() => {
let width = containerSize.width; // Fit the first image to the container
let height = containerSize.height; const targetAspectRatio = containerSize.width / containerSize.height;
const aspectRatio = firstImage.width / firstImage.height; const imageAspectRatio = firstImage.width / firstImage.height;
if (firstImage.width > firstImage.height) {
width = firstImage.width; if (firstImage.width <= containerSize.width && firstImage.height <= containerSize.height) {
height = width / aspectRatio; return { width: firstImage.width, height: firstImage.height };
}
let width: number;
let height: number;
if (imageAspectRatio > targetAspectRatio) {
// Image is wider than container's aspect ratio
width = containerSize.width;
height = width / imageAspectRatio;
} else { } else {
height = firstImage.height; // Image is taller than container's aspect ratio
width = height * aspectRatio; height = containerSize.height;
width = height * imageAspectRatio;
} }
return { width, height }; return { width, height };
}, [containerSize.height, containerSize.width, firstImage.height, firstImage.width]); }, [containerSize.height, containerSize.width, firstImage]);
console.log({ containerSize, fittedSize });
return ( return (
<Flex w="full" h="full" maxW="full" maxH="full" position="relative" alignItems="center" justifyContent="center"> <Flex w="full" h="full" maxW="full" maxH="full" position="relative" alignItems="center" justifyContent="center" bg='green'>
<Flex <Flex
id="image-comparison-container" id="image-comparison-container"
ref={containerRef} ref={containerRef}
@ -81,13 +90,12 @@ export const ImageSliderComparison = memo(({ firstImage, secondImage }: Props) =
maxW="full" maxW="full"
maxH="full" maxH="full"
position="relative" position="relative"
border="1px solid cyan"
alignItems="center" alignItems="center"
justifyContent="center" justifyContent="center"
> >
<Box <Box
position="relative" position="relative"
id="image-comparison-first-image-container" id="image-comparison-second-image-container"
w={fittedSize.width} w={fittedSize.width}
h={fittedSize.height} h={fittedSize.height}
maxW="full" maxW="full"
@ -96,18 +104,17 @@ export const ImageSliderComparison = memo(({ firstImage, secondImage }: Props) =
backgroundSize="contain" backgroundSize="contain"
backgroundRepeat="no-repeat" backgroundRepeat="no-repeat"
userSelect="none" userSelect="none"
border="1px solid green"
overflow="hidden" overflow="hidden"
> >
<Box <Box
id="image-comparison-second-image-container" id="image-comparison-first-image-container"
ref={secondImageContainerRef} ref={secondImageContainerRef}
backgroundImage={`url(${firstImage.image_url})`} backgroundImage={`url(${firstImage.image_url})`}
backgroundSize="auto" backgroundSize={`${fittedSize.width}px ${fittedSize.height}px`}
backgroundPosition="top left" backgroundPosition="top left"
backgroundRepeat="no-repeat" backgroundRepeat="no-repeat"
w={INITIAL_POS} w={INITIAL_POS}
h="full" h={fittedSize.height}
maxW="full" maxW="full"
maxH="full" maxH="full"
position="absolute" position="absolute"
@ -137,7 +144,14 @@ export const ImageSliderComparison = memo(({ firstImage, secondImage }: Props) =
top={0} top={0}
left={HANDLE_INNER_LEFT_INITIAL_PX} left={HANDLE_INNER_LEFT_INITIAL_PX}
/> />
<Flex gap={4} position="absolute" left="50%" top="50%" transform="translate(-50%, 0)"> <Flex
gap={4}
position="absolute"
left="50%"
top="50%"
transform="translate(-50%, 0)"
filter="drop-shadow(0px 0px 4px rgb(0, 0, 0)) drop-shadow(0px 0px 4px rgb(0, 0, 0))"
>
<Icon as={PiCaretLeftBold} /> <Icon as={PiCaretLeftBold} />
<Icon as={PiCaretRightBold} /> <Icon as={PiCaretRightBold} />
</Flex> </Flex>
@ -151,7 +165,6 @@ export const ImageSliderComparison = memo(({ firstImage, secondImage }: Props) =
left={0} left={0}
onMouseDown={onMouseDown} onMouseDown={onMouseDown}
userSelect="none" userSelect="none"
bg="rgba(255,0,0,0.3)"
/> />
</Box> </Box>
</Flex> </Flex>