From 6f354f16ba73b690fcbc9c9ebaef3854b9e5ee72 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sun, 31 Dec 2023 13:46:20 +1100 Subject: [PATCH] feat(ui): canvas perf improvements --- .../canvas/components/IAICanvasMaskLines.tsx | 7 +-- .../components/IAICanvasObjectRenderer.tsx | 17 +---- .../components/IAICanvasStagingArea.tsx | 3 +- .../components/IAICanvasToolPreview.tsx | 6 +- .../IAICanvasToolbar/IAICanvasMaskOptions.tsx | 2 +- .../canvas/hooks/useCanvasDragMove.ts | 62 ++++++++----------- 6 files changed, 36 insertions(+), 61 deletions(-) diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskLines.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskLines.tsx index f55c41f920..028f8b4fd2 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskLines.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasMaskLines.tsx @@ -21,12 +21,11 @@ type InpaintingCanvasLinesProps = GroupConfig; * Uses globalCompositeOperation to handle the brush and eraser tools. */ const IAICanvasLines = (props: InpaintingCanvasLinesProps) => { - const { ...rest } = props; - const lines = useAppSelector(canvasLinesSelector); + const objects = useAppSelector((state) => state.canvas.layerState.objects); return ( - - {lines.map((line, i) => ( + + {objects.filter(isCanvasMaskLine).map((line, i) => ( { - const { - layerState: { objects }, - } = canvas; - return { - objects, - }; -}); - const IAICanvasObjectRenderer = () => { - const { objects } = useAppSelector(selector); - - if (!objects) { - return null; - } + const objects = useAppSelector((state) => state.canvas.layerState.objects); return ( diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx index e2379f205b..41ef422195 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx @@ -39,7 +39,6 @@ const selector = createMemoizedSelector([stateSelector], ({ canvas }) => { type Props = GroupConfig; const IAICanvasStagingArea = (props: Props) => { - const { ...rest } = props; const { currentStagingAreaImage, shouldShowStagingImage, @@ -51,7 +50,7 @@ const IAICanvasStagingArea = (props: Props) => { } = useAppSelector(selector); return ( - + {shouldShowStagingImage && currentStagingAreaImage && ( )} diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolPreview.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolPreview.tsx index b1be23340d..d96dcf871a 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolPreview.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolPreview.tsx @@ -110,7 +110,6 @@ const canvasBrushPreviewSelector = createMemoizedSelector( * Draws a black circle around the canvas brush preview. */ const IAICanvasToolPreview = (props: GroupConfig) => { - const { ...rest } = props; const { brushX, brushY, @@ -133,7 +132,7 @@ const IAICanvasToolPreview = (props: GroupConfig) => { } return ( - + {tool === 'colorPicker' ? ( <> { stroke={brushColorString} strokeWidth={COLOR_PICKER_STROKE_RADIUS} strokeScaleEnabled={false} + listening={false} /> { stroke={colorPickerColorString} strokeWidth={COLOR_PICKER_STROKE_RADIUS} strokeScaleEnabled={false} + listening={false} /> ) : ( @@ -163,6 +164,7 @@ const IAICanvasToolPreview = (props: GroupConfig) => { globalCompositeOperation={ tool === 'eraser' ? 'destination-out' : 'source-out' } + listening={false} /> { ); return ( - + { - const { tool, isMovingBoundingBox } = canvas; - return { - tool, - isStaging, - isMovingBoundingBox, - }; - } -); - const useCanvasDrag = () => { const dispatch = useAppDispatch(); - const { tool, isStaging, isMovingBoundingBox } = useAppSelector(selector); + const tool = useAppSelector((state) => state.canvas.tool); + const isMovingBoundingBox = useAppSelector( + (state) => state.canvas.isMovingBoundingBox + ); + const isStaging = useAppSelector(isStagingSelector); - return { - handleDragStart: useCallback(() => { + const handleDragStart = useCallback(() => { + if (!((tool === 'move' || isStaging) && !isMovingBoundingBox)) { + return; + } + dispatch(setIsMovingStage(true)); + }, [dispatch, isMovingBoundingBox, isStaging, tool]); + + const handleDragMove = useCallback( + (e: KonvaEventObject) => { if (!((tool === 'move' || isStaging) && !isMovingBoundingBox)) { return; } - dispatch(setIsMovingStage(true)); - }, [dispatch, isMovingBoundingBox, isStaging, tool]), - handleDragMove: useCallback( - (e: KonvaEventObject) => { - if (!((tool === 'move' || isStaging) && !isMovingBoundingBox)) { - return; - } + const newCoordinates = { x: e.target.x(), y: e.target.y() }; - const newCoordinates = { x: e.target.x(), y: e.target.y() }; + dispatch(setStageCoordinates(newCoordinates)); + }, + [dispatch, isMovingBoundingBox, isStaging, tool] + ); - dispatch(setStageCoordinates(newCoordinates)); - }, - [dispatch, isMovingBoundingBox, isStaging, tool] - ), + const handleDragEnd = useCallback(() => { + if (!((tool === 'move' || isStaging) && !isMovingBoundingBox)) { + return; + } + dispatch(setIsMovingStage(false)); + }, [dispatch, isMovingBoundingBox, isStaging, tool]); - handleDragEnd: useCallback(() => { - if (!((tool === 'move' || isStaging) && !isMovingBoundingBox)) { - return; - } - dispatch(setIsMovingStage(false)); - }, [dispatch, isMovingBoundingBox, isStaging, tool]), - }; + return { handleDragStart, handleDragMove, handleDragEnd }; }; export default useCanvasDrag;