feat: add canvas information component

shows canvas size, scale, and a slider to change the scale
This commit is contained in:
trafficlunar 2024-12-13 17:09:33 +00:00
parent f0770860d9
commit c0df9e0816
5 changed files with 82 additions and 18 deletions

View file

@ -12,6 +12,7 @@
"dependencies": {
"@pixi/react": "7",
"@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-group": "^1.1.0",
"class-variance-authority": "^0.7.1",

View file

@ -7,7 +7,8 @@ import { TexturesContext } from "@/context/TexturesContext";
import Blocks from "./Blocks";
import Cursor from "./Cursor";
import CursorInformation from "./CursorInformation";
import CursorInformation from "./information/Cursor";
import CanvasInformation from "./information/Canvas";
// Set scale mode to NEAREST
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
@ -139,6 +140,7 @@ function Canvas() {
</Stage>
<CursorInformation mouseCoords={mouseCoords} blocks={blocks} />
<CanvasInformation scale={scale} setScale={setScale} blocks={blocks} />
</div>
);
}

View 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;

View file

@ -20,12 +20,9 @@ function CursorInformation({ mouseCoords, blocks }: Props) {
return (
<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">
{block?.name ?? "air"}
</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>
<div className="info-child">{block?.name ?? "air"}</div>
<div className="info-child">
<span>X: {position.x} </span>
<span>Y: {position.y}</span>
</div>
</div>

View file

@ -1,24 +1,28 @@
@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 components;
@tailwind utilities;
:root {
font-family: Geist, Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
font-family: Geist, Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@layer base {
:root {
--radius: 0.5rem;
}
:root {
--radius: 0.5rem;
}
}
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;
}