ui: Make aspect ratio logic more robust

This commit is contained in:
blessedcoolant 2023-08-30 10:15:26 +12:00
parent c6bab14043
commit 65fb6af01f
4 changed files with 62 additions and 28 deletions

View File

@ -13,7 +13,9 @@ import { useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { FaLock } from 'react-icons/fa'; import { FaLock } from 'react-icons/fa';
import { MdOutlineSwapVert } from 'react-icons/md'; import { MdOutlineSwapVert } from 'react-icons/md';
import ParamAspectRatio from '../../Core/ParamAspectRatio'; import ParamAspectRatio, {
mappedAspectRatios,
} from '../../Core/ParamAspectRatio';
import ParamBoundingBoxHeight from './ParamBoundingBoxHeight'; import ParamBoundingBoxHeight from './ParamBoundingBoxHeight';
import ParamBoundingBoxWidth from './ParamBoundingBoxWidth'; import ParamBoundingBoxWidth from './ParamBoundingBoxWidth';
@ -39,12 +41,43 @@ export default function ParamBoundingBoxSize() {
useAppSelector(sizeOptsSelector); useAppSelector(sizeOptsSelector);
const handleLockRatio = useCallback(() => { const handleLockRatio = useCallback(() => {
dispatch( if (shouldLockAspectRatio) {
setAspectRatio(boundingBoxDimensions.width / boundingBoxDimensions.height) dispatch(setShouldLockAspectRatio(false));
); if (
dispatch(setShouldLockAspectRatio(!shouldLockAspectRatio)); !mappedAspectRatios.includes(
boundingBoxDimensions.width / boundingBoxDimensions.height
)
) {
dispatch(setAspectRatio(null));
} else {
dispatch(
setAspectRatio(
boundingBoxDimensions.width / boundingBoxDimensions.height
)
);
}
} else {
dispatch(setShouldLockAspectRatio(true));
dispatch(
setAspectRatio(
boundingBoxDimensions.width / boundingBoxDimensions.height
)
);
}
}, [shouldLockAspectRatio, boundingBoxDimensions, dispatch]); }, [shouldLockAspectRatio, boundingBoxDimensions, dispatch]);
const handleToggleSize = useCallback(() => {
dispatch(flipBoundingBoxAxes());
dispatch(setAspectRatio(null));
if (shouldLockAspectRatio) {
dispatch(
setAspectRatio(
boundingBoxDimensions.height / boundingBoxDimensions.width
)
);
}
}, [dispatch, shouldLockAspectRatio, boundingBoxDimensions]);
return ( return (
<Flex <Flex
sx={{ sx={{
@ -80,16 +113,7 @@ export default function ParamBoundingBoxSize() {
size="sm" size="sm"
icon={<MdOutlineSwapVert />} icon={<MdOutlineSwapVert />}
fontSize={20} fontSize={20}
onClick={() => { onClick={handleToggleSize}
dispatch(flipBoundingBoxAxes());
if (
![null, 2 / 3, 16 / 9, 1 / 1].includes(
boundingBoxDimensions.height / boundingBoxDimensions.width
)
) {
dispatch(setAspectRatio(null));
}
}}
/> />
<IAIIconButton <IAIIconButton
tooltip={t('ui.lockRatio')} tooltip={t('ui.lockRatio')}

View File

@ -15,6 +15,8 @@ const aspectRatios = [
{ name: '1:1', value: 1 / 1 }, { name: '1:1', value: 1 / 1 },
]; ];
export const mappedAspectRatios = aspectRatios.map((ar) => ar.value);
export default function ParamAspectRatio() { export default function ParamAspectRatio() {
const aspectRatio = useAppSelector( const aspectRatio = useAppSelector(
(state: RootState) => state.generation.aspectRatio (state: RootState) => state.generation.aspectRatio

View File

@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next';
import { FaLock } from 'react-icons/fa'; import { FaLock } from 'react-icons/fa';
import { MdOutlineSwapVert } from 'react-icons/md'; import { MdOutlineSwapVert } from 'react-icons/md';
import { activeTabNameSelector } from '../../../../ui/store/uiSelectors'; import { activeTabNameSelector } from '../../../../ui/store/uiSelectors';
import ParamAspectRatio from './ParamAspectRatio'; import ParamAspectRatio, { mappedAspectRatios } from './ParamAspectRatio';
import ParamHeight from './ParamHeight'; import ParamHeight from './ParamHeight';
import ParamWidth from './ParamWidth'; import ParamWidth from './ParamWidth';
@ -45,10 +45,27 @@ export default function ParamSize() {
} = useAppSelector(sizeOptsSelector); } = useAppSelector(sizeOptsSelector);
const handleLockRatio = useCallback(() => { const handleLockRatio = useCallback(() => {
dispatch(setAspectRatio(width / height)); if (shouldLockAspectRatio) {
dispatch(setShouldLockAspectRatio(!shouldLockAspectRatio)); dispatch(setShouldLockAspectRatio(false));
if (!mappedAspectRatios.includes(width / height)) {
dispatch(setAspectRatio(null));
} else {
dispatch(setAspectRatio(width / height));
}
} else {
dispatch(setShouldLockAspectRatio(true));
dispatch(setAspectRatio(width / height));
}
}, [shouldLockAspectRatio, width, height, dispatch]); }, [shouldLockAspectRatio, width, height, dispatch]);
const handleToggleSize = useCallback(() => {
dispatch(toggleSize());
dispatch(setAspectRatio(null));
if (shouldLockAspectRatio) {
dispatch(setAspectRatio(height / width));
}
}, [dispatch, shouldLockAspectRatio, width, height]);
return ( return (
<Flex <Flex
sx={{ sx={{
@ -87,7 +104,7 @@ export default function ParamSize() {
isDisabled={ isDisabled={
activeTabName === 'img2img' ? !shouldFitToWidthHeight : false activeTabName === 'img2img' ? !shouldFitToWidthHeight : false
} }
onClick={() => dispatch(toggleSize())} onClick={handleToggleSize}
/> />
<IAIIconButton <IAIIconButton
tooltip={t('ui.lockRatio')} tooltip={t('ui.lockRatio')}

View File

@ -152,9 +152,6 @@ export const generationSlice = createSlice({
}, },
toggleSize: (state) => { toggleSize: (state) => {
const [width, height] = [state.width, state.height]; const [width, height] = [state.width, state.height];
if (![null, 2 / 3, 16 / 9, 1 / 1].includes(height / width)) {
state.aspectRatio = null;
}
state.width = height; state.width = height;
state.height = width; state.height = width;
}, },
@ -278,12 +275,6 @@ export const generationSlice = createSlice({
} }
}, },
setShouldLockAspectRatio: (state, action: PayloadAction<boolean>) => { setShouldLockAspectRatio: (state, action: PayloadAction<boolean>) => {
if (
action.payload === false &&
![null, 2 / 3, 16 / 9, 1 / 1].includes(state.aspectRatio)
) {
state.aspectRatio = null;
}
state.shouldLockAspectRatio = action.payload; state.shouldLockAspectRatio = action.payload;
}, },
}, },