fix: slight performance improvements
This commit is contained in:
parent
6773f7f87d
commit
fba6ccdb80
3 changed files with 38 additions and 35 deletions
|
|
@ -21,44 +21,43 @@ settings.use32bitIndex = true;
|
||||||
function Blocks({ blocks, missingTexture, textures, coords, scale, version, isSelectionLayer }: Props) {
|
function Blocks({ blocks, missingTexture, textures, coords, scale, version, isSelectionLayer }: Props) {
|
||||||
const app = useApp();
|
const app = useApp();
|
||||||
const tilemapRef = useRef<CompositeTilemap>();
|
const tilemapRef = useRef<CompositeTilemap>();
|
||||||
|
const containerRef = useRef<PIXI.Container>();
|
||||||
|
|
||||||
const tileBlocks = () => {
|
useEffect(() => {
|
||||||
if (!tilemapRef.current) return;
|
if (!tilemapRef.current) return;
|
||||||
const tilemap = tilemapRef.current;
|
const tilemap = tilemapRef.current;
|
||||||
|
|
||||||
tilemap.clear();
|
tilemap.clear();
|
||||||
|
|
||||||
// Tile solid colors at smaller scales
|
// Tile solid colors at smaller scales
|
||||||
blocks.forEach((block) => {
|
blocks.forEach((block) => {
|
||||||
tilemap.tile(textures[block.name] ?? missingTexture, block.x * 16, block.y * 16);
|
tilemap.tile(textures[block.name] ?? missingTexture, block.x * 16, block.y * 16);
|
||||||
});
|
});
|
||||||
};
|
}, [blocks, version]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (containerRef.current) return;
|
||||||
|
|
||||||
const container = new PIXI.Container();
|
const container = new PIXI.Container();
|
||||||
|
containerRef.current = container;
|
||||||
|
|
||||||
// Put selection layer on top of the blocks layer
|
// Put selection layer on top of the blocks layer
|
||||||
app.stage.addChildAt(container, isSelectionLayer ? 1 : 0);
|
app.stage.addChildAt(container, isSelectionLayer ? 1 : 0);
|
||||||
|
|
||||||
const tilemap = new CompositeTilemap();
|
const tilemap = new CompositeTilemap();
|
||||||
tilemapRef.current = tilemap;
|
tilemapRef.current = tilemap;
|
||||||
|
|
||||||
if (isSelectionLayer) {
|
|
||||||
container.filters = [new PIXI.AlphaFilter(0.5)];
|
|
||||||
}
|
|
||||||
|
|
||||||
container.addChild(tilemap);
|
container.addChild(tilemap);
|
||||||
tileBlocks();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(tileBlocks, [blocks, version]);
|
if (isSelectionLayer) container.filters = [new PIXI.AlphaFilter(0.5)];
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!tilemapRef.current) return;
|
if (!tilemapRef.current) return;
|
||||||
|
const tilemap = tilemapRef.current;
|
||||||
|
|
||||||
tileBlocks();
|
tilemap.x = coords.x;
|
||||||
|
tilemap.y = coords.y;
|
||||||
tilemapRef.current.x = coords.x;
|
tilemap.scale.set(scale, scale);
|
||||||
tilemapRef.current.y = coords.y;
|
|
||||||
tilemapRef.current.scale.set(scale, scale);
|
|
||||||
}, [coords, scale]);
|
}, [coords, scale]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -53,10 +53,10 @@ function Canvas() {
|
||||||
const blockData = useBlockData(version);
|
const blockData = useBlockData(version);
|
||||||
const stageContainerRef = useRef<HTMLDivElement>(null);
|
const stageContainerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const [mousePosition, setMousePosition] = useState<Position>({ x: 0, y: 0 });
|
const mousePosition = useRef<Position>({ x: 0, y: 0 });
|
||||||
const [mouseCoords, setMouseCoords] = useState<Position>({ x: 0, y: 0 });
|
const [mouseCoords, setMouseCoords] = useState<Position>({ x: 0, y: 0 });
|
||||||
const mouseMovementRef = useRef<Position>({ x: 0, y: 0 });
|
const mouseMovementRef = useRef<Position>({ x: 0, y: 0 });
|
||||||
const [dragging, setDragging] = useState(false);
|
const dragging = useRef(false);
|
||||||
const dragStartCoordsRef = useRef<Position>({ x: 0, y: 0 });
|
const dragStartCoordsRef = useRef<Position>({ x: 0, y: 0 });
|
||||||
|
|
||||||
const holdingShiftRef = useRef(false);
|
const holdingShiftRef = useRef(false);
|
||||||
|
|
@ -78,7 +78,7 @@ function Canvas() {
|
||||||
const paintBucketTool = usePaintBucketTool(mouseCoords);
|
const paintBucketTool = usePaintBucketTool(mouseCoords);
|
||||||
const shapeTool = useShapeTool(mouseCoords, dragStartCoordsRef.current, holdingShiftRef.current);
|
const shapeTool = useShapeTool(mouseCoords, dragStartCoordsRef.current, holdingShiftRef.current);
|
||||||
const eyedropperTool = useEyedropperTool(mouseCoords);
|
const eyedropperTool = useEyedropperTool(mouseCoords);
|
||||||
const zoomTool = useZoomTool(mousePosition, holdingAltRef.current);
|
const zoomTool = useZoomTool(mousePosition.current, holdingAltRef.current);
|
||||||
|
|
||||||
const visibleArea = useMemo(() => {
|
const visibleArea = useMemo(() => {
|
||||||
const blockSize = 16 * scale;
|
const blockSize = 16 * scale;
|
||||||
|
|
@ -105,7 +105,7 @@ function Canvas() {
|
||||||
|
|
||||||
const updateCssCursor = useCallback(() => {
|
const updateCssCursor = useCallback(() => {
|
||||||
const cursorMapping: Partial<Record<Tool, string>> = {
|
const cursorMapping: Partial<Record<Tool, string>> = {
|
||||||
hand: dragging ? "grab" : "grabbing",
|
hand: dragging.current ? "grabbing" : "grab",
|
||||||
move: "move",
|
move: "move",
|
||||||
zoom: holdingAltRef.current ? "zoom-out" : "zoom-in",
|
zoom: holdingAltRef.current ? "zoom-out" : "zoom-in",
|
||||||
};
|
};
|
||||||
|
|
@ -132,7 +132,7 @@ function Canvas() {
|
||||||
tools[tool]?.use();
|
tools[tool]?.use();
|
||||||
}, [tool, selectedBlock, moveTool, rectangleSelectTool, lassoTool, pencilTool, eraserTool, shapeTool]);
|
}, [tool, selectedBlock, moveTool, rectangleSelectTool, lassoTool, pencilTool, eraserTool, shapeTool]);
|
||||||
|
|
||||||
const onMouseMove = useCallback(
|
const onPointerMove = useCallback(
|
||||||
(e: React.MouseEvent) => {
|
(e: React.MouseEvent) => {
|
||||||
if (!stageContainerRef.current) return;
|
if (!stageContainerRef.current) return;
|
||||||
const oldMouseCoords = mouseCoords;
|
const oldMouseCoords = mouseCoords;
|
||||||
|
|
@ -146,18 +146,20 @@ function Canvas() {
|
||||||
y: Math.floor((mouseY - coords.y) / (16 * scale)),
|
y: Math.floor((mouseY - coords.y) / (16 * scale)),
|
||||||
};
|
};
|
||||||
|
|
||||||
setMousePosition({
|
mousePosition.current = {
|
||||||
x: mouseX,
|
x: mouseX,
|
||||||
y: mouseY,
|
y: mouseY,
|
||||||
});
|
};
|
||||||
|
if (newMouseCoords.x !== mouseCoords.x || newMouseCoords.y !== mouseCoords.y) {
|
||||||
setMouseCoords(newMouseCoords);
|
setMouseCoords(newMouseCoords);
|
||||||
|
}
|
||||||
|
|
||||||
mouseMovementRef.current = {
|
mouseMovementRef.current = {
|
||||||
x: newMouseCoords.x - oldMouseCoords.x,
|
x: newMouseCoords.x - oldMouseCoords.x,
|
||||||
y: newMouseCoords.y - oldMouseCoords.y,
|
y: newMouseCoords.y - oldMouseCoords.y,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (dragging) {
|
if (dragging.current) {
|
||||||
if (tool === "hand") {
|
if (tool === "hand") {
|
||||||
setCoords((prevCoords) => ({
|
setCoords((prevCoords) => ({
|
||||||
x: prevCoords.x + e.movementX,
|
x: prevCoords.x + e.movementX,
|
||||||
|
|
@ -172,7 +174,8 @@ function Canvas() {
|
||||||
);
|
);
|
||||||
|
|
||||||
const onMouseDown = useCallback(() => {
|
const onMouseDown = useCallback(() => {
|
||||||
setDragging(true);
|
dragging.current = true;
|
||||||
|
|
||||||
onToolUse();
|
onToolUse();
|
||||||
updateCssCursor();
|
updateCssCursor();
|
||||||
|
|
||||||
|
|
@ -185,7 +188,8 @@ function Canvas() {
|
||||||
}, [onToolUse, updateCssCursor, mouseCoords, blocks, selectionCoords, tool, setSelectionCoords]);
|
}, [onToolUse, updateCssCursor, mouseCoords, blocks, selectionCoords, tool, setSelectionCoords]);
|
||||||
|
|
||||||
const onMouseUp = useCallback(() => {
|
const onMouseUp = useCallback(() => {
|
||||||
setDragging(false);
|
dragging.current = false;
|
||||||
|
|
||||||
updateCssCursor();
|
updateCssCursor();
|
||||||
|
|
||||||
pencilTool.stop();
|
pencilTool.stop();
|
||||||
|
|
@ -203,7 +207,7 @@ function Canvas() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tool === "rectangle-select" || tool === "magic-wand" || tool === "lasso") {
|
if (["rectangle-select", "magic-wand", "lasso"].includes(tool)) {
|
||||||
// startSelectionCoordsRef will mutate if we pass it directly
|
// startSelectionCoordsRef will mutate if we pass it directly
|
||||||
const prevSelection = [...startSelectionCoordsRef.current];
|
const prevSelection = [...startSelectionCoordsRef.current];
|
||||||
|
|
||||||
|
|
@ -223,8 +227,8 @@ function Canvas() {
|
||||||
|
|
||||||
setScale(newScale);
|
setScale(newScale);
|
||||||
setCoords({
|
setCoords({
|
||||||
x: mousePosition.x - ((mousePosition.x - coords.x) / scale) * newScale,
|
x: mousePosition.current.x - ((mousePosition.current.x - coords.x) / scale) * newScale,
|
||||||
y: mousePosition.y - ((mousePosition.y - coords.y) / scale) * newScale,
|
y: mousePosition.current.y - ((mousePosition.current.y - coords.y) / scale) * newScale,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[scale, setScale, setCoords, mousePosition, coords]
|
[scale, setScale, setCoords, mousePosition, coords]
|
||||||
|
|
@ -263,7 +267,7 @@ function Canvas() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case " ": // Space
|
case " ": // Space
|
||||||
setDragging(true);
|
dragging.current = true;
|
||||||
oldToolRef.current = tool;
|
oldToolRef.current = tool;
|
||||||
setTool("hand");
|
setTool("hand");
|
||||||
setCssCursor("grabbing");
|
setCssCursor("grabbing");
|
||||||
|
|
@ -390,7 +394,7 @@ function Canvas() {
|
||||||
(e: React.KeyboardEvent) => {
|
(e: React.KeyboardEvent) => {
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
case " ": // Space
|
case " ": // Space
|
||||||
setDragging(false);
|
dragging.current = false;
|
||||||
setCssCursor("grab");
|
setCssCursor("grab");
|
||||||
|
|
||||||
if (!oldToolRef.current) return;
|
if (!oldToolRef.current) return;
|
||||||
|
|
@ -455,8 +459,8 @@ function Canvas() {
|
||||||
onPinch: ({ offset: [d] }) => {
|
onPinch: ({ offset: [d] }) => {
|
||||||
setScale(d);
|
setScale(d);
|
||||||
setCoords({
|
setCoords({
|
||||||
x: mousePosition.x - ((mousePosition.x - coords.x) / scale) * d,
|
x: mousePosition.current.x - ((mousePosition.current.x - coords.x) / scale) * d,
|
||||||
y: mousePosition.y - ((mousePosition.y - coords.y) / scale) * d,
|
y: mousePosition.current.y - ((mousePosition.current.y - coords.y) / scale) * d,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -477,7 +481,7 @@ function Canvas() {
|
||||||
onKeyDown={onKeyDown}
|
onKeyDown={onKeyDown}
|
||||||
onKeyUp={onKeyUp}
|
onKeyUp={onKeyUp}
|
||||||
onPointerDown={onMouseDown}
|
onPointerDown={onMouseDown}
|
||||||
onPointerMove={onMouseMove}
|
onPointerMove={onPointerMove}
|
||||||
onPointerUp={onMouseUp}
|
onPointerUp={onMouseUp}
|
||||||
onWheel={onWheel}
|
onWheel={onWheel}
|
||||||
options={{ backgroundAlpha: 0 }}
|
options={{ backgroundAlpha: 0 }}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export function useEraserTool(mouseCoords: Position) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Interpolate to ensure continuous erasing
|
// Interpolate to remove holes
|
||||||
if (lastPosition.current) {
|
if (lastPosition.current) {
|
||||||
const interpolatedPositions = interpolate(radius, lastPosition.current, radiusPosition);
|
const interpolatedPositions = interpolate(radius, lastPosition.current, radiusPosition);
|
||||||
if (!interpolatedPositions) return;
|
if (!interpolatedPositions) return;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue