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 { useHotkeys } from 'react-hotkeys-hook';
|
||||
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 selectedLayer = controlLayers.present.layers.find((l) => l.id === controlLayers.present.selectedLayerId);
|
||||
@ -45,6 +52,10 @@ export const ToolChooser: React.FC = () => {
|
||||
$tool.set('view');
|
||||
}, []);
|
||||
useHotkeys('h', setToolToView, { enabled: !isDisabled }, [isDisabled]);
|
||||
const setToolToBbox = useCallback(() => {
|
||||
$tool.set('bbox');
|
||||
}, []);
|
||||
useHotkeys('q', setToolToBbox, { enabled: !isDisabled }, [isDisabled]);
|
||||
|
||||
const resetSelectedLayer = useCallback(() => {
|
||||
if (selectedLayerId === null) {
|
||||
@ -101,6 +112,14 @@ export const ToolChooser: React.FC = () => {
|
||||
onClick={setToolToView}
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
@ -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
|
||||
// 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({
|
||||
id: PREVIEW_GENERATION_BBOX_DUMMY_RECT,
|
||||
listening: true,
|
||||
listening: false,
|
||||
strokeEnabled: false,
|
||||
draggable: true,
|
||||
...getBbox(),
|
||||
@ -269,12 +269,10 @@ export const renderBboxPreview = (
|
||||
);
|
||||
const bboxRect = bboxGroup.findOne<Konva.Rect>(`#${PREVIEW_GENERATION_BBOX_DUMMY_RECT}`);
|
||||
const bboxTransformer = bboxGroup.findOne<Konva.Transformer>(`#${PREVIEW_GENERATION_BBOX_TRANSFORMER}`);
|
||||
bboxGroup.listening(tool === 'bbox');
|
||||
// This updates the bbox during transformation
|
||||
bboxRect?.setAttrs({ ...bbox, scaleX: 1, scaleY: 1, listening: tool === 'move' });
|
||||
bboxTransformer?.setAttrs({
|
||||
listening: tool === 'move',
|
||||
enabledAnchors: tool === 'move' ? ALL_ANCHORS : NO_ANCHORS,
|
||||
});
|
||||
bboxRect?.setAttrs({ ...bbox, scaleX: 1, scaleY: 1, listening: tool === 'bbox' });
|
||||
bboxTransformer?.setAttrs({ listening: tool === 'bbox', enabledAnchors: tool === 'bbox' ? ALL_ANCHORS : NO_ANCHORS });
|
||||
};
|
||||
|
||||
export const getToolPreviewGroup = (stage: Konva.Stage): Konva.Group => {
|
||||
@ -365,9 +363,11 @@ export const renderToolPreview = (
|
||||
} else if (tool === 'rect') {
|
||||
// Rect gets a crosshair
|
||||
stage.container().style.cursor = 'crosshair';
|
||||
} else {
|
||||
// Else we hide the native cursor and use the konva-rendered brush preview
|
||||
} else if (tool === 'brush' || tool === 'eraser') {
|
||||
// Hide the native cursor and use the konva-rendered brush preview
|
||||
stage.container().style.cursor = 'none';
|
||||
} else if (tool === 'bbox') {
|
||||
stage.container().style.cursor = 'default';
|
||||
}
|
||||
|
||||
stage.draggable(tool === 'view');
|
||||
|
@ -23,7 +23,7 @@ import type { IRect } from 'konva/lib/types';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
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>;
|
||||
const zDrawingTool = zTool.extract(['brush', 'eraser']);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user