fix: holes in eraser tool
This commit is contained in:
parent
620f15aaed
commit
776a36c11d
2 changed files with 38 additions and 11 deletions
|
|
@ -189,6 +189,7 @@ function Canvas() {
|
|||
updateCssCursor();
|
||||
|
||||
pencilTool.stop();
|
||||
eraserTool.stop();
|
||||
|
||||
// History entries for pencil and eraser
|
||||
if (tool === "pencil" || tool === "eraser") {
|
||||
|
|
@ -212,7 +213,7 @@ function Canvas() {
|
|||
() => setSelectionCoords([...prevSelection])
|
||||
);
|
||||
}
|
||||
}, [updateCssCursor, pencilTool, blocks, tool, addHistory, setBlocks, selectionCoords, setSelectionCoords]);
|
||||
}, [updateCssCursor, pencilTool, eraserTool, blocks, tool, addHistory, setBlocks, selectionCoords, setSelectionCoords]);
|
||||
|
||||
const onWheel = useCallback(
|
||||
(e: React.WheelEvent) => {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { useContext } from "react";
|
||||
import { useContext, useRef } from "react";
|
||||
|
||||
import { CanvasContext } from "@/context/Canvas";
|
||||
import { SelectionContext } from "@/context/Selection";
|
||||
import { ToolContext } from "@/context/Tool";
|
||||
|
||||
import { useRadiusPosition } from "../useRadiusPosition";
|
||||
import { interpolate } from "@/utils/interpolate";
|
||||
|
||||
export function useEraserTool(mouseCoords: Position) {
|
||||
const { blocks, setBlocks } = useContext(CanvasContext);
|
||||
|
|
@ -12,16 +13,41 @@ export function useEraserTool(mouseCoords: Position) {
|
|||
const { radius } = useContext(ToolContext);
|
||||
|
||||
const radiusPosition = useRadiusPosition(mouseCoords);
|
||||
const lastPosition = useRef<Position | null>(null);
|
||||
|
||||
const use = () => {
|
||||
const updated = blocks.filter((block) => {
|
||||
const withinRadius =
|
||||
block.x >= radiusPosition.x && block.x < radiusPosition.x + radius && block.y >= radiusPosition.y && block.y < radiusPosition.y + radius;
|
||||
return !withinRadius || !isInSelection(block.x, block.y);
|
||||
});
|
||||
|
||||
setBlocks(updated);
|
||||
const stop = () => {
|
||||
lastPosition.current = null;
|
||||
};
|
||||
|
||||
return { use };
|
||||
const use = () => {
|
||||
const positions: Position[] = [];
|
||||
|
||||
const eraseBlock = (x: number, y: number) => {
|
||||
if (isInSelection(x, y)) {
|
||||
positions.push({ x, y });
|
||||
}
|
||||
};
|
||||
|
||||
// Interpolate to ensure continuous erasing
|
||||
if (lastPosition.current) {
|
||||
const interpolatedPositions = interpolate(radius, lastPosition.current, radiusPosition);
|
||||
if (!interpolatedPositions) return;
|
||||
|
||||
interpolatedPositions.forEach(({ x, y }) => eraseBlock(x, y));
|
||||
} else {
|
||||
for (let x = 0; x < radius; x++) {
|
||||
for (let y = 0; y < radius; y++) {
|
||||
eraseBlock(radiusPosition.x + x, radiusPosition.y + y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter out erased blocks
|
||||
const updatedBlocks = blocks.filter((block) => !positions.some((b) => block.x === b.x && block.y === b.y));
|
||||
|
||||
setBlocks(updatedBlocks);
|
||||
lastPosition.current = radiusPosition;
|
||||
};
|
||||
|
||||
return { stop, use };
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue