fix: limit placing blocks to selection
This commit is contained in:
parent
603e3537db
commit
ae9f8500e7
1 changed files with 42 additions and 29 deletions
|
|
@ -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) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue