fix: use pixi stage for selected block component

This commit is contained in:
trafficlunar 2024-12-24 20:12:40 +00:00
parent c9d1b8b44a
commit 933b287f9a

View file

@ -1,6 +1,6 @@
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect, useRef, useState } from "react";
import { Container, Sprite, Stage } from "@pixi/react";
import constants from "@/constants"; import * as PIXI from "pixi.js";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
@ -11,65 +11,31 @@ import _blockData from "@/data/blocks/programmer-art/data.json";
const blockData: BlockData = _blockData; const blockData: BlockData = _blockData;
function SelectedBlock() { function SelectedBlock() {
const { textures } = useContext(TexturesContext); const { missingTexture, textures } = useContext(TexturesContext);
const { selectedBlock } = useContext(ToolContext); const { selectedBlock } = useContext(ToolContext);
const divRef = useRef<HTMLDivElement>(null);
const [selectedBlockName, setSelectedBlockName] = useState("Stone"); const [selectedBlockName, setSelectedBlockName] = useState("Stone");
const [selectedBlockTexture, setSelectedBlockTexture] = useState(constants.MISSING_TEXTURE); const [selectedBlockTexture, setSelectedBlockTexture] = useState<PIXI.Texture>();
useEffect(() => { useEffect(() => {
const blockInfo = blockData[selectedBlock]; const blockInfo = blockData[selectedBlock];
setSelectedBlockName(blockInfo.name); setSelectedBlockName(blockInfo.name);
setSelectedBlockTexture(textures[`${selectedBlock}.png`] ?? missingTexture);
const texture = textures[`${selectedBlock}.png`]; }, [textures, selectedBlock, missingTexture]);
if (!texture) {
setSelectedBlockTexture(constants.MISSING_TEXTURE);
return;
}
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = 16;
canvas.height = 16;
if (!ctx) {
setSelectedBlockTexture(constants.MISSING_TEXTURE);
return;
}
const image = new Image();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
image.src = (texture.baseTexture.resource as any).url;
image.onload = () => {
ctx.drawImage(
image,
texture.frame.x,
texture.frame.y,
texture.frame.width,
texture.frame.height,
0,
0,
texture.frame.width,
texture.frame.height
);
setSelectedBlockTexture(canvas.toDataURL());
};
image.onerror = () => {
setSelectedBlockTexture(constants.MISSING_TEXTURE);
};
}, [textures, selectedBlock]);
return ( return (
<TooltipProvider> <TooltipProvider>
<Tooltip delayDuration={0}> <Tooltip delayDuration={0}>
<TooltipTrigger asChild> <TooltipTrigger asChild>
<img <div ref={divRef} className="absolute bottom-1 w-8 h-8 border border-zinc-800 dark:border-zinc-200">
src={selectedBlockTexture} <Stage width={divRef.current?.clientWidth} height={divRef.current?.clientHeight}>
className="absolute bottom-1 w-8 h-8 cursor-pointer border border-zinc-800 dark:border-zinc-200 rounded" <Container>
style={{ imageRendering: "pixelated" }} <Sprite texture={selectedBlockTexture} scale={2} />
/> </Container>
</Stage>
</div>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent side="right" sideOffset={10}> <TooltipContent side="right" sideOffset={10}>
<p>{selectedBlockName}</p> <p>{selectedBlockName}</p>