feat: add canvas border setting

This commit is contained in:
trafficlunar 2024-12-13 22:45:01 +00:00
parent 30beead56c
commit d7eee0d2ea
5 changed files with 59 additions and 25 deletions

View file

@ -11,6 +11,7 @@ import Grid from "./Grid";
import Cursor from "./Cursor";
import CursorInformation from "./information/Cursor";
import CanvasInformation from "./information/Canvas";
import CanvasBorder from "./CanvasBorder";
// Set scale mode to NEAREST
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
@ -36,6 +37,27 @@ function Canvas() {
return blocks.filter((b) => !(b.x === mouseCoords.x && b.y === mouseCoords.y));
}, [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 onToolUse = useCallback(() => {
switch (tool) {
case "pencil": {
@ -137,6 +159,7 @@ function Canvas() {
>
<Container x={coords.x} y={coords.y} scale={scale}>
<Blocks blocks={blocks} setBlocks={setBlocks} textures={textures} />
{settings.canvasBorder && <CanvasBorder canvasSize={canvasSize} />}
<Cursor mouseCoords={mouseCoords} />
</Container>
@ -148,7 +171,7 @@ function Canvas() {
</Stage>
<CursorInformation mouseCoords={mouseCoords} blocks={blocks} />
<CanvasInformation scale={scale} setScale={setScale} blocks={blocks} />
<CanvasInformation scale={scale} setScale={setScale} canvasSize={canvasSize} />
</div>
);
}

View file

@ -0,0 +1,19 @@
import { Graphics } from "@pixi/react";
interface Props {
canvasSize: CanvasSize;
}
function CanvasBorder({ canvasSize }: Props) {
return (
<Graphics
draw={(g) => {
g.clear();
g.lineStyle(2, 0xffffff, 0.25, 1);
g.drawRect(canvasSize.minX * 16, canvasSize.minY * 16, (canvasSize.maxX - canvasSize.minX) * 16, (canvasSize.maxY - canvasSize.minY) * 16);
}}
/>
);
}
export default CanvasBorder;

View file

@ -1,32 +1,13 @@
import React, { useMemo } from "react";
import React from "react";
import { Slider } from "@/components/ui/slider";
interface Props {
scale: number;
setScale: React.Dispatch<React.SetStateAction<number>>;
blocks: Block[];
canvasSize: CanvasSize;
}
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 {
width: maxX - minX,
height: maxY - minY,
};
}, [blocks]);
function CanvasInformation({ scale, setScale, canvasSize }: Props) {
const onValueChange = (value: number[]) => {
setScale(value[0]);
};
@ -36,8 +17,8 @@ function CanvasInformation({ scale, setScale, blocks }: Props) {
<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.width} </span>
<span>H: {canvasSize.height}</span>
<span>W: {canvasSize.maxX - canvasSize.minX} </span>
<span>H: {canvasSize.maxY - canvasSize.minY}</span>
</div>
</div>

View file

@ -16,6 +16,9 @@ function ViewMenu() {
<MenubarCheckboxItem checked={settings.grid} onCheckedChange={onCheckedChange("grid")}>
Grid
</MenubarCheckboxItem>
<MenubarCheckboxItem checked={settings.canvasBorder} onCheckedChange={onCheckedChange("canvasBorder")}>
Canvas Border
</MenubarCheckboxItem>
</MenubarContent>
</MenubarMenu>
);

8
src/types.d.ts vendored
View file

@ -10,6 +10,13 @@ interface Dimension {
height: number;
}
interface CanvasSize {
minX: number;
minY: number;
maxX: number;
maxY: number;
}
interface Block extends Position {
name: string;
}
@ -18,4 +25,5 @@ type Tool = "hand" | "pencil" | "eraser";
interface Settings {
grid: boolean;
canvasBorder: boolean;
}