mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): bbox tool
This commit is contained in:
parent
95d6183a6c
commit
6c1d1588fc
@ -11,7 +11,14 @@ import {
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PiArrowsOutCardinalBold, PiEraserBold, PiHandBold, PiPaintBrushBold, PiRectangleBold } from 'react-icons/pi';
|
import {
|
||||||
|
PiArrowsOutCardinalBold,
|
||||||
|
PiBoundingBoxBold,
|
||||||
|
PiEraserBold,
|
||||||
|
PiHandBold,
|
||||||
|
PiPaintBrushBold,
|
||||||
|
PiRectangleBold,
|
||||||
|
} from 'react-icons/pi';
|
||||||
|
|
||||||
const selectIsDisabled = createSelector(selectControlLayersSlice, (controlLayers) => {
|
const selectIsDisabled = createSelector(selectControlLayersSlice, (controlLayers) => {
|
||||||
const selectedLayer = controlLayers.present.layers.find((l) => l.id === controlLayers.present.selectedLayerId);
|
const selectedLayer = controlLayers.present.layers.find((l) => l.id === controlLayers.present.selectedLayerId);
|
||||||
@ -45,6 +52,10 @@ export const ToolChooser: React.FC = () => {
|
|||||||
$tool.set('view');
|
$tool.set('view');
|
||||||
}, []);
|
}, []);
|
||||||
useHotkeys('h', setToolToView, { enabled: !isDisabled }, [isDisabled]);
|
useHotkeys('h', setToolToView, { enabled: !isDisabled }, [isDisabled]);
|
||||||
|
const setToolToBbox = useCallback(() => {
|
||||||
|
$tool.set('bbox');
|
||||||
|
}, []);
|
||||||
|
useHotkeys('q', setToolToBbox, { enabled: !isDisabled }, [isDisabled]);
|
||||||
|
|
||||||
const resetSelectedLayer = useCallback(() => {
|
const resetSelectedLayer = useCallback(() => {
|
||||||
if (selectedLayerId === null) {
|
if (selectedLayerId === null) {
|
||||||
@ -101,6 +112,14 @@ export const ToolChooser: React.FC = () => {
|
|||||||
onClick={setToolToView}
|
onClick={setToolToView}
|
||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
/>
|
/>
|
||||||
|
<IconButton
|
||||||
|
aria-label={`${t('controlLayers.bbox')} (Q)`}
|
||||||
|
tooltip={`${t('controlLayers.bbox')} (Q)`}
|
||||||
|
icon={<PiBoundingBoxBold />}
|
||||||
|
variant={tool === 'bbox' ? 'solid' : 'outline'}
|
||||||
|
onClick={setToolToBbox}
|
||||||
|
isDisabled={isDisabled}
|
||||||
|
/>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -62,10 +62,10 @@ export const getBboxPreviewGroup = (
|
|||||||
|
|
||||||
// Use a transformer for the generation bbox. Transformers need some shape to transform, we will use a fully
|
// Use a transformer for the generation bbox. Transformers need some shape to transform, we will use a fully
|
||||||
// transparent rect for this purpose.
|
// transparent rect for this purpose.
|
||||||
bboxPreviewGroup = new Konva.Group({ id: PREVIEW_GENERATION_BBOX_GROUP });
|
bboxPreviewGroup = new Konva.Group({ id: PREVIEW_GENERATION_BBOX_GROUP, listening: false });
|
||||||
const bboxRect = new Konva.Rect({
|
const bboxRect = new Konva.Rect({
|
||||||
id: PREVIEW_GENERATION_BBOX_DUMMY_RECT,
|
id: PREVIEW_GENERATION_BBOX_DUMMY_RECT,
|
||||||
listening: true,
|
listening: false,
|
||||||
strokeEnabled: false,
|
strokeEnabled: false,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
...getBbox(),
|
...getBbox(),
|
||||||
@ -269,12 +269,10 @@ export const renderBboxPreview = (
|
|||||||
);
|
);
|
||||||
const bboxRect = bboxGroup.findOne<Konva.Rect>(`#${PREVIEW_GENERATION_BBOX_DUMMY_RECT}`);
|
const bboxRect = bboxGroup.findOne<Konva.Rect>(`#${PREVIEW_GENERATION_BBOX_DUMMY_RECT}`);
|
||||||
const bboxTransformer = bboxGroup.findOne<Konva.Transformer>(`#${PREVIEW_GENERATION_BBOX_TRANSFORMER}`);
|
const bboxTransformer = bboxGroup.findOne<Konva.Transformer>(`#${PREVIEW_GENERATION_BBOX_TRANSFORMER}`);
|
||||||
|
bboxGroup.listening(tool === 'bbox');
|
||||||
// This updates the bbox during transformation
|
// This updates the bbox during transformation
|
||||||
bboxRect?.setAttrs({ ...bbox, scaleX: 1, scaleY: 1, listening: tool === 'move' });
|
bboxRect?.setAttrs({ ...bbox, scaleX: 1, scaleY: 1, listening: tool === 'bbox' });
|
||||||
bboxTransformer?.setAttrs({
|
bboxTransformer?.setAttrs({ listening: tool === 'bbox', enabledAnchors: tool === 'bbox' ? ALL_ANCHORS : NO_ANCHORS });
|
||||||
listening: tool === 'move',
|
|
||||||
enabledAnchors: tool === 'move' ? ALL_ANCHORS : NO_ANCHORS,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getToolPreviewGroup = (stage: Konva.Stage): Konva.Group => {
|
export const getToolPreviewGroup = (stage: Konva.Stage): Konva.Group => {
|
||||||
@ -365,9 +363,11 @@ export const renderToolPreview = (
|
|||||||
} else if (tool === 'rect') {
|
} else if (tool === 'rect') {
|
||||||
// Rect gets a crosshair
|
// Rect gets a crosshair
|
||||||
stage.container().style.cursor = 'crosshair';
|
stage.container().style.cursor = 'crosshair';
|
||||||
} else {
|
} else if (tool === 'brush' || tool === 'eraser') {
|
||||||
// Else we hide the native cursor and use the konva-rendered brush preview
|
// Hide the native cursor and use the konva-rendered brush preview
|
||||||
stage.container().style.cursor = 'none';
|
stage.container().style.cursor = 'none';
|
||||||
|
} else if (tool === 'bbox') {
|
||||||
|
stage.container().style.cursor = 'default';
|
||||||
}
|
}
|
||||||
|
|
||||||
stage.draggable(tool === 'view');
|
stage.draggable(tool === 'view');
|
||||||
|
@ -23,7 +23,7 @@ import type { IRect } from 'konva/lib/types';
|
|||||||
import type { ImageDTO } from 'services/api/types';
|
import type { ImageDTO } from 'services/api/types';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
const zTool = z.enum(['brush', 'eraser', 'move', 'rect', 'view']);
|
const zTool = z.enum(['brush', 'eraser', 'move', 'rect', 'view', 'bbox']);
|
||||||
export type Tool = z.infer<typeof zTool>;
|
export type Tool = z.infer<typeof zTool>;
|
||||||
const zDrawingTool = zTool.extract(['brush', 'eraser']);
|
const zDrawingTool = zTool.extract(['brush', 'eraser']);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user