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();
|
updateCssCursor();
|
||||||
|
|
||||||
pencilTool.stop();
|
pencilTool.stop();
|
||||||
|
eraserTool.stop();
|
||||||
|
|
||||||
// History entries for pencil and eraser
|
// History entries for pencil and eraser
|
||||||
if (tool === "pencil" || tool === "eraser") {
|
if (tool === "pencil" || tool === "eraser") {
|
||||||
|
|
@ -212,7 +213,7 @@ function Canvas() {
|
||||||
() => setSelectionCoords([...prevSelection])
|
() => setSelectionCoords([...prevSelection])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [updateCssCursor, pencilTool, blocks, tool, addHistory, setBlocks, selectionCoords, setSelectionCoords]);
|
}, [updateCssCursor, pencilTool, eraserTool, blocks, tool, addHistory, setBlocks, selectionCoords, setSelectionCoords]);
|
||||||
|
|
||||||
const onWheel = useCallback(
|
const onWheel = useCallback(
|
||||||
(e: React.WheelEvent) => {
|
(e: React.WheelEvent) => {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import { useContext } from "react";
|
import { useContext, useRef } from "react";
|
||||||
|
|
||||||
import { CanvasContext } from "@/context/Canvas";
|
import { CanvasContext } from "@/context/Canvas";
|
||||||
import { SelectionContext } from "@/context/Selection";
|
import { SelectionContext } from "@/context/Selection";
|
||||||
import { ToolContext } from "@/context/Tool";
|
import { ToolContext } from "@/context/Tool";
|
||||||
|
|
||||||
import { useRadiusPosition } from "../useRadiusPosition";
|
import { useRadiusPosition } from "../useRadiusPosition";
|
||||||
|
import { interpolate } from "@/utils/interpolate";
|
||||||
|
|
||||||
export function useEraserTool(mouseCoords: Position) {
|
export function useEraserTool(mouseCoords: Position) {
|
||||||
const { blocks, setBlocks } = useContext(CanvasContext);
|
const { blocks, setBlocks } = useContext(CanvasContext);
|
||||||
|
|
@ -12,16 +13,41 @@ export function useEraserTool(mouseCoords: Position) {
|
||||||
const { radius } = useContext(ToolContext);
|
const { radius } = useContext(ToolContext);
|
||||||
|
|
||||||
const radiusPosition = useRadiusPosition(mouseCoords);
|
const radiusPosition = useRadiusPosition(mouseCoords);
|
||||||
|
const lastPosition = useRef<Position | null>(null);
|
||||||
|
|
||||||
const use = () => {
|
const stop = () => {
|
||||||
const updated = blocks.filter((block) => {
|
lastPosition.current = null;
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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