mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
fix(ui): bbox not centered on very first app startup
This commit is contained in:
committed by
Kent Keirsey
parent
dfac0292f4
commit
1d61a587ee
@@ -98,7 +98,6 @@ export class CanvasStageModule extends CanvasModuleBase {
|
||||
this.konva.stage.container(this.container);
|
||||
this.setResizeObserver();
|
||||
this.fitStageToContainer();
|
||||
this.fitLayersToStage();
|
||||
|
||||
this.konva.stage.on('wheel', this.onStageMouseWheel);
|
||||
this.konva.stage.on('dragmove', this.onStageDragMove);
|
||||
|
||||
@@ -1,26 +1,60 @@
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { buildUseBoolean } from 'common/hooks/useBoolean';
|
||||
import { useCanvasManagerSafe } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
|
||||
import { imageSelected, imageToCompareChanged } from 'features/gallery/store/gallerySlice';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
/**
|
||||
* There's a race condition that causes the canvas to not fit to layers on the very first app startup.
|
||||
*
|
||||
* The canvas stage uses a resize observer to fit the stage to the container, and on the first resize event, it also
|
||||
* fits the layers to the stage. Subsequent resize events only fit the stage to the container, they do not fit layers
|
||||
* to the stage.
|
||||
*
|
||||
* On the very first app startup (new user or after they reset all web UI state), the resizable panels library needs
|
||||
* to do one extra resize as it initializes and figures out its target size. At this time, the canvas stage has already
|
||||
* done its one-time fit layers to stage, so the canvas stage does not fit layers to the stage again.
|
||||
*
|
||||
* For the end user, this means that the bbox is not centered in the canvas stage on the very first app startup. On
|
||||
* all subsequent app startups, the bbox is centered in the canvas stage.
|
||||
*
|
||||
* We can hack around this, thanks to the fact that the image viewer is always opened on the first app startup. By the
|
||||
* time the user closes it, the resizable panels library has already done its one extra resize and the DOM layout has
|
||||
* stablized. So we can track the first time the image viewer is closed and fit the layers to the stage at that time,
|
||||
* ensuring that the bbox is centered in the canvas stage on that first app startup.
|
||||
*
|
||||
* TODO(psyche): Figure out a better way to do handle this...
|
||||
*/
|
||||
let didCloseImageViewer = false;
|
||||
const [useImageViewerState, $imageViewerState] = buildUseBoolean(true);
|
||||
|
||||
export const useImageViewer = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const canvasManager = useCanvasManagerSafe();
|
||||
const imageViewerState = useImageViewerState();
|
||||
const isOpen = useMemo(() => imageViewerState.isTrue, [imageViewerState]);
|
||||
const open = useMemo(() => imageViewerState.setTrue, [imageViewerState]);
|
||||
const close = useMemo(() => imageViewerState.setFalse, [imageViewerState]);
|
||||
const toggle = useMemo(() => imageViewerState.toggle, [imageViewerState]);
|
||||
const close = useCallback(() => {
|
||||
if (!didCloseImageViewer && canvasManager) {
|
||||
didCloseImageViewer = true;
|
||||
canvasManager.stage.fitLayersToStage();
|
||||
}
|
||||
imageViewerState.setFalse();
|
||||
}, [canvasManager, imageViewerState]);
|
||||
const openImageInViewer = useCallback(
|
||||
(imageDTO: ImageDTO) => {
|
||||
dispatch(imageToCompareChanged(null));
|
||||
dispatch(imageSelected(imageDTO));
|
||||
open();
|
||||
imageViewerState.setTrue();
|
||||
},
|
||||
[dispatch, open]
|
||||
[dispatch, imageViewerState]
|
||||
);
|
||||
|
||||
return { isOpen, open, close, toggle, $state: $imageViewerState, openImageInViewer };
|
||||
return {
|
||||
isOpen: imageViewerState.isTrue,
|
||||
open: imageViewerState.setTrue,
|
||||
close,
|
||||
toggle: imageViewerState.toggle,
|
||||
$state: $imageViewerState,
|
||||
openImageInViewer,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user