feat: add canvas border setting
This commit is contained in:
parent
30beead56c
commit
d7eee0d2ea
5 changed files with 59 additions and 25 deletions
|
|
@ -11,6 +11,7 @@ import Grid from "./Grid";
|
||||||
import Cursor from "./Cursor";
|
import Cursor from "./Cursor";
|
||||||
import CursorInformation from "./information/Cursor";
|
import CursorInformation from "./information/Cursor";
|
||||||
import CanvasInformation from "./information/Canvas";
|
import CanvasInformation from "./information/Canvas";
|
||||||
|
import CanvasBorder from "./CanvasBorder";
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
@ -36,6 +37,27 @@ 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 onToolUse = useCallback(() => {
|
const onToolUse = useCallback(() => {
|
||||||
switch (tool) {
|
switch (tool) {
|
||||||
case "pencil": {
|
case "pencil": {
|
||||||
|
|
@ -137,6 +159,7 @@ function Canvas() {
|
||||||
>
|
>
|
||||||
<Container x={coords.x} y={coords.y} scale={scale}>
|
<Container x={coords.x} y={coords.y} scale={scale}>
|
||||||
<Blocks blocks={blocks} setBlocks={setBlocks} textures={textures} />
|
<Blocks blocks={blocks} setBlocks={setBlocks} textures={textures} />
|
||||||
|
{settings.canvasBorder && <CanvasBorder canvasSize={canvasSize} />}
|
||||||
<Cursor mouseCoords={mouseCoords} />
|
<Cursor mouseCoords={mouseCoords} />
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
|
|
@ -148,7 +171,7 @@ function Canvas() {
|
||||||
</Stage>
|
</Stage>
|
||||||
|
|
||||||
<CursorInformation mouseCoords={mouseCoords} blocks={blocks} />
|
<CursorInformation mouseCoords={mouseCoords} blocks={blocks} />
|
||||||
<CanvasInformation scale={scale} setScale={setScale} blocks={blocks} />
|
<CanvasInformation scale={scale} setScale={setScale} canvasSize={canvasSize} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
src/components/CanvasBorder.tsx
Normal file
19
src/components/CanvasBorder.tsx
Normal 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;
|
||||||
|
|
@ -1,32 +1,13 @@
|
||||||
import React, { useMemo } from "react";
|
import React from "react";
|
||||||
import { Slider } from "@/components/ui/slider";
|
import { Slider } from "@/components/ui/slider";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
scale: number;
|
scale: number;
|
||||||
setScale: React.Dispatch<React.SetStateAction<number>>;
|
setScale: React.Dispatch<React.SetStateAction<number>>;
|
||||||
blocks: Block[];
|
canvasSize: CanvasSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
function CanvasInformation({ scale, setScale, blocks }: Props) {
|
function CanvasInformation({ scale, setScale, canvasSize }: 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]);
|
|
||||||
|
|
||||||
const onValueChange = (value: number[]) => {
|
const onValueChange = (value: number[]) => {
|
||||||
setScale(value[0]);
|
setScale(value[0]);
|
||||||
};
|
};
|
||||||
|
|
@ -36,8 +17,8 @@ function CanvasInformation({ scale, setScale, blocks }: Props) {
|
||||||
<div className="flex flex-col 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">{Math.floor(scale * 100)}%</div>
|
||||||
<div className="info-child">
|
<div className="info-child">
|
||||||
<span>W: {canvasSize.width} </span>
|
<span>W: {canvasSize.maxX - canvasSize.minX} </span>
|
||||||
<span>H: {canvasSize.height}</span>
|
<span>H: {canvasSize.maxY - canvasSize.minY}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@ function ViewMenu() {
|
||||||
<MenubarCheckboxItem checked={settings.grid} onCheckedChange={onCheckedChange("grid")}>
|
<MenubarCheckboxItem checked={settings.grid} onCheckedChange={onCheckedChange("grid")}>
|
||||||
Grid
|
Grid
|
||||||
</MenubarCheckboxItem>
|
</MenubarCheckboxItem>
|
||||||
|
<MenubarCheckboxItem checked={settings.canvasBorder} onCheckedChange={onCheckedChange("canvasBorder")}>
|
||||||
|
Canvas Border
|
||||||
|
</MenubarCheckboxItem>
|
||||||
</MenubarContent>
|
</MenubarContent>
|
||||||
</MenubarMenu>
|
</MenubarMenu>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
8
src/types.d.ts
vendored
8
src/types.d.ts
vendored
|
|
@ -10,6 +10,13 @@ interface Dimension {
|
||||||
height: number;
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CanvasSize {
|
||||||
|
minX: number;
|
||||||
|
minY: number;
|
||||||
|
maxX: number;
|
||||||
|
maxY: number;
|
||||||
|
}
|
||||||
|
|
||||||
interface Block extends Position {
|
interface Block extends Position {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
@ -18,4 +25,5 @@ type Tool = "hand" | "pencil" | "eraser";
|
||||||
|
|
||||||
interface Settings {
|
interface Settings {
|
||||||
grid: boolean;
|
grid: boolean;
|
||||||
|
canvasBorder: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue