fix(gui): remove duplicate dots caused by mouse click and down handlers both firing
This commit is contained in:
parent
684c156d68
commit
fa0cd8eaa4
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue