mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): use position
and dimensions
instead of separate x,y,width,height attrs
This commit is contained in:
parent
56237328f1
commit
44f91026e1
@ -58,7 +58,7 @@ export const addStagingListeners = (startAppListening: AppStartListening) => {
|
||||
assert(stagingAreaImage, 'No staged image found to accept');
|
||||
const { x, y } = state.canvasV2.bbox.rect;
|
||||
|
||||
api.dispatch(layerAddedFromStagingArea({ stagingAreaImage, pos: { x, y } }));
|
||||
api.dispatch(layerAddedFromStagingArea({ stagingAreaImage, position: { x, y } }));
|
||||
api.dispatch(sessionStagingAreaReset());
|
||||
},
|
||||
});
|
||||
|
@ -24,10 +24,10 @@ export const HeadsUpDisplay = memo(() => {
|
||||
return (
|
||||
<Flex flexDir="column" bg="blackAlpha.400" borderBottomEndRadius="base" p={2} minW={64} gap={2}>
|
||||
<HUDItem label="Zoom" value={`${round(stageAttrs.scale * 100, 2)}%`} />
|
||||
<HUDItem label="Stage Pos" value={`${round(stageAttrs.x, 3)}, ${round(stageAttrs.y, 3)}`} />
|
||||
<HUDItem label="Stage Pos" value={`${round(stageAttrs.position.x, 3)}, ${round(stageAttrs.position.y, 3)}`} />
|
||||
<HUDItem
|
||||
label="Stage Size"
|
||||
value={`${round(stageAttrs.width / stageAttrs.scale, 2)}×${round(stageAttrs.height / stageAttrs.scale, 2)} px`}
|
||||
value={`${round(stageAttrs.dimensions.width / stageAttrs.scale, 2)}×${round(stageAttrs.dimensions.height / stageAttrs.scale, 2)} px`}
|
||||
/>
|
||||
<HUDItem label="BBox Size" value={`${bbox.rect.width}×${bbox.rect.height} px`} />
|
||||
<HUDItem label="BBox Position" value={`${bbox.rect.x}, ${bbox.rect.y}`} />
|
||||
|
@ -42,12 +42,15 @@ export class CanvasControlAdapter {
|
||||
});
|
||||
this.transformer.on('transformend', () => {
|
||||
this.manager.stateApi.onScaleChanged(
|
||||
{ id: this.id, scale: this.group.scaleX(), x: this.group.x(), y: this.group.y() },
|
||||
{ id: this.id, scale: this.group.scaleX(), position: { x: this.group.x(), y: this.group.y() } },
|
||||
'control_adapter'
|
||||
);
|
||||
});
|
||||
this.transformer.on('dragend', () => {
|
||||
this.manager.stateApi.onPosChanged({ id: this.id, x: this.group.x(), y: this.group.y() }, 'control_adapter');
|
||||
this.manager.stateApi.onPosChanged(
|
||||
{ id: this.id, position: { x: this.group.x(), y: this.group.y() } },
|
||||
'control_adapter'
|
||||
);
|
||||
});
|
||||
this.layer.add(this.transformer);
|
||||
|
||||
@ -60,8 +63,8 @@ export class CanvasControlAdapter {
|
||||
|
||||
// Update the layer's position and listening state
|
||||
this.group.setAttrs({
|
||||
x: controlAdapterState.x,
|
||||
y: controlAdapterState.y,
|
||||
x: controlAdapterState.position.x,
|
||||
y: controlAdapterState.position.y,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
});
|
||||
|
@ -42,7 +42,7 @@ export class CanvasInitialImage {
|
||||
}
|
||||
|
||||
if (!this.image) {
|
||||
this.image = await new CanvasImage(this.initialImageState.imageObject, {});
|
||||
this.image = await new CanvasImage(this.initialImageState.imageObject);
|
||||
this.objectsGroup.add(this.image.konvaImageGroup);
|
||||
await this.image.update(this.initialImageState.imageObject, true);
|
||||
} else if (!this.image.isLoading && !this.image.isError) {
|
||||
|
@ -46,12 +46,15 @@ export class CanvasInpaintMask {
|
||||
});
|
||||
this.transformer.on('transformend', () => {
|
||||
this.manager.stateApi.onScaleChanged(
|
||||
{ id: this.id, scale: this.group.scaleX(), x: this.group.x(), y: this.group.y() },
|
||||
{ id: this.id, scale: this.group.scaleX(), position: { x: this.group.x(), y: this.group.y() } },
|
||||
'inpaint_mask'
|
||||
);
|
||||
});
|
||||
this.transformer.on('dragend', () => {
|
||||
this.manager.stateApi.onPosChanged({ id: this.id, x: this.group.x(), y: this.group.y() }, 'inpaint_mask');
|
||||
this.manager.stateApi.onPosChanged(
|
||||
{ id: this.id, position: { x: this.group.x(), y: this.group.y() } },
|
||||
'inpaint_mask'
|
||||
);
|
||||
});
|
||||
this.layer.add(this.transformer);
|
||||
|
||||
@ -103,8 +106,8 @@ export class CanvasInpaintMask {
|
||||
|
||||
// Update the layer's position and listening state
|
||||
this.group.setAttrs({
|
||||
x: inpaintMaskState.x,
|
||||
y: inpaintMaskState.y,
|
||||
x: inpaintMaskState.position.x,
|
||||
y: inpaintMaskState.position.y,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
});
|
||||
|
@ -48,12 +48,12 @@ export class CanvasLayer {
|
||||
});
|
||||
this.transformer.on('transformend', () => {
|
||||
this.manager.stateApi.onScaleChanged(
|
||||
{ id: this.id, scale: this.group.scaleX(), x: this.group.x(), y: this.group.y() },
|
||||
{ id: this.id, scale: this.group.scaleX(), position: { x: this.group.x(), y: this.group.y() } },
|
||||
'layer'
|
||||
);
|
||||
});
|
||||
this.transformer.on('dragend', () => {
|
||||
this.manager.stateApi.onPosChanged({ id: this.id, x: this.group.x(), y: this.group.y() }, 'layer');
|
||||
this.manager.stateApi.onPosChanged({ id: this.id, position: { x: this.group.x(), y: this.group.y() } }, 'layer');
|
||||
});
|
||||
this.layer.add(this.transformer);
|
||||
|
||||
@ -99,8 +99,8 @@ export class CanvasLayer {
|
||||
|
||||
// Update the layer's position and listening state
|
||||
this.group.setAttrs({
|
||||
x: layerState.x,
|
||||
y: layerState.y,
|
||||
x: layerState.position.x,
|
||||
y: layerState.position.y,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
});
|
||||
|
@ -212,10 +212,8 @@ export class CanvasManager {
|
||||
this.stage.width(this.container.offsetWidth);
|
||||
this.stage.height(this.container.offsetHeight);
|
||||
this.stateApi.setStageAttrs({
|
||||
x: this.stage.x(),
|
||||
y: this.stage.y(),
|
||||
width: this.stage.width(),
|
||||
height: this.stage.height(),
|
||||
position: { x: this.stage.x(), y: this.stage.y() },
|
||||
dimensions: { width: this.stage.width(), height: this.stage.height() },
|
||||
scale: this.stage.scaleX(),
|
||||
});
|
||||
this.background.render();
|
||||
|
@ -47,12 +47,15 @@ export class CanvasRegion {
|
||||
});
|
||||
this.transformer.on('transformend', () => {
|
||||
this.manager.stateApi.onScaleChanged(
|
||||
{ id: this.id, scale: this.group.scaleX(), x: this.group.x(), y: this.group.y() },
|
||||
{ id: this.id, scale: this.group.scaleX(), position: { x: this.group.x(), y: this.group.y() } },
|
||||
'regional_guidance'
|
||||
);
|
||||
});
|
||||
this.transformer.on('dragend', () => {
|
||||
this.manager.stateApi.onPosChanged({ id: this.id, x: this.group.x(), y: this.group.y() }, 'regional_guidance');
|
||||
this.manager.stateApi.onPosChanged(
|
||||
{ id: this.id, position: { x: this.group.x(), y: this.group.y() } },
|
||||
'regional_guidance'
|
||||
);
|
||||
});
|
||||
this.layer.add(this.transformer);
|
||||
|
||||
@ -104,8 +107,8 @@ export class CanvasRegion {
|
||||
|
||||
// Update the layer's position and listening state
|
||||
this.group.setAttrs({
|
||||
x: regionState.x,
|
||||
y: regionState.y,
|
||||
x: regionState.position.x,
|
||||
y: regionState.position.y,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
});
|
||||
|
@ -47,7 +47,7 @@ import type {
|
||||
BrushLine,
|
||||
CanvasEntity,
|
||||
EraserLine,
|
||||
PosChangedArg,
|
||||
PositionChangedArg,
|
||||
RectShape,
|
||||
ScaleChangedArg,
|
||||
Tool,
|
||||
@ -70,7 +70,7 @@ export class CanvasStateApi {
|
||||
return this.store.getState().canvasV2;
|
||||
};
|
||||
|
||||
onPosChanged = (arg: PosChangedArg, entityType: CanvasEntity['type']) => {
|
||||
onPosChanged = (arg: PositionChangedArg, entityType: CanvasEntity['type']) => {
|
||||
log.debug('onPosChanged');
|
||||
if (entityType === 'layer') {
|
||||
this.store.dispatch(layerTranslated(arg));
|
||||
|
@ -2,9 +2,9 @@ import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
|
||||
import { getScaledCursorPosition } from 'features/controlLayers/konva/util';
|
||||
import type {
|
||||
CanvasV2State,
|
||||
Coordinate,
|
||||
InpaintMaskEntity,
|
||||
LayerEntity,
|
||||
Coordinate,
|
||||
RegionEntity,
|
||||
Tool,
|
||||
} from 'features/controlLayers/store/types';
|
||||
@ -141,15 +141,15 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
|
||||
if (settings.clipToBbox) {
|
||||
return {
|
||||
x: bboxRect.x - entity.x,
|
||||
y: bboxRect.y - entity.y,
|
||||
x: bboxRect.x - entity.position.x,
|
||||
y: bboxRect.y - entity.position.y,
|
||||
width: bboxRect.width,
|
||||
height: bboxRect.height,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
x: -stage.x() / stage.scaleX() - entity.x,
|
||||
y: -stage.y() / stage.scaleY() - entity.y,
|
||||
x: -stage.x() / stage.scaleX() - entity.position.x,
|
||||
y: -stage.y() / stage.scaleY() - entity.position.y,
|
||||
width: stage.width() / stage.scaleX(),
|
||||
height: stage.height() / stage.scaleY(),
|
||||
};
|
||||
@ -194,8 +194,8 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
// The last point of the last line is already normalized to the entity's coordinates
|
||||
lastLinePoint.x,
|
||||
lastLinePoint.y,
|
||||
pos.x - selectedEntity.x,
|
||||
pos.y - selectedEntity.y,
|
||||
pos.x - selectedEntity.position.x,
|
||||
pos.y - selectedEntity.position.y,
|
||||
],
|
||||
strokeWidth: toolState.brush.width,
|
||||
color: getCurrentFill(),
|
||||
@ -208,7 +208,7 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
await selectedEntityAdapter.setDrawingBuffer({
|
||||
id: getBrushLineId(selectedEntityAdapter.id, uuidv4()),
|
||||
type: 'brush_line',
|
||||
points: [pos.x - selectedEntity.x, pos.y - selectedEntity.y],
|
||||
points: [pos.x - selectedEntity.position.x, pos.y - selectedEntity.position.y],
|
||||
strokeWidth: toolState.brush.width,
|
||||
color: getCurrentFill(),
|
||||
clip: getClip(selectedEntity),
|
||||
@ -231,8 +231,8 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
// The last point of the last line is already normalized to the entity's coordinates
|
||||
lastLinePoint.x,
|
||||
lastLinePoint.y,
|
||||
pos.x - selectedEntity.x,
|
||||
pos.y - selectedEntity.y,
|
||||
pos.x - selectedEntity.position.x,
|
||||
pos.y - selectedEntity.position.y,
|
||||
],
|
||||
strokeWidth: toolState.eraser.width,
|
||||
clip: getClip(selectedEntity),
|
||||
@ -244,7 +244,7 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
await selectedEntityAdapter.setDrawingBuffer({
|
||||
id: getEraserLineId(selectedEntityAdapter.id, uuidv4()),
|
||||
type: 'eraser_line',
|
||||
points: [pos.x - selectedEntity.x, pos.y - selectedEntity.y],
|
||||
points: [pos.x - selectedEntity.position.x, pos.y - selectedEntity.position.y],
|
||||
strokeWidth: toolState.eraser.width,
|
||||
clip: getClip(selectedEntity),
|
||||
});
|
||||
@ -259,8 +259,8 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
await selectedEntityAdapter.setDrawingBuffer({
|
||||
id: getRectShapeId(selectedEntityAdapter.id, uuidv4()),
|
||||
type: 'rect_shape',
|
||||
x: pos.x - selectedEntity.x,
|
||||
y: pos.y - selectedEntity.y,
|
||||
x: pos.x - selectedEntity.position.x,
|
||||
y: pos.y - selectedEntity.position.y,
|
||||
width: 0,
|
||||
height: 0,
|
||||
color: getCurrentFill(),
|
||||
@ -342,7 +342,10 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
if (drawingBuffer?.type === 'brush_line') {
|
||||
const nextPoint = getNextPoint(pos, toolState, getLastPointOfLine(drawingBuffer.points));
|
||||
if (nextPoint) {
|
||||
drawingBuffer.points.push(nextPoint.x - selectedEntity.x, nextPoint.y - selectedEntity.y);
|
||||
drawingBuffer.points.push(
|
||||
nextPoint.x - selectedEntity.position.x,
|
||||
nextPoint.y - selectedEntity.position.y
|
||||
);
|
||||
await selectedEntityAdapter.setDrawingBuffer(drawingBuffer);
|
||||
setLastAddedPoint(nextPoint);
|
||||
}
|
||||
@ -356,7 +359,7 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
await selectedEntityAdapter.setDrawingBuffer({
|
||||
id: getBrushLineId(selectedEntityAdapter.id, uuidv4()),
|
||||
type: 'brush_line',
|
||||
points: [pos.x - selectedEntity.x, pos.y - selectedEntity.y],
|
||||
points: [pos.x - selectedEntity.position.x, pos.y - selectedEntity.position.y],
|
||||
strokeWidth: toolState.brush.width,
|
||||
color: getCurrentFill(),
|
||||
clip: getClip(selectedEntity),
|
||||
@ -371,7 +374,10 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
if (drawingBuffer.type === 'eraser_line') {
|
||||
const nextPoint = getNextPoint(pos, toolState, getLastPointOfLine(drawingBuffer.points));
|
||||
if (nextPoint) {
|
||||
drawingBuffer.points.push(nextPoint.x - selectedEntity.x, nextPoint.y - selectedEntity.y);
|
||||
drawingBuffer.points.push(
|
||||
nextPoint.x - selectedEntity.position.x,
|
||||
nextPoint.y - selectedEntity.position.y
|
||||
);
|
||||
await selectedEntityAdapter.setDrawingBuffer(drawingBuffer);
|
||||
setLastAddedPoint(nextPoint);
|
||||
}
|
||||
@ -385,7 +391,7 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
await selectedEntityAdapter.setDrawingBuffer({
|
||||
id: getEraserLineId(selectedEntityAdapter.id, uuidv4()),
|
||||
type: 'eraser_line',
|
||||
points: [pos.x - selectedEntity.x, pos.y - selectedEntity.y],
|
||||
points: [pos.x - selectedEntity.position.x, pos.y - selectedEntity.position.y],
|
||||
strokeWidth: toolState.eraser.width,
|
||||
clip: getClip(selectedEntity),
|
||||
});
|
||||
@ -397,8 +403,8 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
const drawingBuffer = selectedEntityAdapter.getDrawingBuffer();
|
||||
if (drawingBuffer) {
|
||||
if (drawingBuffer.type === 'rect_shape') {
|
||||
drawingBuffer.width = pos.x - selectedEntity.x - drawingBuffer.x;
|
||||
drawingBuffer.height = pos.y - selectedEntity.y - drawingBuffer.y;
|
||||
drawingBuffer.width = pos.x - selectedEntity.position.x - drawingBuffer.x;
|
||||
drawingBuffer.height = pos.y - selectedEntity.position.y - drawingBuffer.y;
|
||||
await selectedEntityAdapter.setDrawingBuffer(drawingBuffer);
|
||||
} else {
|
||||
await selectedEntityAdapter.setDrawingBuffer(null);
|
||||
@ -429,16 +435,16 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
) {
|
||||
const drawingBuffer = selectedEntityAdapter.getDrawingBuffer();
|
||||
if (toolState.selected === 'brush' && drawingBuffer?.type === 'brush_line') {
|
||||
drawingBuffer.points.push(pos.x - selectedEntity.x, pos.y - selectedEntity.y);
|
||||
drawingBuffer.points.push(pos.x - selectedEntity.position.x, pos.y - selectedEntity.position.y);
|
||||
await selectedEntityAdapter.setDrawingBuffer(drawingBuffer);
|
||||
selectedEntityAdapter.finalizeDrawingBuffer();
|
||||
} else if (toolState.selected === 'eraser' && drawingBuffer?.type === 'eraser_line') {
|
||||
drawingBuffer.points.push(pos.x - selectedEntity.x, pos.y - selectedEntity.y);
|
||||
drawingBuffer.points.push(pos.x - selectedEntity.position.x, pos.y - selectedEntity.position.y);
|
||||
await selectedEntityAdapter.setDrawingBuffer(drawingBuffer);
|
||||
selectedEntityAdapter.finalizeDrawingBuffer();
|
||||
} else if (toolState.selected === 'rect' && drawingBuffer?.type === 'rect_shape') {
|
||||
drawingBuffer.width = pos.x - selectedEntity.x - drawingBuffer.x;
|
||||
drawingBuffer.height = pos.y - selectedEntity.y - drawingBuffer.y;
|
||||
drawingBuffer.width = pos.x - selectedEntity.position.x - drawingBuffer.x;
|
||||
drawingBuffer.height = pos.y - selectedEntity.position.y - drawingBuffer.y;
|
||||
await selectedEntityAdapter.setDrawingBuffer(drawingBuffer);
|
||||
selectedEntityAdapter.finalizeDrawingBuffer();
|
||||
}
|
||||
@ -484,7 +490,11 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
stage.scaleX(newScale);
|
||||
stage.scaleY(newScale);
|
||||
stage.position(newPos);
|
||||
setStageAttrs({ ...newPos, width: stage.width(), height: stage.height(), scale: newScale });
|
||||
setStageAttrs({
|
||||
position: newPos,
|
||||
dimensions: { width: stage.width(), height: stage.height() },
|
||||
scale: newScale,
|
||||
});
|
||||
manager.background.render();
|
||||
}
|
||||
}
|
||||
@ -494,10 +504,8 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
//#region dragmove
|
||||
stage.on('dragmove', () => {
|
||||
setStageAttrs({
|
||||
x: Math.floor(stage.x()),
|
||||
y: Math.floor(stage.y()),
|
||||
width: stage.width(),
|
||||
height: stage.height(),
|
||||
position: { x: Math.floor(stage.x()), y: Math.floor(stage.y()) },
|
||||
dimensions: { width: stage.width(), height: stage.height() },
|
||||
scale: stage.scaleX(),
|
||||
});
|
||||
manager.background.render();
|
||||
@ -508,10 +516,8 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
||||
stage.on('dragend', () => {
|
||||
// Stage position should always be an integer, else we get fractional pixels which are blurry
|
||||
setStageAttrs({
|
||||
x: Math.floor(stage.x()),
|
||||
y: Math.floor(stage.y()),
|
||||
width: stage.width(),
|
||||
height: stage.height(),
|
||||
position: { x: Math.floor(stage.x()), y: Math.floor(stage.y()) },
|
||||
dimensions: { width: stage.width(), height: stage.height() },
|
||||
scale: stage.scaleX(),
|
||||
});
|
||||
manager.preview.tool.render();
|
||||
|
@ -50,8 +50,10 @@ const initialState: CanvasV2State = {
|
||||
imageCache: null,
|
||||
isEnabled: true,
|
||||
objects: [],
|
||||
x: 0,
|
||||
y: 0,
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
},
|
||||
tool: {
|
||||
selected: 'view',
|
||||
@ -369,10 +371,8 @@ const migrate = (state: any): any => {
|
||||
// Ephemeral state that does not need to be in redux
|
||||
export const $isPreviewVisible = atom(true);
|
||||
export const $stageAttrs = atom<StageAttrs>({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
position: { x: 0, y: 0 },
|
||||
dimensions: { width: 0, height: 0 },
|
||||
scale: 0,
|
||||
});
|
||||
export const $shouldShowStagedImage = atom(true);
|
||||
|
@ -14,6 +14,7 @@ import type {
|
||||
ControlNetConfig,
|
||||
ControlNetData,
|
||||
Filter,
|
||||
PositionChangedArg,
|
||||
ProcessorConfig,
|
||||
ScaleChangedArg,
|
||||
T2IAdapterConfig,
|
||||
@ -35,8 +36,7 @@ export const controlAdaptersReducers = {
|
||||
state.controlAdapters.entities.push({
|
||||
id,
|
||||
type: 'control_adapter',
|
||||
x: 0,
|
||||
y: 0,
|
||||
position: { x: 0, y: 0 },
|
||||
bbox: null,
|
||||
bboxNeedsUpdate: false,
|
||||
isEnabled: true,
|
||||
@ -64,17 +64,16 @@ export const controlAdaptersReducers = {
|
||||
}
|
||||
ca.isEnabled = !ca.isEnabled;
|
||||
},
|
||||
caTranslated: (state, action: PayloadAction<{ id: string; x: number; y: number }>) => {
|
||||
const { id, x, y } = action.payload;
|
||||
caTranslated: (state, action: PayloadAction<PositionChangedArg>) => {
|
||||
const { id, position } = action.payload;
|
||||
const ca = selectCA(state, id);
|
||||
if (!ca) {
|
||||
return;
|
||||
}
|
||||
ca.x = x;
|
||||
ca.y = y;
|
||||
ca.position = position;
|
||||
},
|
||||
caScaled: (state, action: PayloadAction<ScaleChangedArg>) => {
|
||||
const { id, scale, x, y } = action.payload;
|
||||
const { id, scale, position } = action.payload;
|
||||
const ca = selectCA(state, id);
|
||||
if (!ca) {
|
||||
return;
|
||||
@ -92,8 +91,7 @@ export const controlAdaptersReducers = {
|
||||
ca.processedImageObject.height *= scale;
|
||||
ca.processedImageObject.width *= scale;
|
||||
}
|
||||
ca.x = x;
|
||||
ca.y = y;
|
||||
ca.position = position;
|
||||
ca.bboxNeedsUpdate = true;
|
||||
state.layers.imageCache = null;
|
||||
},
|
||||
|
@ -2,6 +2,7 @@ import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
|
||||
import type {
|
||||
BrushLine,
|
||||
CanvasV2State,
|
||||
Coordinate,
|
||||
EraserLine,
|
||||
InpaintMaskEntity,
|
||||
RectShape,
|
||||
@ -28,13 +29,12 @@ export const inpaintMaskReducers = {
|
||||
imIsEnabledToggled: (state) => {
|
||||
state.inpaintMask.isEnabled = !state.inpaintMask.isEnabled;
|
||||
},
|
||||
imTranslated: (state, action: PayloadAction<{ x: number; y: number }>) => {
|
||||
const { x, y } = action.payload;
|
||||
state.inpaintMask.x = x;
|
||||
state.inpaintMask.y = y;
|
||||
imTranslated: (state, action: PayloadAction<{ position: Coordinate }>) => {
|
||||
const { position } = action.payload;
|
||||
state.inpaintMask.position = position;
|
||||
},
|
||||
imScaled: (state, action: PayloadAction<ScaleChangedArg>) => {
|
||||
const { scale, x, y } = action.payload;
|
||||
const { scale, position } = action.payload;
|
||||
for (const obj of state.inpaintMask.objects) {
|
||||
if (obj.type === 'brush_line') {
|
||||
obj.points = obj.points.map((point) => point * scale);
|
||||
@ -49,8 +49,7 @@ export const inpaintMaskReducers = {
|
||||
obj.width *= scale;
|
||||
}
|
||||
}
|
||||
state.inpaintMask.x = x;
|
||||
state.inpaintMask.y = y;
|
||||
state.inpaintMask.position = position;
|
||||
state.inpaintMask.bboxNeedsUpdate = true;
|
||||
state.inpaintMask.imageCache = null;
|
||||
},
|
||||
|
@ -8,10 +8,11 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
import type {
|
||||
BrushLine,
|
||||
CanvasV2State,
|
||||
Coordinate,
|
||||
EraserLine,
|
||||
ImageObjectAddedArg,
|
||||
LayerEntity,
|
||||
Coordinate,
|
||||
PositionChangedArg,
|
||||
RectShape,
|
||||
ScaleChangedArg,
|
||||
StagingAreaImage,
|
||||
@ -37,8 +38,7 @@ export const layersReducers = {
|
||||
bboxNeedsUpdate: false,
|
||||
objects: [],
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
y: 0,
|
||||
position: { x: 0, y: 0 },
|
||||
});
|
||||
state.selectedEntityIdentifier = { type: 'layer', id };
|
||||
state.layers.imageCache = null;
|
||||
@ -48,9 +48,9 @@ export const layersReducers = {
|
||||
layerAddedFromStagingArea: {
|
||||
reducer: (
|
||||
state,
|
||||
action: PayloadAction<{ id: string; objectId: string; stagingAreaImage: StagingAreaImage; pos: Coordinate }>
|
||||
action: PayloadAction<{ id: string; objectId: string; stagingAreaImage: StagingAreaImage; position: Coordinate }>
|
||||
) => {
|
||||
const { id, objectId, stagingAreaImage, pos } = action.payload;
|
||||
const { id, objectId, stagingAreaImage, position } = action.payload;
|
||||
const { imageDTO, offsetX, offsetY } = stagingAreaImage;
|
||||
const imageObject = imageDTOToImageObject(id, objectId, imageDTO);
|
||||
state.layers.entities.push({
|
||||
@ -61,13 +61,12 @@ export const layersReducers = {
|
||||
bboxNeedsUpdate: false,
|
||||
objects: [imageObject],
|
||||
opacity: 1,
|
||||
x: pos.x + offsetX,
|
||||
y: pos.y + offsetY,
|
||||
position: { x: position.x + offsetX, y: position.y + offsetY },
|
||||
});
|
||||
state.selectedEntityIdentifier = { type: 'layer', id };
|
||||
state.layers.imageCache = null;
|
||||
},
|
||||
prepare: (payload: { stagingAreaImage: StagingAreaImage; pos: Coordinate }) => ({
|
||||
prepare: (payload: { stagingAreaImage: StagingAreaImage; position: Coordinate }) => ({
|
||||
payload: { ...payload, id: uuidv4(), objectId: uuidv4() },
|
||||
}),
|
||||
},
|
||||
@ -86,14 +85,13 @@ export const layersReducers = {
|
||||
layer.isEnabled = !layer.isEnabled;
|
||||
state.layers.imageCache = null;
|
||||
},
|
||||
layerTranslated: (state, action: PayloadAction<{ id: string; x: number; y: number }>) => {
|
||||
const { id, x, y } = action.payload;
|
||||
layerTranslated: (state, action: PayloadAction<PositionChangedArg>) => {
|
||||
const { id, position } = action.payload;
|
||||
const layer = selectLayer(state, id);
|
||||
if (!layer) {
|
||||
return;
|
||||
}
|
||||
layer.x = x;
|
||||
layer.y = y;
|
||||
layer.position = position;
|
||||
state.layers.imageCache = null;
|
||||
},
|
||||
layerBboxChanged: (state, action: PayloadAction<{ id: string; bbox: IRect | null }>) => {
|
||||
@ -121,8 +119,7 @@ export const layersReducers = {
|
||||
layer.bbox = null;
|
||||
layer.bboxNeedsUpdate = false;
|
||||
state.layers.imageCache = null;
|
||||
layer.x = 0;
|
||||
layer.y = 0;
|
||||
layer.position = { x: 0, y: 0 };
|
||||
},
|
||||
layerDeleted: (state, action: PayloadAction<{ id: string }>) => {
|
||||
const { id } = action.payload;
|
||||
@ -212,7 +209,7 @@ export const layersReducers = {
|
||||
state.layers.imageCache = null;
|
||||
},
|
||||
layerScaled: (state, action: PayloadAction<ScaleChangedArg>) => {
|
||||
const { id, scale, x, y } = action.payload;
|
||||
const { id, scale, position } = action.payload;
|
||||
const layer = selectLayer(state, id);
|
||||
if (!layer) {
|
||||
return;
|
||||
@ -236,8 +233,7 @@ export const layersReducers = {
|
||||
obj.width *= scale;
|
||||
}
|
||||
}
|
||||
layer.x = x;
|
||||
layer.y = y;
|
||||
layer.position = position;
|
||||
layer.bboxNeedsUpdate = true;
|
||||
state.layers.imageCache = null;
|
||||
},
|
||||
|
@ -6,6 +6,7 @@ import type {
|
||||
CLIPVisionModelV2,
|
||||
EraserLine,
|
||||
IPMethodV2,
|
||||
PositionChangedArg,
|
||||
RectShape,
|
||||
ScaleChangedArg,
|
||||
} from 'features/controlLayers/store/types';
|
||||
@ -61,8 +62,7 @@ export const regionsReducers = {
|
||||
bboxNeedsUpdate: false,
|
||||
objects: [],
|
||||
fill: getRGMaskFill(state),
|
||||
x: 0,
|
||||
y: 0,
|
||||
position: { x: 0, y: 0 },
|
||||
autoNegative: 'invert',
|
||||
positivePrompt: '',
|
||||
negativePrompt: null,
|
||||
@ -97,16 +97,15 @@ export const regionsReducers = {
|
||||
rg.isEnabled = !rg.isEnabled;
|
||||
}
|
||||
},
|
||||
rgTranslated: (state, action: PayloadAction<{ id: string; x: number; y: number }>) => {
|
||||
const { id, x, y } = action.payload;
|
||||
rgTranslated: (state, action: PayloadAction<PositionChangedArg>) => {
|
||||
const { id, position } = action.payload;
|
||||
const rg = selectRG(state, id);
|
||||
if (rg) {
|
||||
rg.x = x;
|
||||
rg.y = y;
|
||||
rg.position = position;
|
||||
}
|
||||
},
|
||||
rgScaled: (state, action: PayloadAction<ScaleChangedArg>) => {
|
||||
const { id, scale, x, y } = action.payload;
|
||||
const { id, scale, position } = action.payload;
|
||||
const rg = selectRG(state, id);
|
||||
if (!rg) {
|
||||
return;
|
||||
@ -125,8 +124,7 @@ export const regionsReducers = {
|
||||
obj.width *= scale;
|
||||
}
|
||||
}
|
||||
rg.x = x;
|
||||
rg.y = y;
|
||||
rg.position = position;
|
||||
rg.bboxNeedsUpdate = true;
|
||||
state.layers.imageCache = null;
|
||||
},
|
||||
|
@ -506,6 +506,18 @@ export const RGBA_RED: RgbaColor = { r: 255, g: 0, b: 0, a: 1 };
|
||||
|
||||
const zOpacity = z.number().gte(0).lte(1);
|
||||
|
||||
const zDimensions = z.object({
|
||||
width: z.number().int().positive(),
|
||||
height: z.number().int().positive(),
|
||||
});
|
||||
export type Dimensions = z.infer<typeof zDimensions>;
|
||||
|
||||
const zCoordinate = z.object({
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
});
|
||||
export type Coordinate = z.infer<typeof zCoordinate>;
|
||||
|
||||
const zRect = z.object({
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
@ -566,8 +578,7 @@ export const zLayerEntity = z.object({
|
||||
id: zId,
|
||||
type: z.literal('layer'),
|
||||
isEnabled: z.boolean(),
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
position: zCoordinate,
|
||||
bbox: zRect.nullable(),
|
||||
bboxNeedsUpdate: z.boolean(),
|
||||
opacity: zOpacity,
|
||||
@ -631,8 +642,7 @@ export const zRegionEntity = z.object({
|
||||
id: zId,
|
||||
type: z.literal('regional_guidance'),
|
||||
isEnabled: z.boolean(),
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
position: zCoordinate,
|
||||
bbox: zRect.nullable(),
|
||||
bboxNeedsUpdate: z.boolean(),
|
||||
objects: z.array(zMaskObject),
|
||||
@ -658,8 +668,7 @@ const zInpaintMaskEntity = z.object({
|
||||
id: z.literal('inpaint_mask'),
|
||||
type: z.literal('inpaint_mask'),
|
||||
isEnabled: z.boolean(),
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
position: zCoordinate,
|
||||
bbox: zRect.nullable(),
|
||||
bboxNeedsUpdate: z.boolean(),
|
||||
objects: z.array(zMaskObject),
|
||||
@ -682,8 +691,7 @@ const zControlAdapterEntityBase = z.object({
|
||||
id: zId,
|
||||
type: z.literal('control_adapter'),
|
||||
isEnabled: z.boolean(),
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
position: zCoordinate,
|
||||
bbox: zRect.nullable(),
|
||||
bboxNeedsUpdate: z.boolean(),
|
||||
opacity: zOpacity,
|
||||
@ -809,18 +817,6 @@ export type CanvasEntity =
|
||||
| InitialImageEntity;
|
||||
export type CanvasEntityIdentifier = Pick<CanvasEntity, 'id' | 'type'>;
|
||||
|
||||
const zDimensions = z.object({
|
||||
width: z.number().int().positive(),
|
||||
height: z.number().int().positive(),
|
||||
});
|
||||
export type Dimensions = z.infer<typeof zDimensions>;
|
||||
|
||||
const zCoordinate = z.object({
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
});
|
||||
export type Coordinate = z.infer<typeof zCoordinate>;
|
||||
|
||||
export type LoRA = {
|
||||
id: string;
|
||||
isEnabled: boolean;
|
||||
@ -926,9 +922,9 @@ export type CanvasV2State = {
|
||||
};
|
||||
};
|
||||
|
||||
export type StageAttrs = { x: number; y: number; width: number; height: number; scale: number };
|
||||
export type PosChangedArg = { id: string; x: number; y: number };
|
||||
export type ScaleChangedArg = { id: string; scale: number; x: number; y: number };
|
||||
export type StageAttrs = { position: Coordinate; dimensions: Dimensions; scale: number };
|
||||
export type PositionChangedArg = { id: string; position: Coordinate };
|
||||
export type ScaleChangedArg = { id: string; scale: number; position: Coordinate };
|
||||
export type BboxChangedArg = { id: string; bbox: Rect | null };
|
||||
export type EraserLineAddedArg = {
|
||||
id: string;
|
||||
@ -939,7 +935,7 @@ export type EraserLineAddedArg = {
|
||||
export type BrushLineAddedArg = EraserLineAddedArg & { color: RgbaColor };
|
||||
export type PointAddedToLineArg = { id: string; point: [number, number] };
|
||||
export type RectShapeAddedArg = { id: string; rect: IRect; color: RgbaColor };
|
||||
export type ImageObjectAddedArg = { id: string; imageDTO: ImageDTO; pos?: Coordinate };
|
||||
export type ImageObjectAddedArg = { id: string; imageDTO: ImageDTO; position?: Coordinate };
|
||||
|
||||
//#region Type guards
|
||||
export const isLine = (obj: RenderableObject): obj is BrushLine | EraserLine => {
|
||||
|
Loading…
Reference in New Issue
Block a user