feat(ui): support reset canvas view when no image on canvas

This commit is contained in:
psychedelicious 2024-01-09 18:41:14 +11:00 committed by Kent Keirsey
parent 68a231afea
commit ebd68b7a6c
3 changed files with 63 additions and 52 deletions

View File

@ -1,27 +1,33 @@
// https://stackoverflow.com/a/73731908
import { useCallback, useEffect, useState } from 'react';
export function useSingleAndDoubleClick(
handleSingleClick: () => void,
handleDoubleClick: () => void,
delay = 250
) {
export type UseSingleAndDoubleClickOptions = {
onSingleClick: () => void;
onDoubleClick: () => void;
latency?: number;
};
export function useSingleAndDoubleClick({
onSingleClick,
onDoubleClick,
latency = 250,
}: UseSingleAndDoubleClickOptions): () => void {
const [click, setClick] = useState(0);
useEffect(() => {
const timer = setTimeout(() => {
if (click === 1) {
handleSingleClick();
onSingleClick();
}
setClick(0);
}, delay);
}, latency);
if (click === 2) {
handleDoubleClick();
onDoubleClick();
}
return () => clearTimeout(timer);
}, [click, handleSingleClick, handleDoubleClick, delay]);
}, [click, onDoubleClick, latency, onSingleClick]);
const onClick = useCallback(() => setClick((prev) => prev + 1), []);

View File

@ -15,7 +15,7 @@ import {
canvasMerged,
canvasSavedToGallery,
} from 'features/canvas/store/actions';
import { $canvasBaseLayer,$tool } from 'features/canvas/store/canvasNanostore';
import { $canvasBaseLayer, $tool } from 'features/canvas/store/canvasNanostore';
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
import {
resetCanvas,
@ -135,26 +135,35 @@ const IAICanvasToolbar = () => {
$tool.set('move');
}, []);
const handleClickResetCanvasView = useSingleAndDoubleClick(
() => handleResetCanvasView(false),
() => handleResetCanvasView(true)
const handleResetCanvasView = useCallback(
(shouldScaleTo1 = false) => {
const canvasBaseLayer = $canvasBaseLayer.get();
if (!canvasBaseLayer) {
return;
}
const clientRect = canvasBaseLayer.getClientRect({
skipTransform: true,
});
dispatch(
resetCanvasView({
contentRect: clientRect,
shouldScaleTo1,
})
);
},
[dispatch]
);
const onSingleClick = useCallback(() => {
handleResetCanvasView(false);
}, [handleResetCanvasView]);
const onDoubleClick = useCallback(() => {
handleResetCanvasView(true);
}, [handleResetCanvasView]);
const handleResetCanvasView = (shouldScaleTo1 = false) => {
const canvasBaseLayer = $canvasBaseLayer.get();
if (!canvasBaseLayer) {
return;
}
const clientRect = canvasBaseLayer.getClientRect({
skipTransform: true,
});
dispatch(
resetCanvasView({
contentRect: clientRect,
shouldScaleTo1,
})
);
};
const handleClickResetCanvasView = useSingleAndDoubleClick({
onSingleClick,
onDoubleClick,
});
const handleResetCanvas = useCallback(() => {
dispatch(resetCanvas());

View File

@ -488,32 +488,28 @@ export const canvasSlice = createSlice({
stageDimensions: { width: stageWidth, height: stageHeight },
} = state;
const { x, y, width, height } = contentRect;
const newScale = shouldScaleTo1
? 1
: calculateScale(
stageWidth,
stageHeight,
contentRect.width || state.boundingBoxDimensions.width,
contentRect.height || state.boundingBoxDimensions.height,
STAGE_PADDING_PERCENTAGE
);
if (width !== 0 && height !== 0) {
const newScale = shouldScaleTo1
? 1
: calculateScale(
stageWidth,
stageHeight,
width,
height,
STAGE_PADDING_PERCENTAGE
);
const newCoordinates = calculateCoordinates(
stageWidth,
stageHeight,
contentRect.x || state.boundingBoxCoordinates.x,
contentRect.y || state.boundingBoxCoordinates.y,
contentRect.width || state.boundingBoxDimensions.width,
contentRect.height || state.boundingBoxDimensions.height,
newScale
);
const newCoordinates = calculateCoordinates(
stageWidth,
stageHeight,
x,
y,
width,
height,
newScale
);
state.stageScale = newScale;
state.stageCoordinates = newCoordinates;
}
state.stageScale = newScale;
state.stageCoordinates = newCoordinates;
},
nextStagingAreaImage: (state) => {
if (!state.layerState.stagingArea.images.length) {