David Regla e46102124e [WebUI] Even off JSX string props
Increased consistency and readability by replacing any unnecessary JSX expressions in places where string literals are sufficient
2023-02-16 19:54:25 +11:00

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;