refactor: move canvasSize and blocks to context

This commit is contained in:
trafficlunar 2024-12-20 22:01:03 +00:00
parent afc53f48a2
commit b8f55b401f
3 changed files with 57 additions and 37 deletions

View file

@ -3,6 +3,7 @@ import React, { useCallback, useContext, useEffect, useMemo, useRef, useState }
import * as PIXI from "pixi.js"; import * as PIXI from "pixi.js";
import { Container, Stage } from "@pixi/react"; import { Container, Stage } from "@pixi/react";
import { CanvasContext } from "@/context/Canvas";
import { ImageContext } from "@/context/Image"; import { ImageContext } from "@/context/Image";
import { SettingsContext } from "@/context/Settings"; import { SettingsContext } from "@/context/Settings";
import { TexturesContext } from "@/context/Textures"; import { TexturesContext } from "@/context/Textures";
@ -22,6 +23,7 @@ import welcomeBlocksData from "@/data/welcome.json";
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST; PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
function Canvas() { function Canvas() {
const { canvasSize, blocks, setBlocks } = useContext(CanvasContext);
const { image, imageDimensions } = useContext(ImageContext); const { image, imageDimensions } = useContext(ImageContext);
const { settings } = useContext(SettingsContext); const { settings } = useContext(SettingsContext);
const textures = useContext(TexturesContext); const textures = useContext(TexturesContext);
@ -37,8 +39,6 @@ function Canvas() {
const [mouseCoords, setMouseCoords] = useState<Position>({ x: 0, y: 0 }); const [mouseCoords, setMouseCoords] = useState<Position>({ x: 0, y: 0 });
const [dragging, setDragging] = useState(false); const [dragging, setDragging] = useState(false);
const [blocks, setBlocks] = useState<Block[]>([]);
const [holdingAlt, setHoldingAlt] = useState(false); const [holdingAlt, setHoldingAlt] = useState(false);
const [oldTool, setOldTool] = useState<Tool>("hand"); const [oldTool, setOldTool] = useState<Tool>("hand");
@ -46,27 +46,6 @@ function Canvas() {
return blocks.filter((b) => !(b.x === mouseCoords.x && b.y === mouseCoords.y)); return blocks.filter((b) => !(b.x === mouseCoords.x && b.y === mouseCoords.y));
}, [blocks, mouseCoords]); }, [blocks, mouseCoords]);
const canvasSize = useMemo(() => {
let minX = Infinity,
maxX = -Infinity;
let minY = Infinity,
maxY = -Infinity;
blocks.forEach((coord) => {
if (coord.x < minX) minX = coord.x;
if (coord.x > maxX) maxX = coord.x;
if (coord.y < minY) minY = coord.y;
if (coord.y > maxY) maxY = coord.y;
});
return {
minX,
minY,
maxX: maxX + 1,
maxY: maxY + 1,
};
}, [blocks]);
const visibleArea = useMemo(() => { const visibleArea = useMemo(() => {
const blockSize = 16 * scale; const blockSize = 16 * scale;
@ -126,7 +105,7 @@ function Canvas() {
setBlocks(updatedBlocks); setBlocks(updatedBlocks);
break; break;
} }
}, [tool, mouseCoords, selectedBlock, updatedBlocks]); }, [tool, mouseCoords, selectedBlock, updatedBlocks, setBlocks]);
const onMouseMove = useCallback( const onMouseMove = useCallback(
(e: React.MouseEvent) => { (e: React.MouseEvent) => {

38
src/context/Canvas.tsx Normal file
View file

@ -0,0 +1,38 @@
import React, { createContext, ReactNode, useMemo, useState } from "react";
interface Props {
children: ReactNode;
}
export const CanvasContext = createContext({
canvasSize: { minX: 0, minY: 0, maxX: 0, maxY: 0 },
blocks: [] as Block[],
setBlocks: ((blocks: Block[]) => {}) as React.Dispatch<React.SetStateAction<Block[]>>,
});
export const CanvasProvider = ({ children }: Props) => {
const [blocks, setBlocks] = useState<Block[]>([]);
const canvasSize = useMemo(() => {
let minX = Infinity,
maxX = -Infinity;
let minY = Infinity,
maxY = -Infinity;
blocks.forEach((coord) => {
if (coord.x < minX) minX = coord.x;
if (coord.x > maxX) maxX = coord.x;
if (coord.y < minY) minY = coord.y;
if (coord.y > maxY) maxY = coord.y;
});
return {
minX,
minY,
maxX: maxX + 1,
maxY: maxY + 1,
};
}, [blocks]);
return <CanvasContext.Provider value={{ canvasSize, blocks, setBlocks }}>{children}</CanvasContext.Provider>;
};

View file

@ -1,3 +1,4 @@
import { CanvasProvider } from "@/context/Canvas";
import { ImageProvider } from "../context/Image"; import { ImageProvider } from "../context/Image";
import { SettingsProvider } from "../context/Settings"; import { SettingsProvider } from "../context/Settings";
import { TexturesProvider } from "../context/Textures"; import { TexturesProvider } from "../context/Textures";
@ -9,19 +10,21 @@ import Canvas from "../components/canvas/Canvas";
function AppPage() { function AppPage() {
return ( return (
<ImageProvider> <CanvasProvider>
<SettingsProvider> <ImageProvider>
<TexturesProvider> <SettingsProvider>
<ToolProvider> <TexturesProvider>
<main className="h-screen grid grid-rows-[2.5rem_1fr] grid-cols-[2.5rem_1fr]"> <ToolProvider>
<Menubar /> <main className="h-screen grid grid-rows-[2.5rem_1fr] grid-cols-[2.5rem_1fr]">
<Toolbar /> <Menubar />
<Canvas /> <Toolbar />
</main> <Canvas />
</ToolProvider> </main>
</TexturesProvider> </ToolProvider>
</SettingsProvider> </TexturesProvider>
</ImageProvider> </SettingsProvider>
</ImageProvider>
</CanvasProvider>
); );
} }