1
0
Fork 0

fix(gui): remove duplicate dots caused by mouse click and down handlers both firing

This commit is contained in:
Sean Sube 2023-02-13 08:43:11 -06:00
parent 684c156d68
commit fa0cd8eaa4
Signed by: ssube
GPG Key ID: 3EED7B957D362AF1
1 changed files with 42 additions and 50 deletions

View File

@ -42,7 +42,7 @@ export interface MaskCanvasProps {
onSave: (blob: Blob) => void; onSave: (blob: Blob) => void;
} }
const logger = createLogger({ name: 'react', level: 'info' }); // TODO: hackeroni and cheese const logger = createLogger({ name: 'react', level: 'debug' }); // TODO: hackeroni and cheese
export function MaskCanvas(props: MaskCanvasProps) { export function MaskCanvas(props: MaskCanvasProps) {
const { source, mask } = props; const { source, mask } = props;
@ -106,6 +106,23 @@ export function MaskCanvas(props: MaskCanvasProps) {
} }
} }
function drawMouse(event: React.MouseEvent<HTMLCanvasElement>) {
const canvas = mustExist(viewRef.current);
const bounds = canvas.getBoundingClientRect();
if (painting.current) {
drawClicks([{
x: event.clientX - bounds.left,
y: event.clientY - bounds.top,
}]);
} else {
drawBrush({
x: event.clientX - bounds.left,
y: event.clientY - bounds.top,
});
}
}
function drawUndo(): void { function drawUndo(): void {
if (doesExist(maskRef.current) && doesExist(undoRef.current)) { if (doesExist(maskRef.current) && doesExist(undoRef.current)) {
logger.debug('draw undo'); logger.debug('draw undo');
@ -131,6 +148,16 @@ export function MaskCanvas(props: MaskCanvasProps) {
} }
} }
function drawFill(fn: FloodFn): void {
saveUndo();
floodCanvas(maskRef, fn);
composite();
dirty.current = true;
}
/**
* Save the current mask to the undo canvas.
*/
function saveUndo(): void { function saveUndo(): void {
if (doesExist(maskRef.current) && doesExist(undoRef.current)) { if (doesExist(maskRef.current) && doesExist(undoRef.current)) {
logger.debug('save undo'); logger.debug('save undo');
@ -139,6 +166,9 @@ export function MaskCanvas(props: MaskCanvasProps) {
} }
} }
/**
* Save the current mask to state, so that it persists between tabs.
*/
function saveMask(): void { function saveMask(): void {
if (doesExist(maskRef.current)) { if (doesExist(maskRef.current)) {
logger.debug('save mask', { dirty: dirty.current }); logger.debug('save mask', { dirty: dirty.current });
@ -183,7 +213,7 @@ export function MaskCanvas(props: MaskCanvasProps) {
useEffect(() => { useEffect(() => {
if (doesExist(maskRef.current) && doesExist(mask)) { if (doesExist(maskRef.current) && doesExist(mask)) {
drawMask(mask).catch((err) => { drawMask(mask).catch((err) => {
// TODO: handle logger.error(err, 'error drawing mask for effect');
}); });
} }
}, [mask]); }, [mask]);
@ -246,41 +276,18 @@ export function MaskCanvas(props: MaskCanvasProps) {
height={params.height.default} height={params.height.default}
width={params.width.default} width={params.width.default}
style={backgroundStyle} style={backgroundStyle}
onClick={(event) => { onMouseDown={(event) => {
logger.debug('mouse click', { state: painting.current });
const canvas = mustExist(viewRef.current);
const bounds = canvas.getBoundingClientRect();
drawClicks([{
x: event.clientX - bounds.left,
y: event.clientY - bounds.top,
}]);
}}
onMouseDown={() => {
logger.debug('mouse down', { state: painting.current }); logger.debug('mouse down', { state: painting.current });
painting.current = true;
saveUndo(); saveUndo();
painting.current = true;
drawMouse(event);
}} }}
onMouseLeave={finishPainting} onMouseLeave={finishPainting}
onMouseOut={finishPainting} onMouseOut={finishPainting}
onMouseUp={finishPainting} onMouseUp={finishPainting}
onMouseMove={(event) => { onMouseMove={drawMouse}
const canvas = mustExist(viewRef.current);
const bounds = canvas.getBoundingClientRect();
if (painting.current) {
drawClicks([{
x: event.clientX - bounds.left,
y: event.clientY - bounds.top,
}]);
} else {
drawBrush({
x: event.clientX - bounds.left,
y: event.clientY - bounds.top,
});
}
}}
/> />
<Typography variant='body1'> <Typography variant='body1'>
Black pixels in the mask will stay the same, white pixels will be replaced. The masked pixels will be blended Black pixels in the mask will stay the same, white pixels will be replaced. The masked pixels will be blended
@ -330,10 +337,7 @@ export function MaskCanvas(props: MaskCanvasProps) {
variant='outlined' variant='outlined'
startIcon={<FormatColorFill />} startIcon={<FormatColorFill />}
onClick={() => { onClick={() => {
saveUndo(); drawFill(floodBlack);
floodCanvas(maskRef, floodBlack);
composite();
dirty.current = true;
}}> }}>
Fill with black Fill with black
</Button> </Button>
@ -341,10 +345,7 @@ export function MaskCanvas(props: MaskCanvasProps) {
variant='outlined' variant='outlined'
startIcon={<FormatColorFill />} startIcon={<FormatColorFill />}
onClick={() => { onClick={() => {
saveUndo(); drawFill(floodWhite);
floodCanvas(maskRef, floodWhite);
composite();
dirty.current = true;
}}> }}>
Fill with white Fill with white
</Button> </Button>
@ -352,10 +353,7 @@ export function MaskCanvas(props: MaskCanvasProps) {
variant='outlined' variant='outlined'
startIcon={<InvertColors />} startIcon={<InvertColors />}
onClick={() => { onClick={() => {
saveUndo(); drawFill(floodInvert);
floodCanvas(maskRef, floodInvert);
composite();
dirty.current = true;
}}> }}>
Invert Invert
</Button> </Button>
@ -363,10 +361,7 @@ export function MaskCanvas(props: MaskCanvasProps) {
variant='outlined' variant='outlined'
startIcon={<Gradient />} startIcon={<Gradient />}
onClick={() => { onClick={() => {
saveUndo(); drawFill(floodBelow);
floodCanvas(maskRef, floodBelow);
composite();
dirty.current = true;
}}> }}>
Gray to black Gray to black
</Button> </Button>
@ -374,10 +369,7 @@ export function MaskCanvas(props: MaskCanvasProps) {
variant='outlined' variant='outlined'
startIcon={<Gradient />} startIcon={<Gradient />}
onClick={() => { onClick={() => {
saveUndo(); drawFill(floodAbove);
floodCanvas(maskRef, floodAbove);
composite();
dirty.current = true;
}}> }}>
Gray to white Gray to white
</Button> </Button>