Skip to content

Commit cff6ed5

Browse files
feat: implement eraser tool functionality in canvas drawing
1 parent 1530c90 commit cff6ed5

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

client/src/components/Canvas.jsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const SHAPE_TYPE = {
1414
LINE: "line",
1515
PEN: "pen",
1616
CIRCLE: "circle",
17+
ERASER: "eraser",
1718
};
1819

1920
export const Canvas = () => {
@@ -194,6 +195,22 @@ export const Canvas = () => {
194195
ctx.stroke();
195196
}
196197
break;
198+
case SHAPE_TYPE.ERASER:
199+
if (shape.path && shape.path.length > 1) {
200+
ctx.save();
201+
ctx.globalCompositeOperation = "destination-out";
202+
ctx.lineWidth = shape.width;
203+
ctx.lineCap = "round";
204+
ctx.lineJoin = "round";
205+
ctx.strokeStyle = "rgba(0,0,0,1)";
206+
ctx.beginPath();
207+
ctx.moveTo(shape.path[0].x, shape.path[0].y);
208+
shape.path.forEach(p => ctx.lineTo(p.x, p.y));
209+
ctx.stroke();
210+
ctx.restore();
211+
}
212+
break;
213+
197214
default:
198215
break;
199216
}
@@ -603,6 +620,22 @@ export const Canvas = () => {
603620
manipulationMode.current = { mode: "area" };
604621
return;
605622
}
623+
if (activeTool === SHAPE_TYPE.ERASER) {
624+
setIsDrawing(true);
625+
manipulationMode.current = { mode: "erase" };
626+
const ctx = canvasRef.current.getContext("2d");
627+
ctx.save();
628+
ctx.globalCompositeOperation = "destination-out";
629+
ctx.lineWidth = strokeWidth * 2;
630+
ctx.lineCap = "round";
631+
ctx.lineJoin = "round";
632+
ctx.beginPath();
633+
const { x, y } = getWorldPoint(e);
634+
ctx.moveTo(x, y);
635+
ctx.restore();
636+
return;
637+
}
638+
606639

607640
// creation tools
608641
if (Object.values(SHAPE_TYPE).includes(activeTool) || activeTool.startsWith('brush-')) {
@@ -765,6 +798,21 @@ export const Canvas = () => {
765798

766799
// AREA select skipping here
767800
if (activeTool === 'area-select') return;
801+
if (manipulationMode.current?.mode === "erase") {
802+
const ctx = canvasRef.current.getContext("2d");
803+
ctx.save();
804+
ctx.globalCompositeOperation = "destination-out";
805+
ctx.lineWidth = strokeWidth * 2;
806+
ctx.lineCap = "round";
807+
ctx.lineJoin = "round";
808+
const { x, y } = getWorldPoint(e);
809+
ctx.lineTo(x, y);
810+
ctx.stroke();
811+
ctx.restore();
812+
return;
813+
}
814+
815+
768816

769817
// CREATE
770818
if (newShapeId.current && manipulationMode.current && manipulationMode.current.mode === 'create') {
@@ -800,6 +848,11 @@ export const Canvas = () => {
800848
setIsDrawing(false);
801849
newShapeId.current = null;
802850
manipulationMode.current = null;
851+
if (manipulationMode.current?.mode === "erase") {
852+
const ctx = canvasRef.current.getContext("2d");
853+
ctx.globalCompositeOperation = "source-over";
854+
}
855+
803856
};
804857

805858
// delete

0 commit comments

Comments
 (0)