add cursor pos to canvasmeta

This commit is contained in:
Grant 2024-02-15 19:33:06 -07:00
parent b0f9419653
commit 774d56fbee
7 changed files with 68 additions and 11 deletions

View File

@ -8,7 +8,7 @@ import {
import { useAppContext } from "../contexts/AppContext"; import { useAppContext } from "../contexts/AppContext";
export const CanvasMeta = () => { export const CanvasMeta = () => {
const { canvasPosition } = useAppContext(); const { canvasPosition, cursorPosition } = useAppContext();
const { isOpen, onOpen, onOpenChange } = useDisclosure(); const { isOpen, onOpen, onOpenChange } = useDisclosure();
return ( return (
@ -19,6 +19,14 @@ export const CanvasMeta = () => {
<button className="btn-link" onClick={onOpen}> <button className="btn-link" onClick={onOpen}>
({canvasPosition.x}, {canvasPosition.y}) ({canvasPosition.x}, {canvasPosition.y})
</button> </button>
{cursorPosition && (
<>
{" "}
<span className="canvas-meta--cursor-pos">
(Cursor: {cursorPosition.x}, {cursorPosition.y})
</span>
</>
)}
</span> </span>
)} )}
<span> <span>

View File

@ -5,7 +5,7 @@ import { PanZoomWrapper } from "@sc07-canvas/lib/src/renderer";
import { RendererContext } from "@sc07-canvas/lib/src/renderer/RendererContext"; import { RendererContext } from "@sc07-canvas/lib/src/renderer/RendererContext";
import { ViewportMoveEvent } from "@sc07-canvas/lib/src/renderer/PanZoom"; import { ViewportMoveEvent } from "@sc07-canvas/lib/src/renderer/PanZoom";
import throttle from "lodash.throttle"; import throttle from "lodash.throttle";
import { ICanvasPosition } from "../types"; import { ICanvasPosition, IPosition } from "../types";
import { Routes } from "../lib/routes"; import { Routes } from "../lib/routes";
export const CanvasWrapper = () => { export const CanvasWrapper = () => {
@ -21,7 +21,7 @@ export const CanvasWrapper = () => {
const CanvasInner = () => { const CanvasInner = () => {
const canvasRef = createRef<HTMLCanvasElement>(); const canvasRef = createRef<HTMLCanvasElement>();
const { config, setCanvasPosition } = useAppContext(); const { config, setCanvasPosition, setCursorPosition } = useAppContext();
const PanZoom = useContext(RendererContext); const PanZoom = useContext(RendererContext);
// const { centerView } = useControls(); // const { centerView } = useControls();
@ -45,11 +45,26 @@ const CanvasInner = () => {
window.location.replace(Routes.canvas(canvasPosition)); window.location.replace(Routes.canvas(canvasPosition));
}, 1000); }, 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); PanZoom.addListener("viewportMove", handleViewportMove);
canvasInstance.on("cursorPos", handleCursorPos);
return () => { return () => {
canvasInstance.destroy(); canvasInstance.destroy();
PanZoom.removeListener("viewportMove", handleViewportMove); PanZoom.removeListener("viewportMove", handleViewportMove);
canvasInstance.off("cursorPos", handleCursorPos);
}; };
}, [PanZoom, canvasRef, config, setCanvasPosition]); }, [PanZoom, canvasRef, config, setCanvasPosition]);

View File

@ -13,7 +13,7 @@ export const Pallete = () => {
useEffect(() => { useEffect(() => {
if (!Canvas.instance) return; if (!Canvas.instance) return;
Canvas.instance.emit("pallete", pallete); Canvas.instance.updatePallete(pallete);
}, [pallete]); }, [pallete]);
return ( return (

View File

@ -5,7 +5,12 @@ import {
useEffect, useEffect,
useState, useState,
} from "react"; } from "react";
import { ClientConfig, IAppContext, ICanvasPosition } from "../types"; import {
ClientConfig,
IAppContext,
ICanvasPosition,
IPosition,
} from "../types";
import { AuthSession } from "@sc07-canvas/lib/src/net"; import { AuthSession } from "@sc07-canvas/lib/src/net";
import Network from "../lib/network"; import Network from "../lib/network";
@ -17,6 +22,7 @@ export const AppContext = ({ children }: PropsWithChildren) => {
const [config, setConfig] = useState<ClientConfig>(undefined as any); const [config, setConfig] = useState<ClientConfig>(undefined as any);
const [auth, setAuth] = useState<AuthSession>(); const [auth, setAuth] = useState<AuthSession>();
const [canvasPosition, setCanvasPosition] = useState<ICanvasPosition>(); const [canvasPosition, setCanvasPosition] = useState<ICanvasPosition>();
const [cursorPosition, setCursorPosition] = useState<IPosition>();
useEffect(() => { useEffect(() => {
function handleConfig(config: ClientConfig) { function handleConfig(config: ClientConfig) {
@ -41,7 +47,14 @@ export const AppContext = ({ children }: PropsWithChildren) => {
return ( return (
<appContext.Provider <appContext.Provider
value={{ config, user: auth, canvasPosition, setCanvasPosition }} value={{
config,
user: auth,
canvasPosition,
setCanvasPosition,
cursorPosition,
setCursorPosition,
}}
> >
{config ? children : "Loading..."} {config ? children : "Loading..."}
</appContext.Provider> </appContext.Provider>

View File

@ -1,5 +1,5 @@
import EventEmitter from "eventemitter3"; import EventEmitter from "eventemitter3";
import { ClientConfig, IPalleteContext, Pixel } from "../types"; import { ClientConfig, IPalleteContext, IPosition, Pixel } from "../types";
import Network from "./network"; import Network from "./network";
import { import {
ClickEvent, ClickEvent,
@ -7,7 +7,17 @@ import {
PanZoom, PanZoom,
} from "@sc07-canvas/lib/src/renderer/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<CanvasEvents> {
static instance: Canvas | undefined; static instance: Canvas | undefined;
private _destroy = false; private _destroy = false;
@ -41,8 +51,6 @@ export class Canvas extends EventEmitter {
this.PanZoom.addListener("hover", this.handleMouseMove.bind(this)); this.PanZoom.addListener("hover", this.handleMouseMove.bind(this));
this.PanZoom.addListener("click", this.handleMouseDown.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)); Network.waitFor("canvas").then(([pixels]) => this.handleBatch(pixels));
this.draw(); this.draw();
@ -77,6 +85,8 @@ export class Canvas extends EventEmitter {
this.cursor.x = -1; this.cursor.x = -1;
this.cursor.y = -1; this.cursor.y = -1;
} }
this.emit("cursorPos", this.cursor);
} }
handleBatch(pixels: string[]) { 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] = { this.pixels[x + "_" + y] = {
color, color,
type: "full", type: "full",

View File

@ -94,6 +94,10 @@ header#main-header {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.canvas-meta--cursor-pos {
font-style: italic;
}
} }
main { main {

View File

@ -20,6 +20,8 @@ export interface IAppContext {
user?: AuthSession; user?: AuthSession;
canvasPosition?: ICanvasPosition; canvasPosition?: ICanvasPosition;
setCanvasPosition: (v: ICanvasPosition) => void; setCanvasPosition: (v: ICanvasPosition) => void;
cursorPosition?: IPosition;
setCursorPosition: (v?: IPosition) => void;
} }
export interface IPalleteContext { export interface IPalleteContext {
@ -32,6 +34,11 @@ export interface ICanvasPosition {
zoom: number; zoom: number;
} }
export interface IPosition {
x: number;
y: number;
}
// other // other
export type Pixel = { export type Pixel = {