mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): support reset canvas view when no image on canvas
This commit is contained in:
parent
68a231afea
commit
ebd68b7a6c
@ -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), []);
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user