feat: add canvas information component
shows canvas size, scale, and a slider to change the scale
This commit is contained in:
parent
f0770860d9
commit
c0df9e0816
5 changed files with 82 additions and 18 deletions
|
|
@ -12,6 +12,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pixi/react": "7",
|
"@pixi/react": "7",
|
||||||
"@radix-ui/react-menubar": "^1.1.2",
|
"@radix-ui/react-menubar": "^1.1.2",
|
||||||
|
"@radix-ui/react-slider": "^1.2.2",
|
||||||
"@radix-ui/react-toggle": "^1.1.0",
|
"@radix-ui/react-toggle": "^1.1.0",
|
||||||
"@radix-ui/react-toggle-group": "^1.1.0",
|
"@radix-ui/react-toggle-group": "^1.1.0",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ import { TexturesContext } from "@/context/TexturesContext";
|
||||||
|
|
||||||
import Blocks from "./Blocks";
|
import Blocks from "./Blocks";
|
||||||
import Cursor from "./Cursor";
|
import Cursor from "./Cursor";
|
||||||
import CursorInformation from "./CursorInformation";
|
import CursorInformation from "./information/Cursor";
|
||||||
|
import CanvasInformation from "./information/Canvas";
|
||||||
|
|
||||||
// Set scale mode to NEAREST
|
// Set scale mode to NEAREST
|
||||||
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
|
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
|
||||||
|
|
@ -139,6 +140,7 @@ function Canvas() {
|
||||||
</Stage>
|
</Stage>
|
||||||
|
|
||||||
<CursorInformation mouseCoords={mouseCoords} blocks={blocks} />
|
<CursorInformation mouseCoords={mouseCoords} blocks={blocks} />
|
||||||
|
<CanvasInformation scale={scale} setScale={setScale} blocks={blocks} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
60
src/components/information/Canvas.tsx
Normal file
60
src/components/information/Canvas.tsx
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
|
import { Slider } from "@/components/ui/slider";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
scale: number;
|
||||||
|
setScale: React.Dispatch<React.SetStateAction<number>>;
|
||||||
|
blocks: Block[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function CanvasInformation({ scale, setScale, blocks }: Props) {
|
||||||
|
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 {
|
||||||
|
x: maxX - minX,
|
||||||
|
y: maxY - minY,
|
||||||
|
};
|
||||||
|
}, [blocks]);
|
||||||
|
|
||||||
|
const onValueChange = (value: number[]) => {
|
||||||
|
setScale(value[0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="absolute right-4 bottom-4 flex items-end gap-1">
|
||||||
|
<div className="flex flex-col items-end gap-1">
|
||||||
|
<div className="info-child">{Math.floor(scale * 100)}%</div>
|
||||||
|
<div className="info-child">
|
||||||
|
<span>W: {canvasSize.x} </span>
|
||||||
|
<span>H: {canvasSize.y}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="info-child">
|
||||||
|
<Slider
|
||||||
|
defaultValue={[1]}
|
||||||
|
min={0.25}
|
||||||
|
max={32}
|
||||||
|
step={0.1}
|
||||||
|
value={[scale]}
|
||||||
|
onValueChange={onValueChange}
|
||||||
|
orientation="vertical"
|
||||||
|
className="!h-32"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CanvasInformation;
|
||||||
|
|
@ -20,11 +20,8 @@ function CursorInformation({ mouseCoords, blocks }: Props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="absolute left-4 bottom-4 flex flex-col gap-1">
|
<div className="absolute left-4 bottom-4 flex flex-col gap-1">
|
||||||
<div className="bg-white dark:bg-zinc-950 px-2 py-1 rounded shadow-xl w-fit border border-zinc-200 dark:border-zinc-800">
|
<div className="info-child">{block?.name ?? "air"}</div>
|
||||||
{block?.name ?? "air"}
|
<div className="info-child">
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex gap-4 bg-white dark:bg-zinc-950 px-2 py-1 rounded shadow-xl w-fit border border-zinc-200 dark:border-zinc-800">
|
|
||||||
<span>X: {position.x} </span>
|
<span>X: {position.x} </span>
|
||||||
<span>Y: {position.y}</span>
|
<span>Y: {position.y}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Geist:wght@100..900&display=swap');
|
@import url("https://fonts.googleapis.com/css2?family=Geist:wght@100..900&display=swap");
|
||||||
|
|
||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
|
|
@ -22,3 +22,7 @@
|
||||||
body {
|
body {
|
||||||
@apply bg-zinc-50 dark:bg-zinc-950 dark:text-zinc-50;
|
@apply bg-zinc-50 dark:bg-zinc-950 dark:text-zinc-50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.info-child {
|
||||||
|
@apply bg-white dark:bg-zinc-950 px-2 py-1 rounded shadow-xl w-fit border border-zinc-200 dark:border-zinc-800;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue