Skip to content

Commit

Permalink
fix(gui): draw single clicks and avoid blending mask with itself
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed Jan 19, 2023
1 parent df7bba4 commit 5e23f84
Showing 1 changed file with 56 additions and 48 deletions.
104 changes: 56 additions & 48 deletions gui/src/components/input/MaskCanvas.tsx
Expand Up @@ -48,19 +48,6 @@ export function MaskCanvas(props: MaskCanvasProps) {
const { source, mask } = props;
const { params } = mustExist(useContext(ConfigContext));

function saveMask(): void {
if (doesExist(bufferRef.current)) {
if (maskState.current === MASK_STATE.clean) {
return;
}

bufferRef.current.toBlob((blob) => {
maskState.current = MASK_STATE.clean;
props.onSave(mustExist(blob));
});
}
}

function drawBuffer() {
if (doesExist(brushRef.current) && doesExist(bufferRef.current) && doesExist(canvasRef.current)) {
const { ctx } = getClearContext(canvasRef);
Expand All @@ -73,10 +60,38 @@ export function MaskCanvas(props: MaskCanvasProps) {
}
}

function drawBrush(point: Point): void {
const { ctx } = getClearContext(brushRef);
ctx.fillStyle = grayToRGB(brush.color, brush.strength);

drawCircle(ctx, {
x: point.x,
y: point.y,
}, brush.size);

drawBuffer();
}

function drawClicks(): void {
if (clicks.length > 0) {
const { ctx } = getContext(bufferRef);
ctx.fillStyle = grayToRGB(brush.color, brush.strength);

for (const click of clicks) {
drawCircle(ctx, click, brush.size);
}

clicks.length = 0;

drawBuffer();
}
}

function drawSource(file: Blob): void {
const image = new Image();
image.onload = () => {
const { ctx } = getContext(bufferRef);
const { ctx } = getClearContext(bufferRef);
ctx.globalAlpha = 1.0;
ctx.drawImage(image, 0, 0);
URL.revokeObjectURL(src);

Expand All @@ -90,12 +105,25 @@ export function MaskCanvas(props: MaskCanvasProps) {
function finishPainting() {
if (doesExist(brushRef.current)) {
getClearContext(brushRef);
drawBuffer();
}

drawClicks();

if (maskState.current === MASK_STATE.painting) {
maskState.current = MASK_STATE.dirty;
save();
}
}

function saveMask(): void {
if (doesExist(bufferRef.current)) {
if (maskState.current === MASK_STATE.clean) {
return;
}

bufferRef.current.toBlob((blob) => {
maskState.current = MASK_STATE.clean;
props.onSave(mustExist(blob));
});
}
}

Expand All @@ -118,21 +146,6 @@ export function MaskCanvas(props: MaskCanvasProps) {
// eslint-disable-next-line @typescript-eslint/unbound-method
const setBrush = useStore(state, (s) => s.setBrush);

useEffect(() => {
// including clicks.length prevents the initial render from saving a blank canvas
if (doesExist(bufferRef.current) && maskState.current === MASK_STATE.painting && clicks.length > 0) {
const { ctx } = getContext(bufferRef);
ctx.fillStyle = grayToRGB(brush.color, brush.strength);

for (const click of clicks) {
drawCircle(ctx, click, brush.size);
}

clicks.length = 0;
drawBuffer();
}
}, [clicks.length]);

useEffect(() => {
if (maskState.current === MASK_STATE.dirty) {
save();
Expand All @@ -155,6 +168,9 @@ export function MaskCanvas(props: MaskCanvasProps) {
}
}, [source]);

// last resort to draw lost clicks
drawClicks();

const styles: React.CSSProperties = {
border: '1px solid black',
maxHeight: params.height.default,
Expand Down Expand Up @@ -191,16 +207,13 @@ export function MaskCanvas(props: MaskCanvasProps) {
const canvas = mustExist(canvasRef.current);
const bounds = canvas.getBoundingClientRect();

const { ctx } = getContext(bufferRef);
ctx.fillStyle = grayToRGB(brush.color, brush.strength);

drawCircle(ctx, {
setClicks([...clicks, {
x: event.clientX - bounds.left,
y: event.clientY - bounds.top,
}, brush.size);
}]);

drawClicks();
maskState.current = MASK_STATE.dirty;
save();
}}
onMouseDown={() => {
maskState.current = MASK_STATE.painting;
Expand All @@ -218,15 +231,10 @@ export function MaskCanvas(props: MaskCanvasProps) {
y: event.clientY - bounds.top,
}]);
} else {
const { ctx } = getClearContext(brushRef);
ctx.fillStyle = grayToRGB(brush.color, brush.strength);

drawCircle(ctx, {
drawBrush({
x: event.clientX - bounds.left,
y: event.clientY - bounds.top,
}, brush.size);

drawBuffer();
});
}
}}
/>
Expand Down Expand Up @@ -272,7 +280,7 @@ export function MaskCanvas(props: MaskCanvasProps) {
onClick={() => {
floodCanvas(bufferRef, floodBelow);
drawBuffer();
save();
maskState.current = MASK_STATE.dirty;
}}>
Gray to black
</Button>
Expand All @@ -282,7 +290,7 @@ export function MaskCanvas(props: MaskCanvasProps) {
onClick={() => {
floodCanvas(bufferRef, floodBlack);
drawBuffer();
save();
maskState.current = MASK_STATE.dirty;
}}>
Fill with black
</Button>
Expand All @@ -292,7 +300,7 @@ export function MaskCanvas(props: MaskCanvasProps) {
onClick={() => {
floodCanvas(bufferRef, floodWhite);
drawBuffer();
save();
maskState.current = MASK_STATE.dirty;
}}>
Fill with white
</Button>
Expand All @@ -302,7 +310,7 @@ export function MaskCanvas(props: MaskCanvasProps) {
onClick={() => {
floodCanvas(bufferRef, floodAbove);
drawBuffer();
save();
maskState.current = MASK_STATE.dirty;
}}>
Gray to white
</Button>
Expand Down

0 comments on commit 5e23f84

Please sign in to comment.