diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/constants.ts b/invokeai/frontend/web/src/features/controlLayers/konva/constants.ts index e7a3e35d2b..e526e2249e 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/constants.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/constants.ts @@ -20,6 +20,11 @@ export const BRUSH_BORDER_INNER_COLOR = 'rgba(0,0,0,1)'; */ export const BRUSH_BORDER_OUTER_COLOR = 'rgba(255,255,255,0.8)'; +/** + * The border width for the brush preview. + */ +export const BRUSH_ERASER_BORDER_WIDTH = 1.5; + /** * The target spacing of individual points of brush strokes, as a percentage of the brush size. */ diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/events.ts b/invokeai/frontend/web/src/features/controlLayers/konva/events.ts index 849a164bb7..f275bf415f 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/events.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/events.ts @@ -1,4 +1,5 @@ import { renderBackgroundLayer } from 'features/controlLayers/konva/renderers/background'; +import { scaleToolPreview } from 'features/controlLayers/konva/renderers/previewLayer'; import { getScaledFlooredCursorPosition } from 'features/controlLayers/konva/util'; import type { BrushLineAddedArg, @@ -420,14 +421,15 @@ export const setStageEventHandlers = ({ stage.position(newPos); setStageAttrs({ ...newPos, width: stage.width(), height: stage.height(), scale: newScale }); renderBackgroundLayer(stage); + scaleToolPreview(stage, getToolState()); } }); //#region dragmove stage.on('dragmove', () => { setStageAttrs({ - x: stage.x(), - y: stage.y(), + x: Math.floor(stage.x()), + y: Math.floor(stage.y()), width: stage.width(), height: stage.height(), scale: stage.scaleX(), diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/previewLayer.ts b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/previewLayer.ts index 2ca1573041..eff1e48bc3 100644 --- a/invokeai/frontend/web/src/features/controlLayers/konva/renderers/previewLayer.ts +++ b/invokeai/frontend/web/src/features/controlLayers/konva/renderers/previewLayer.ts @@ -1,6 +1,10 @@ import { rgbaColorToString } from 'common/util/colorCodeTransformers'; import { roundToMultiple, roundToMultipleMin } from 'common/util/roundDownToMultiple'; -import { BRUSH_BORDER_INNER_COLOR, BRUSH_BORDER_OUTER_COLOR } from 'features/controlLayers/konva/constants'; +import { + BRUSH_BORDER_INNER_COLOR, + BRUSH_BORDER_OUTER_COLOR, + BRUSH_ERASER_BORDER_WIDTH, +} from 'features/controlLayers/konva/constants'; import { PREVIEW_BRUSH_BORDER_INNER_ID, PREVIEW_BRUSH_BORDER_OUTER_ID, @@ -293,7 +297,7 @@ export const getToolPreviewGroup = (stage: Konva.Stage): Konva.Group => { id: PREVIEW_BRUSH_BORDER_INNER_ID, listening: false, stroke: BRUSH_BORDER_INNER_COLOR, - strokeWidth: 1 / scale, + strokeWidth: BRUSH_ERASER_BORDER_WIDTH / scale, strokeEnabled: true, }); brushPreviewGroup.add(brushPreviewBorderInner); @@ -301,7 +305,7 @@ export const getToolPreviewGroup = (stage: Konva.Stage): Konva.Group => { id: PREVIEW_BRUSH_BORDER_OUTER_ID, listening: false, stroke: BRUSH_BORDER_OUTER_COLOR, - strokeWidth: 1 / scale, + strokeWidth: BRUSH_ERASER_BORDER_WIDTH / scale, strokeEnabled: true, }); brushPreviewGroup.add(brushPreviewBorderOuter); @@ -387,6 +391,7 @@ export const renderToolPreview = ( // No need to render the brush preview if the cursor position or color is missing if (cursorPos && (tool === 'brush' || tool === 'eraser')) { + const scale = stage.scaleX(); // Update the fill circle const brushPreviewFill = brushPreviewGroup.findOne(`#${PREVIEW_BRUSH_FILL_ID}`); const radius = (tool === 'brush' ? toolState.brush.width : toolState.eraser.width) / 2; @@ -407,9 +412,11 @@ export const renderToolPreview = ( brushPreviewOuter?.setAttrs({ x: cursorPos.x, y: cursorPos.y, - radius: radius + 1, + radius: radius + BRUSH_ERASER_BORDER_WIDTH / scale, }); + scaleToolPreview(stage, toolState); + brushPreviewGroup.visible(true); } else { brushPreviewGroup.visible(false); @@ -430,3 +437,15 @@ export const renderToolPreview = ( } } }; + +export const scaleToolPreview = (stage: Konva.Stage, toolState: CanvasV2State['tool']): void => { + const scale = stage.scaleX(); + const radius = (toolState.selected === 'brush' ? toolState.brush.width : toolState.eraser.width) / 2; + const brushPreviewGroup = stage.findOne(`#${PREVIEW_BRUSH_GROUP_ID}`); + brushPreviewGroup + ?.findOne(`#${PREVIEW_BRUSH_BORDER_INNER_ID}`) + ?.strokeWidth(BRUSH_ERASER_BORDER_WIDTH / scale); + brushPreviewGroup + ?.findOne(`#${PREVIEW_BRUSH_BORDER_OUTER_ID}`) + ?.setAttrs({ strokeWidth: BRUSH_ERASER_BORDER_WIDTH / scale, radius: radius + BRUSH_ERASER_BORDER_WIDTH / scale }); +};