feat(ui): misc canvas perf improvements

- disable listening when not needed
- use useMemo for gridlines
This commit is contained in:
psychedelicious 2023-12-31 00:40:32 +11:00 committed by Kent Keirsey
parent 8d2ef5afc3
commit 2663a07e94
7 changed files with 28 additions and 17 deletions

View File

@ -210,7 +210,7 @@ const IAICanvas = () => {
onWheel={handleWheel}
draggable={(tool === 'move' || isStaging) && !isModifyingBoundingBox}
>
<Layer id="grid" visible={shouldShowGrid}>
<Layer id="grid" visible={shouldShowGrid} listening={false}>
<IAICanvasGrid />
</Layer>
@ -230,17 +230,21 @@ const IAICanvas = () => {
<IAICanvasMaskLines visible={true} listening={false} />
<IAICanvasMaskCompositer listening={false} />
</Layer>
<Layer>
<Layer listening={false}>
<IAICanvasBoundingBoxOverlay />
</Layer>
<Layer id="preview" imageSmoothingEnabled={shouldAntialias}>
<Layer
id="preview"
listening={false}
imageSmoothingEnabled={shouldAntialias}
>
{!isStaging && (
<IAICanvasToolPreview
visible={tool !== 'move'}
listening={false}
/>
)}
<IAICanvasStagingArea visible={isStaging} />
<IAICanvasStagingArea listening={false} visible={isStaging} />
{shouldShowIntermediates && <IAICanvasIntermediateImage />}
<IAICanvasBoundingBox
visible={shouldShowBoundingBox && !isStaging}

View File

@ -34,7 +34,7 @@ const IAICanvasBoundingBoxOverlay = () => {
} = useAppSelector(selector);
return (
<Group>
<Group listening={false}>
<Rect
offsetX={stageCoordinates.x / stageScale}
offsetY={stageCoordinates.y / stageScale}

View File

@ -4,8 +4,7 @@ import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { range } from 'lodash-es';
import type { ReactNode } from 'react';
import { memo, useCallback, useLayoutEffect, useState } from 'react';
import { memo, useCallback, useMemo } from 'react';
import { Group, Line as KonvaLine } from 'react-konva';
const selector = createMemoizedSelector([stateSelector], ({ canvas }) => {
@ -16,7 +15,6 @@ const selector = createMemoizedSelector([stateSelector], ({ canvas }) => {
const IAICanvasGrid = () => {
const { stageScale, stageCoordinates, stageDimensions } =
useAppSelector(selector);
const [gridLines, setGridLines] = useState<ReactNode[]>([]);
const [gridLineColor] = useToken('colors', ['base.800']);
const unscale = useCallback(
@ -26,7 +24,7 @@ const IAICanvasGrid = () => {
[stageScale]
);
useLayoutEffect(() => {
const gridLines = useMemo(() => {
const { width, height } = stageDimensions;
const { x, y } = stageCoordinates;
@ -77,6 +75,7 @@ const IAICanvasGrid = () => {
points={[0, 0, 0, ySize]}
stroke={gridLineColor}
strokeWidth={1}
listening={false}
/>
));
const yLines = range(0, ySteps).map((i) => (
@ -87,13 +86,14 @@ const IAICanvasGrid = () => {
points={[0, 0, xSize, 0]}
stroke={gridLineColor}
strokeWidth={1}
listening={false}
/>
));
setGridLines(xLines.concat(yLines));
}, [stageScale, stageCoordinates, stageDimensions, unscale, gridLineColor]);
return xLines.concat(yLines);
}, [stageCoordinates, stageDimensions, unscale, gridLineColor]);
return <Group>{gridLines}</Group>;
return <Group listening={false}>{gridLines}</Group>;
};
export default memo(IAICanvasGrid);

View File

@ -13,13 +13,14 @@ const IAICanvasImageErrorFallback = ({
const [rectFill, textFill] = useToken('colors', ['base.500', 'base.900']);
const { t } = useTranslation();
return (
<Group>
<Group listening={false}>
<Rect
x={canvasImage.x}
y={canvasImage.y}
width={canvasImage.width}
height={canvasImage.height}
fill={rectFill}
listening={false}
/>
<Text
x={canvasImage.x}
@ -33,6 +34,7 @@ const IAICanvasImageErrorFallback = ({
fontStyle="600"
text={t('common.imageFailedToLoad')}
fill={textFill}
listening={false}
/>
</Group>
);

View File

@ -9,7 +9,7 @@ import { Group, Line } from 'react-konva';
export const canvasLinesSelector = createMemoizedSelector(
[stateSelector],
({ canvas }) => {
return { objects: canvas.layerState.objects };
return canvas.layerState.objects.filter(isCanvasMaskLine);
}
);
@ -22,11 +22,11 @@ type InpaintingCanvasLinesProps = GroupConfig;
*/
const IAICanvasLines = (props: InpaintingCanvasLinesProps) => {
const { ...rest } = props;
const { objects } = useAppSelector(canvasLinesSelector);
const lines = useAppSelector(canvasLinesSelector);
return (
<Group listening={false} {...rest}>
{objects.filter(isCanvasMaskLine).map((line, i) => (
{lines.map((line, i) => (
<Line
key={i}
points={line.points}

View File

@ -59,6 +59,7 @@ const IAICanvasObjectRenderer = () => {
clipY={obj.clip.y}
clipWidth={obj.clip.width}
clipHeight={obj.clip.height}
listening={false}
>
{line}
</Group>
@ -75,6 +76,7 @@ const IAICanvasObjectRenderer = () => {
width={obj.width}
height={obj.height}
fill={rgbaColorToString(obj.color)}
listening={false}
/>
);
} else if (isCanvasEraseRect(obj)) {
@ -87,6 +89,7 @@ const IAICanvasObjectRenderer = () => {
height={obj.height}
fill="rgb(255, 255, 255)"
globalCompositeOperation="destination-out"
listening={false}
/>
);
}

View File

@ -56,7 +56,7 @@ const IAICanvasStagingArea = (props: Props) => {
<IAICanvasImage canvasImage={currentStagingAreaImage} />
)}
{shouldShowStagingOutline && (
<Group>
<Group listening={false}>
<Rect
x={x}
y={y}
@ -65,6 +65,7 @@ const IAICanvasStagingArea = (props: Props) => {
strokeWidth={1}
stroke="white"
strokeScaleEnabled={false}
listening={false}
/>
<Rect
x={x}
@ -75,6 +76,7 @@ const IAICanvasStagingArea = (props: Props) => {
strokeWidth={1}
stroke="black"
strokeScaleEnabled={false}
listening={false}
/>
</Group>
)}