fix: limit placing blocks to selection

This commit is contained in:
trafficlunar 2025-01-15 22:19:36 +00:00
parent 603e3537db
commit ae9f8500e7

View file

@ -87,40 +87,38 @@ function Canvas() {
}, [dragging, holdingAlt, tool, setCssCursor]); }, [dragging, holdingAlt, tool, setCssCursor]);
const onToolUse = useCallback(() => { const onToolUse = useCallback(() => {
// Radius calculation - if odd number cursor is in center, if even cursor is in top-left corner // If selection box is there
const getBlocksWithinRadius = (centerX: number, centerY: number, radius: number, blockName: string): Block[] => { if (!(selectionBoxBounds.maxX == selectionBoxBounds.minX && selectionBoxBounds.maxY == selectionBoxBounds.maxY)) {
const radiusBlocks = []; // If the mouse is not in the selection, return
const halfSize = Math.floor(radius / 2); if (
!(
const startX = centerX - (radius % 2 === 0 ? 0 : halfSize); mouseCoords.x >= selectionBoxBounds.minX &&
const startY = centerY - (radius % 2 === 0 ? 0 : halfSize); mouseCoords.x <= selectionBoxBounds.maxX - 1 &&
mouseCoords.y >= selectionBoxBounds.minY &&
for (let x = 0; x < radius; x++) { mouseCoords.y <= selectionBoxBounds.maxY - 1
for (let y = 0; y < radius; y++) { )
const tileX = startX + x; ) {
const tileY = startY + y; return;
radiusBlocks.push({
name: blockName,
x: tileX,
y: tileY,
});
}
} }
}
return radiusBlocks; // Radius calculation - if odd number cursor is in center, if even cursor is in top-left corner
const getRadiusPosition = (): Position => {
const halfSize = Math.floor(radius / 2);
const x = mouseCoords.x - (radius % 2 === 0 ? 0 : halfSize);
const y = mouseCoords.y - (radius % 2 === 0 ? 0 : halfSize);
return { x, y };
}; };
const eraseTool = () => { const eraseTool = () => {
// Fixes Infinity and NaN errors // Fixes Infinity and NaN errors
if (blocks.length == 1) return; if (blocks.length == 1) return;
const halfSize = Math.floor(radius / 2); const radiusPosition = getRadiusPosition();
const startX = mouseCoords.x - (radius % 2 === 0 ? 0 : halfSize);
const startY = mouseCoords.y - (radius % 2 === 0 ? 0 : halfSize);
const updated = blocks.filter((block) => { const updated = blocks.filter((block) => {
const withinSquare = block.x >= startX && block.x < startX + radius && block.y >= startY && block.y < startY + radius; const withinSquare =
block.x >= radiusPosition.x && block.x < radiusPosition.x + radius && block.y >= radiusPosition.y && block.y < radiusPosition.y + radius;
return !withinSquare; return !withinSquare;
}); });
@ -134,12 +132,27 @@ function Canvas() {
break; break;
} }
const newBlocks = getBlocksWithinRadius(mouseCoords.x, mouseCoords.y, radius, selectedBlock); const radiusPosition = getRadiusPosition();
const radiusBlocks: Block[] = [];
for (let x = 0; x < radius; x++) {
for (let y = 0; y < radius; y++) {
const tileX = radiusPosition.x + x;
const tileY = radiusPosition.y + y;
radiusBlocks.push({
name: selectedBlock,
x: tileX,
y: tileY,
});
}
}
const mergedBlocks = blocks.filter((block) => { const mergedBlocks = blocks.filter((block) => {
return !newBlocks.some((newBlock) => block.x === newBlock.x && block.y === newBlock.y); return !radiusBlocks.some((newBlock) => block.x === newBlock.x && block.y === newBlock.y);
}); });
setBlocks([...mergedBlocks, ...newBlocks]); setBlocks([...mergedBlocks, ...radiusBlocks]);
break; break;
} }
case "eraser": { case "eraser": {
@ -147,7 +160,7 @@ function Canvas() {
break; break;
} }
} }
}, [tool, mouseCoords, selectedBlock, setBlocks, blocks, radius]); }, [tool, mouseCoords, selectedBlock, blocks, radius, selectionBoxBounds, setBlocks]);
const onMouseMove = useCallback( const onMouseMove = useCallback(
(e: React.MouseEvent) => { (e: React.MouseEvent) => {