mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Increased consistency and readability by replacing any unnecessary JSX expressions in places where string literals are sufficient
210 lines
6.1 KiB
TypeScript
210 lines
6.1 KiB
TypeScript
import { createSelector } from '@reduxjs/toolkit';
|
|
import { useAppSelector } from 'app/storeHooks';
|
|
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
|
import { rgbaColorToString } from 'features/canvas/util/colorToString';
|
|
import { GroupConfig } from 'konva/lib/Group';
|
|
import { isEqual } from 'lodash';
|
|
|
|
import { Circle, Group } from 'react-konva';
|
|
import {
|
|
COLOR_PICKER_SIZE,
|
|
COLOR_PICKER_STROKE_RADIUS,
|
|
} from '../util/constants';
|
|
|
|
const canvasBrushPreviewSelector = createSelector(
|
|
canvasSelector,
|
|
(canvas) => {
|
|
const {
|
|
cursorPosition,
|
|
brushSize,
|
|
colorPickerColor,
|
|
maskColor,
|
|
brushColor,
|
|
tool,
|
|
layer,
|
|
shouldShowBrush,
|
|
isMovingBoundingBox,
|
|
isTransformingBoundingBox,
|
|
stageScale,
|
|
stageDimensions,
|
|
boundingBoxCoordinates,
|
|
boundingBoxDimensions,
|
|
shouldRestrictStrokesToBox,
|
|
} = canvas;
|
|
|
|
const clip = shouldRestrictStrokesToBox
|
|
? {
|
|
clipX: boundingBoxCoordinates.x,
|
|
clipY: boundingBoxCoordinates.y,
|
|
clipWidth: boundingBoxDimensions.width,
|
|
clipHeight: boundingBoxDimensions.height,
|
|
}
|
|
: {};
|
|
|
|
// // big brain time; this is the *inverse* of the clip that is needed for shouldRestrictStrokesToBox
|
|
// // it took some fiddling to work out, so I am leaving it here in case it is needed for something else...
|
|
// const clipFunc = shouldRestrictStrokesToBox
|
|
// ? (ctx: SceneContext) => {
|
|
// console.log(
|
|
// stageCoordinates.x / stageScale,
|
|
// stageCoordinates.y / stageScale,
|
|
// stageDimensions.height / stageScale,
|
|
// stageDimensions.width / stageScale
|
|
// );
|
|
// ctx.fillStyle = 'red';
|
|
// ctx.rect(
|
|
// -stageCoordinates.x / stageScale,
|
|
// -stageCoordinates.y / stageScale,
|
|
// stageDimensions.width / stageScale,
|
|
// stageCoordinates.y / stageScale + boundingBoxCoordinates.y
|
|
// );
|
|
// ctx.rect(
|
|
// -stageCoordinates.x / stageScale,
|
|
// boundingBoxCoordinates.y + boundingBoxDimensions.height,
|
|
// stageDimensions.width / stageScale,
|
|
// stageDimensions.height / stageScale
|
|
// );
|
|
// ctx.rect(
|
|
// -stageCoordinates.x / stageScale,
|
|
// -stageCoordinates.y / stageScale,
|
|
// stageCoordinates.x / stageScale + boundingBoxCoordinates.x,
|
|
// stageDimensions.height / stageScale
|
|
// );
|
|
// ctx.rect(
|
|
// boundingBoxCoordinates.x + boundingBoxDimensions.width,
|
|
// -stageCoordinates.y / stageScale,
|
|
// stageDimensions.width / stageScale -
|
|
// (boundingBoxCoordinates.x + boundingBoxDimensions.width),
|
|
// stageDimensions.height / stageScale
|
|
// );
|
|
// }
|
|
// : undefined;
|
|
|
|
return {
|
|
cursorPosition,
|
|
brushX: cursorPosition ? cursorPosition.x : stageDimensions.width / 2,
|
|
brushY: cursorPosition ? cursorPosition.y : stageDimensions.height / 2,
|
|
radius: brushSize / 2,
|
|
colorPickerOuterRadius: COLOR_PICKER_SIZE / stageScale,
|
|
colorPickerInnerRadius:
|
|
(COLOR_PICKER_SIZE - COLOR_PICKER_STROKE_RADIUS + 1) / stageScale,
|
|
maskColorString: rgbaColorToString({ ...maskColor, a: 0.5 }),
|
|
brushColorString: rgbaColorToString(brushColor),
|
|
colorPickerColorString: rgbaColorToString(colorPickerColor),
|
|
tool,
|
|
layer,
|
|
shouldShowBrush,
|
|
shouldDrawBrushPreview:
|
|
!(
|
|
isMovingBoundingBox ||
|
|
isTransformingBoundingBox ||
|
|
!cursorPosition
|
|
) && shouldShowBrush,
|
|
strokeWidth: 1.5 / stageScale,
|
|
dotRadius: 1.5 / stageScale,
|
|
clip,
|
|
};
|
|
},
|
|
{
|
|
memoizeOptions: {
|
|
resultEqualityCheck: isEqual,
|
|
},
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Draws a black circle around the canvas brush preview.
|
|
*/
|
|
const IAICanvasToolPreview = (props: GroupConfig) => {
|
|
const { ...rest } = props;
|
|
const {
|
|
brushX,
|
|
brushY,
|
|
radius,
|
|
maskColorString,
|
|
tool,
|
|
layer,
|
|
shouldDrawBrushPreview,
|
|
dotRadius,
|
|
strokeWidth,
|
|
brushColorString,
|
|
colorPickerColorString,
|
|
colorPickerInnerRadius,
|
|
colorPickerOuterRadius,
|
|
clip,
|
|
} = useAppSelector(canvasBrushPreviewSelector);
|
|
|
|
if (!shouldDrawBrushPreview) return null;
|
|
|
|
return (
|
|
<Group listening={false} {...clip} {...rest}>
|
|
{tool === 'colorPicker' ? (
|
|
<>
|
|
<Circle
|
|
x={brushX}
|
|
y={brushY}
|
|
radius={colorPickerOuterRadius}
|
|
stroke={brushColorString}
|
|
strokeWidth={COLOR_PICKER_STROKE_RADIUS}
|
|
strokeScaleEnabled={false}
|
|
/>
|
|
<Circle
|
|
x={brushX}
|
|
y={brushY}
|
|
radius={colorPickerInnerRadius}
|
|
stroke={colorPickerColorString}
|
|
strokeWidth={COLOR_PICKER_STROKE_RADIUS}
|
|
strokeScaleEnabled={false}
|
|
/>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Circle
|
|
x={brushX}
|
|
y={brushY}
|
|
radius={radius}
|
|
fill={layer === 'mask' ? maskColorString : brushColorString}
|
|
globalCompositeOperation={
|
|
tool === 'eraser' ? 'destination-out' : 'source-out'
|
|
}
|
|
/>
|
|
<Circle
|
|
x={brushX}
|
|
y={brushY}
|
|
radius={radius}
|
|
stroke="rgba(255,255,255,0.4)"
|
|
strokeWidth={strokeWidth * 2}
|
|
strokeEnabled={true}
|
|
listening={false}
|
|
/>
|
|
<Circle
|
|
x={brushX}
|
|
y={brushY}
|
|
radius={radius}
|
|
stroke="rgba(0,0,0,1)"
|
|
strokeWidth={strokeWidth}
|
|
strokeEnabled={true}
|
|
listening={false}
|
|
/>
|
|
</>
|
|
)}
|
|
<Circle
|
|
x={brushX}
|
|
y={brushY}
|
|
radius={dotRadius * 2}
|
|
fill="rgba(255,255,255,0.4)"
|
|
listening={false}
|
|
/>
|
|
<Circle
|
|
x={brushX}
|
|
y={brushY}
|
|
radius={dotRadius}
|
|
fill="rgba(0,0,0,1)"
|
|
listening={false}
|
|
/>
|
|
</Group>
|
|
);
|
|
};
|
|
|
|
export default IAICanvasToolPreview;
|