diff --git a/packages/client-next/src/components/CanvasMeta.tsx b/packages/client-next/src/components/CanvasMeta.tsx index 8be4e9f..126cd63 100644 --- a/packages/client-next/src/components/CanvasMeta.tsx +++ b/packages/client-next/src/components/CanvasMeta.tsx @@ -8,7 +8,7 @@ import { import { useAppContext } from "../contexts/AppContext"; export const CanvasMeta = () => { - const { canvasPosition } = useAppContext(); + const { canvasPosition, cursorPosition } = useAppContext(); const { isOpen, onOpen, onOpenChange } = useDisclosure(); return ( @@ -19,6 +19,14 @@ export const CanvasMeta = () => { + {cursorPosition && ( + <> + {" "} + + (Cursor: {cursorPosition.x}, {cursorPosition.y}) + + + )} )} diff --git a/packages/client-next/src/components/CanvasWrapper.tsx b/packages/client-next/src/components/CanvasWrapper.tsx index 2f6d276..2db2dda 100644 --- a/packages/client-next/src/components/CanvasWrapper.tsx +++ b/packages/client-next/src/components/CanvasWrapper.tsx @@ -5,7 +5,7 @@ import { PanZoomWrapper } from "@sc07-canvas/lib/src/renderer"; import { RendererContext } from "@sc07-canvas/lib/src/renderer/RendererContext"; import { ViewportMoveEvent } from "@sc07-canvas/lib/src/renderer/PanZoom"; import throttle from "lodash.throttle"; -import { ICanvasPosition } from "../types"; +import { ICanvasPosition, IPosition } from "../types"; import { Routes } from "../lib/routes"; export const CanvasWrapper = () => { @@ -21,7 +21,7 @@ export const CanvasWrapper = () => { const CanvasInner = () => { const canvasRef = createRef(); - const { config, setCanvasPosition } = useAppContext(); + const { config, setCanvasPosition, setCursorPosition } = useAppContext(); const PanZoom = useContext(RendererContext); // const { centerView } = useControls(); @@ -45,11 +45,26 @@ const CanvasInner = () => { window.location.replace(Routes.canvas(canvasPosition)); }, 1000); + const handleCursorPos = (pos: IPosition) => { + if ( + pos.x < 0 || + pos.y < 0 || + pos.x > config.canvas.size[0] || + pos.y > config.canvas.size[1] + ) { + setCursorPosition(); + } else { + setCursorPosition(pos); + } + }; + PanZoom.addListener("viewportMove", handleViewportMove); + canvasInstance.on("cursorPos", handleCursorPos); return () => { canvasInstance.destroy(); PanZoom.removeListener("viewportMove", handleViewportMove); + canvasInstance.off("cursorPos", handleCursorPos); }; }, [PanZoom, canvasRef, config, setCanvasPosition]); diff --git a/packages/client-next/src/components/Pallete.tsx b/packages/client-next/src/components/Pallete.tsx index d068ae5..518c74b 100644 --- a/packages/client-next/src/components/Pallete.tsx +++ b/packages/client-next/src/components/Pallete.tsx @@ -13,7 +13,7 @@ export const Pallete = () => { useEffect(() => { if (!Canvas.instance) return; - Canvas.instance.emit("pallete", pallete); + Canvas.instance.updatePallete(pallete); }, [pallete]); return ( diff --git a/packages/client-next/src/contexts/AppContext.tsx b/packages/client-next/src/contexts/AppContext.tsx index 05bfc4c..a3d4300 100644 --- a/packages/client-next/src/contexts/AppContext.tsx +++ b/packages/client-next/src/contexts/AppContext.tsx @@ -5,7 +5,12 @@ import { useEffect, useState, } from "react"; -import { ClientConfig, IAppContext, ICanvasPosition } from "../types"; +import { + ClientConfig, + IAppContext, + ICanvasPosition, + IPosition, +} from "../types"; import { AuthSession } from "@sc07-canvas/lib/src/net"; import Network from "../lib/network"; @@ -17,6 +22,7 @@ export const AppContext = ({ children }: PropsWithChildren) => { const [config, setConfig] = useState(undefined as any); const [auth, setAuth] = useState(); const [canvasPosition, setCanvasPosition] = useState(); + const [cursorPosition, setCursorPosition] = useState(); useEffect(() => { function handleConfig(config: ClientConfig) { @@ -41,7 +47,14 @@ export const AppContext = ({ children }: PropsWithChildren) => { return ( {config ? children : "Loading..."} diff --git a/packages/client-next/src/lib/canvas.ts b/packages/client-next/src/lib/canvas.ts index 6acc916..d8a4add 100644 --- a/packages/client-next/src/lib/canvas.ts +++ b/packages/client-next/src/lib/canvas.ts @@ -1,5 +1,5 @@ import EventEmitter from "eventemitter3"; -import { ClientConfig, IPalleteContext, Pixel } from "../types"; +import { ClientConfig, IPalleteContext, IPosition, Pixel } from "../types"; import Network from "./network"; import { ClickEvent, @@ -7,7 +7,17 @@ import { PanZoom, } from "@sc07-canvas/lib/src/renderer/PanZoom"; -export class Canvas extends EventEmitter { +interface CanvasEvents { + /** + * Cursor canvas position + * (-1, -1) is not on canvas + * @param position Canvas position + * @returns + */ + cursorPos: (position: IPosition) => void; +} + +export class Canvas extends EventEmitter { static instance: Canvas | undefined; private _destroy = false; @@ -41,8 +51,6 @@ export class Canvas extends EventEmitter { this.PanZoom.addListener("hover", this.handleMouseMove.bind(this)); this.PanZoom.addListener("click", this.handleMouseDown.bind(this)); - this.on("pallete", this.updatePallete.bind(this)); - Network.waitFor("canvas").then(([pixels]) => this.handleBatch(pixels)); this.draw(); @@ -77,6 +85,8 @@ export class Canvas extends EventEmitter { this.cursor.x = -1; this.cursor.y = -1; } + + this.emit("cursorPos", this.cursor); } handleBatch(pixels: string[]) { @@ -92,7 +102,7 @@ export class Canvas extends EventEmitter { }); } - handlePixel({ x, y, color, ...pixel }: Pixel) { + handlePixel({ x, y, color }: Pixel) { this.pixels[x + "_" + y] = { color, type: "full", diff --git a/packages/client-next/src/style.scss b/packages/client-next/src/style.scss index faba6f0..ff5cba8 100644 --- a/packages/client-next/src/style.scss +++ b/packages/client-next/src/style.scss @@ -94,6 +94,10 @@ header#main-header { display: flex; flex-direction: column; + + .canvas-meta--cursor-pos { + font-style: italic; + } } main { diff --git a/packages/client-next/src/types.ts b/packages/client-next/src/types.ts index dc27411..1bcdde4 100644 --- a/packages/client-next/src/types.ts +++ b/packages/client-next/src/types.ts @@ -20,6 +20,8 @@ export interface IAppContext { user?: AuthSession; canvasPosition?: ICanvasPosition; setCanvasPosition: (v: ICanvasPosition) => void; + cursorPosition?: IPosition; + setCursorPosition: (v?: IPosition) => void; } export interface IPalleteContext { @@ -32,6 +34,11 @@ export interface ICanvasPosition { zoom: number; } +export interface IPosition { + x: number; + y: number; +} + // other export type Pixel = {