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 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>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
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";
|
||||
|
||||
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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
8
src/types.d.ts
vendored
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue