Typescript
This commit is contained in:
parent
569ed696fc
commit
68c1c6db0c
@ -255,9 +255,9 @@ function Map({
|
|||||||
const mapDrawing = (
|
const mapDrawing = (
|
||||||
<MapDrawing
|
<MapDrawing
|
||||||
map={map}
|
map={map}
|
||||||
shapes={drawShapes}
|
drawings={drawShapes}
|
||||||
onShapeAdd={handleMapShapeAdd}
|
onDrawingAdd={handleMapShapeAdd}
|
||||||
onShapesRemove={handleMapShapesRemove}
|
onDrawingsRemove={handleMapShapesRemove}
|
||||||
active={selectedToolId === "drawing"}
|
active={selectedToolId === "drawing"}
|
||||||
toolSettings={settings.drawing}
|
toolSettings={settings.drawing}
|
||||||
/>
|
/>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import shortid from "shortid";
|
import shortid from "shortid";
|
||||||
import { Group, Line, Rect, Circle } from "react-konva";
|
import { Group, Line, Rect, Circle } from "react-konva";
|
||||||
|
|
||||||
@ -25,14 +25,34 @@ import { getRelativePointerPosition } from "../../helpers/konva";
|
|||||||
|
|
||||||
import useGridSnapping from "../../hooks/useGridSnapping";
|
import useGridSnapping from "../../hooks/useGridSnapping";
|
||||||
|
|
||||||
|
import { Map } from "../../types/Map";
|
||||||
|
import {
|
||||||
|
Drawing,
|
||||||
|
DrawingToolSettings,
|
||||||
|
drawingToolIsShape,
|
||||||
|
Shape,
|
||||||
|
} from "../../types/Drawing";
|
||||||
|
|
||||||
|
export type DrawingAddEventHanlder = (drawing: Drawing) => void;
|
||||||
|
export type DrawingsRemoveEventHandler = (drawingIds: string[]) => void;
|
||||||
|
|
||||||
|
type MapDrawingProps = {
|
||||||
|
map: Map;
|
||||||
|
drawings: Drawing[];
|
||||||
|
onDrawingAdd: DrawingAddEventHanlder;
|
||||||
|
onDrawingsRemove: DrawingsRemoveEventHandler;
|
||||||
|
active: boolean;
|
||||||
|
toolSettings: DrawingToolSettings;
|
||||||
|
};
|
||||||
|
|
||||||
function MapDrawing({
|
function MapDrawing({
|
||||||
map,
|
map,
|
||||||
shapes,
|
drawings,
|
||||||
onShapeAdd,
|
onDrawingAdd: onShapeAdd,
|
||||||
onShapesRemove,
|
onDrawingsRemove: onShapesRemove,
|
||||||
active,
|
active,
|
||||||
toolSettings,
|
toolSettings,
|
||||||
}) {
|
}: MapDrawingProps) {
|
||||||
const stageScale = useDebouncedStageScale();
|
const stageScale = useDebouncedStageScale();
|
||||||
const mapWidth = useMapWidth();
|
const mapWidth = useMapWidth();
|
||||||
const mapHeight = useMapHeight();
|
const mapHeight = useMapHeight();
|
||||||
@ -42,11 +62,12 @@ function MapDrawing({
|
|||||||
const gridStrokeWidth = useGridStrokeWidth();
|
const gridStrokeWidth = useGridStrokeWidth();
|
||||||
|
|
||||||
const mapStageRef = useMapStage();
|
const mapStageRef = useMapStage();
|
||||||
const [drawingShape, setDrawingShape] = useState(null);
|
const [drawing, setDrawing] = useState<Drawing | null>(null);
|
||||||
const [isBrushDown, setIsBrushDown] = useState(false);
|
const [isBrushDown, setIsBrushDown] = useState(false);
|
||||||
const [erasingShapes, setErasingShapes] = useState([]);
|
const [erasingDrawings, setErasingDrawings] = useState<Drawing[]>([]);
|
||||||
|
|
||||||
const shouldHover = toolSettings.type === "erase" && active;
|
const shouldHover = toolSettings.type === "erase" && active;
|
||||||
|
|
||||||
const isBrush =
|
const isBrush =
|
||||||
toolSettings.type === "brush" || toolSettings.type === "paint";
|
toolSettings.type === "brush" || toolSettings.type === "paint";
|
||||||
const isShape =
|
const isShape =
|
||||||
@ -64,8 +85,14 @@ function MapDrawing({
|
|||||||
const mapStage = mapStageRef.current;
|
const mapStage = mapStageRef.current;
|
||||||
|
|
||||||
function getBrushPosition() {
|
function getBrushPosition() {
|
||||||
|
if (!mapStage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const mapImage = mapStage.findOne("#mapImage");
|
const mapImage = mapStage.findOne("#mapImage");
|
||||||
let position = getRelativePointerPosition(mapImage);
|
let position = getRelativePointerPosition(mapImage);
|
||||||
|
if (!position) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (map.snapToGrid && isShape) {
|
if (map.snapToGrid && isShape) {
|
||||||
position = snapPositionToGrid(position);
|
position = snapPositionToGrid(position);
|
||||||
}
|
}
|
||||||
@ -77,36 +104,46 @@ function MapDrawing({
|
|||||||
|
|
||||||
function handleBrushDown() {
|
function handleBrushDown() {
|
||||||
const brushPosition = getBrushPosition();
|
const brushPosition = getBrushPosition();
|
||||||
|
if (!brushPosition) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const commonShapeData = {
|
const commonShapeData = {
|
||||||
color: toolSettings.color,
|
color: toolSettings.color,
|
||||||
blend: toolSettings.useBlending,
|
blend: toolSettings.useBlending,
|
||||||
id: shortid.generate(),
|
id: shortid.generate(),
|
||||||
};
|
};
|
||||||
|
const type = toolSettings.type;
|
||||||
if (isBrush) {
|
if (isBrush) {
|
||||||
setDrawingShape({
|
setDrawing({
|
||||||
type: "path",
|
type: "path",
|
||||||
pathType: toolSettings.type === "brush" ? "stroke" : "fill",
|
pathType: type === "brush" ? "stroke" : "fill",
|
||||||
data: { points: [brushPosition] },
|
data: { points: [brushPosition] },
|
||||||
strokeWidth: toolSettings.type === "brush" ? 1 : 0,
|
strokeWidth: type === "brush" ? 1 : 0,
|
||||||
...commonShapeData,
|
...commonShapeData,
|
||||||
});
|
});
|
||||||
} else if (isShape) {
|
} else if (isShape && drawingToolIsShape(type)) {
|
||||||
setDrawingShape({
|
setDrawing({
|
||||||
type: "shape",
|
type: "shape",
|
||||||
shapeType: toolSettings.type,
|
shapeType: type,
|
||||||
data: getDefaultShapeData(toolSettings.type, brushPosition),
|
data: getDefaultShapeData(type, brushPosition),
|
||||||
strokeWidth: toolSettings.type === "line" ? 1 : 0,
|
strokeWidth: toolSettings.type === "line" ? 1 : 0,
|
||||||
...commonShapeData,
|
...commonShapeData,
|
||||||
});
|
} as Shape);
|
||||||
}
|
}
|
||||||
setIsBrushDown(true);
|
setIsBrushDown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleBrushMove() {
|
function handleBrushMove() {
|
||||||
const brushPosition = getBrushPosition();
|
const brushPosition = getBrushPosition();
|
||||||
if (isBrushDown && drawingShape) {
|
if (!brushPosition) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isBrushDown && drawing) {
|
||||||
if (isBrush) {
|
if (isBrush) {
|
||||||
setDrawingShape((prevShape) => {
|
setDrawing((prevShape) => {
|
||||||
|
if (prevShape?.type !== "path") {
|
||||||
|
return prevShape;
|
||||||
|
}
|
||||||
const prevPoints = prevShape.data.points;
|
const prevPoints = prevShape.data.points;
|
||||||
if (
|
if (
|
||||||
Vector2.compare(
|
Vector2.compare(
|
||||||
@ -127,63 +164,68 @@ function MapDrawing({
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
} else if (isShape) {
|
} else if (isShape) {
|
||||||
setDrawingShape((prevShape) => ({
|
setDrawing((prevShape) => {
|
||||||
...prevShape,
|
if (prevShape?.type !== "shape") {
|
||||||
data: getUpdatedShapeData(
|
return prevShape;
|
||||||
prevShape.shapeType,
|
}
|
||||||
prevShape.data,
|
return {
|
||||||
brushPosition,
|
...prevShape,
|
||||||
gridCellNormalizedSize,
|
data: getUpdatedShapeData(
|
||||||
mapWidth,
|
prevShape.shapeType,
|
||||||
mapHeight
|
prevShape.data,
|
||||||
),
|
brushPosition,
|
||||||
}));
|
gridCellNormalizedSize,
|
||||||
|
mapWidth,
|
||||||
|
mapHeight
|
||||||
|
),
|
||||||
|
} as Shape;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleBrushUp() {
|
function handleBrushUp() {
|
||||||
if (isBrush && drawingShape) {
|
if (isBrush && drawing && drawing.type === "path") {
|
||||||
if (drawingShape.data.points.length > 1) {
|
if (drawing.data.points.length > 1) {
|
||||||
onShapeAdd(drawingShape);
|
onShapeAdd(drawing);
|
||||||
}
|
}
|
||||||
} else if (isShape && drawingShape) {
|
} else if (isShape && drawing) {
|
||||||
onShapeAdd(drawingShape);
|
onShapeAdd(drawing);
|
||||||
}
|
}
|
||||||
|
|
||||||
eraseHoveredShapes();
|
eraseHoveredShapes();
|
||||||
|
|
||||||
setDrawingShape(null);
|
setDrawing(null);
|
||||||
setIsBrushDown(false);
|
setIsBrushDown(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
interactionEmitter.on("dragStart", handleBrushDown);
|
interactionEmitter?.on("dragStart", handleBrushDown);
|
||||||
interactionEmitter.on("drag", handleBrushMove);
|
interactionEmitter?.on("drag", handleBrushMove);
|
||||||
interactionEmitter.on("dragEnd", handleBrushUp);
|
interactionEmitter?.on("dragEnd", handleBrushUp);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
interactionEmitter.off("dragStart", handleBrushDown);
|
interactionEmitter?.off("dragStart", handleBrushDown);
|
||||||
interactionEmitter.off("drag", handleBrushMove);
|
interactionEmitter?.off("drag", handleBrushMove);
|
||||||
interactionEmitter.off("dragEnd", handleBrushUp);
|
interactionEmitter?.off("dragEnd", handleBrushUp);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleShapeOver(shape, isDown) {
|
function handleShapeOver(shape: Drawing, isDown: boolean) {
|
||||||
if (shouldHover && isDown) {
|
if (shouldHover && isDown) {
|
||||||
if (erasingShapes.findIndex((s) => s.id === shape.id) === -1) {
|
if (erasingDrawings.findIndex((s) => s.id === shape.id) === -1) {
|
||||||
setErasingShapes((prevShapes) => [...prevShapes, shape]);
|
setErasingDrawings((prevShapes) => [...prevShapes, shape]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function eraseHoveredShapes() {
|
function eraseHoveredShapes() {
|
||||||
if (erasingShapes.length > 0) {
|
if (erasingDrawings.length > 0) {
|
||||||
onShapesRemove(erasingShapes.map((shape) => shape.id));
|
onShapesRemove(erasingDrawings.map((shape) => shape.id));
|
||||||
setErasingShapes([]);
|
setErasingDrawings([]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderShape(shape) {
|
function renderDrawing(shape: Drawing) {
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
key: shape.id,
|
key: shape.id,
|
||||||
onMouseMove: () => handleShapeOver(shape, isBrushDown),
|
onMouseMove: () => handleShapeOver(shape, isBrushDown),
|
||||||
@ -200,7 +242,11 @@ function MapDrawing({
|
|||||||
return (
|
return (
|
||||||
<Line
|
<Line
|
||||||
points={shape.data.points.reduce(
|
points={shape.data.points.reduce(
|
||||||
(acc, point) => [...acc, point.x * mapWidth, point.y * mapHeight],
|
(acc: number[], point) => [
|
||||||
|
...acc,
|
||||||
|
point.x * mapWidth,
|
||||||
|
point.y * mapHeight,
|
||||||
|
],
|
||||||
[]
|
[]
|
||||||
)}
|
)}
|
||||||
stroke={colors[shape.color] || shape.color}
|
stroke={colors[shape.color] || shape.color}
|
||||||
@ -238,7 +284,11 @@ function MapDrawing({
|
|||||||
return (
|
return (
|
||||||
<Line
|
<Line
|
||||||
points={shape.data.points.reduce(
|
points={shape.data.points.reduce(
|
||||||
(acc, point) => [...acc, point.x * mapWidth, point.y * mapHeight],
|
(acc: number[], point) => [
|
||||||
|
...acc,
|
||||||
|
point.x * mapWidth,
|
||||||
|
point.y * mapHeight,
|
||||||
|
],
|
||||||
[]
|
[]
|
||||||
)}
|
)}
|
||||||
closed={true}
|
closed={true}
|
||||||
@ -249,7 +299,11 @@ function MapDrawing({
|
|||||||
return (
|
return (
|
||||||
<Line
|
<Line
|
||||||
points={shape.data.points.reduce(
|
points={shape.data.points.reduce(
|
||||||
(acc, point) => [...acc, point.x * mapWidth, point.y * mapHeight],
|
(acc: number[], point) => [
|
||||||
|
...acc,
|
||||||
|
point.x * mapWidth,
|
||||||
|
point.y * mapHeight,
|
||||||
|
],
|
||||||
[]
|
[]
|
||||||
)}
|
)}
|
||||||
strokeWidth={gridStrokeWidth * shape.strokeWidth}
|
strokeWidth={gridStrokeWidth * shape.strokeWidth}
|
||||||
@ -262,19 +316,19 @@ function MapDrawing({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderErasingShape(shape) {
|
function renderErasingDrawing(drawing: Drawing) {
|
||||||
const eraseShape = {
|
const eraseShape: Drawing = {
|
||||||
...shape,
|
...drawing,
|
||||||
color: "#BB99FF",
|
color: "primary",
|
||||||
};
|
};
|
||||||
return renderShape(eraseShape);
|
return renderDrawing(eraseShape);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group>
|
<Group>
|
||||||
{shapes.map(renderShape)}
|
{drawings.map(renderDrawing)}
|
||||||
{drawingShape && renderShape(drawingShape)}
|
{drawing && renderDrawing(drawing)}
|
||||||
{erasingShapes.length > 0 && erasingShapes.map(renderErasingShape)}
|
{erasingDrawings.length > 0 && erasingDrawings.map(renderErasingDrawing)}
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* @typedef {object} Timer
|
|
||||||
* @property {number} current
|
|
||||||
* @property {number} max
|
|
||||||
*/
|
|
||||||
export type Timer = {
|
|
||||||
current: number,
|
|
||||||
max: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {object} PlayerDice
|
|
||||||
* @property {boolean} share
|
|
||||||
* @property {[]} rolls
|
|
||||||
*/
|
|
||||||
export type PlayerDice = { share: boolean, rolls: [] }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {object} PlayerInfo
|
|
||||||
* @property {string} nickname
|
|
||||||
* @property {Timer | null} timer
|
|
||||||
* @property {PlayerDice} dice
|
|
||||||
* @property {string} sessionId
|
|
||||||
* @property {string} userId
|
|
||||||
*/
|
|
||||||
export type PlayerInfo = {
|
|
||||||
nickname: string,
|
|
||||||
timer: Timer | null,
|
|
||||||
dice: PlayerDice,
|
|
||||||
sessionId: string,
|
|
||||||
userId: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {object} PartyState
|
|
||||||
* @property {string} player
|
|
||||||
* @property {PlayerInfo} playerInfo
|
|
||||||
*/
|
|
||||||
export type PartyState = { [player: string]: PlayerInfo }
|
|
@ -1,16 +1,45 @@
|
|||||||
import React, { ReactChild, useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
|
import { EventEmitter } from "stream";
|
||||||
import useDebounce from "../hooks/useDebounce";
|
import useDebounce from "../hooks/useDebounce";
|
||||||
|
|
||||||
export const StageScaleContext = React.createContext(undefined) as any;
|
type MapInteraction = {
|
||||||
export const DebouncedStageScaleContext = React.createContext(undefined) as any;
|
stageScale: number;
|
||||||
export const StageWidthContext = React.createContext(undefined) as any;
|
stageWidth: number;
|
||||||
export const StageHeightContext = React.createContext(undefined) as any;
|
stageHeight: number;
|
||||||
export const SetPreventMapInteractionContext = React.createContext(undefined) as any;
|
setPreventMapInteraction: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
export const MapWidthContext = React.createContext(undefined) as any;
|
mapWidth: number;
|
||||||
export const MapHeightContext = React.createContext(undefined) as any;
|
mapHeight: number;
|
||||||
export const InteractionEmitterContext = React.createContext(undefined) as any;
|
interactionEmitter: EventEmitter | null;
|
||||||
|
};
|
||||||
|
|
||||||
export function MapInteractionProvider({ value, children }: { value: any, children: ReactChild[]}) {
|
export const StageScaleContext =
|
||||||
|
React.createContext<MapInteraction["stageScale"] | undefined>(undefined);
|
||||||
|
export const DebouncedStageScaleContext =
|
||||||
|
React.createContext<MapInteraction["stageScale"] | undefined>(undefined);
|
||||||
|
export const StageWidthContext =
|
||||||
|
React.createContext<MapInteraction["stageWidth"] | undefined>(undefined);
|
||||||
|
export const StageHeightContext =
|
||||||
|
React.createContext<MapInteraction["stageHeight"] | undefined>(undefined);
|
||||||
|
export const SetPreventMapInteractionContext =
|
||||||
|
React.createContext<MapInteraction["setPreventMapInteraction"] | undefined>(
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
export const MapWidthContext =
|
||||||
|
React.createContext<MapInteraction["mapWidth"] | undefined>(undefined);
|
||||||
|
export const MapHeightContext =
|
||||||
|
React.createContext<MapInteraction["mapHeight"] | undefined>(undefined);
|
||||||
|
export const InteractionEmitterContext =
|
||||||
|
React.createContext<MapInteraction["interactionEmitter"] | undefined>(
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
|
||||||
|
export function MapInteractionProvider({
|
||||||
|
value,
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
value: MapInteraction;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
const {
|
const {
|
||||||
stageScale,
|
stageScale,
|
||||||
stageWidth,
|
stageWidth,
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
|
import { Stage } from "konva/types/Stage";
|
||||||
|
|
||||||
const MapStageContext = React.createContext({ current: null });
|
type MapStage = React.MutableRefObject<Stage | null>;
|
||||||
export const MapStageProvider: any = MapStageContext.Provider;
|
|
||||||
|
const MapStageContext = React.createContext<MapStage | undefined>(undefined);
|
||||||
|
export const MapStageProvider = MapStageContext.Provider;
|
||||||
|
|
||||||
export function useMapStage() {
|
export function useMapStage() {
|
||||||
const context = useContext(MapStageContext);
|
const context = useContext(MapStageContext);
|
||||||
|
@ -12,6 +12,7 @@ const colors = {
|
|||||||
darkGray: "rgb(90, 90, 90)",
|
darkGray: "rgb(90, 90, 90)",
|
||||||
lightGray: "rgb(179, 179, 179)",
|
lightGray: "rgb(179, 179, 179)",
|
||||||
white: "rgb(255, 255, 255)",
|
white: "rgb(255, 255, 255)",
|
||||||
|
primary: "hsl(260, 100%, 80%)",
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Colors = typeof colors;
|
export type Colors = typeof colors;
|
||||||
|
@ -331,10 +331,8 @@ export function getRelativePointerPosition(
|
|||||||
): { x: number; y: number } | undefined {
|
): { x: number; y: number } | undefined {
|
||||||
let transform = node.getAbsoluteTransform().copy();
|
let transform = node.getAbsoluteTransform().copy();
|
||||||
transform.invert();
|
transform.invert();
|
||||||
// TODO: handle possible null value
|
|
||||||
let position = node.getStage()?.getPointerPosition();
|
let position = node.getStage()?.getPointerPosition();
|
||||||
if (!position) {
|
if (!position) {
|
||||||
// TODO: handle possible null value
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return transform.point(position);
|
return transform.point(position);
|
||||||
|
@ -19,11 +19,14 @@ import {
|
|||||||
* @param {number=} snappingSensitivity 1 = Always snap, 0 = never snap if undefined the default user setting will be used
|
* @param {number=} snappingSensitivity 1 = Always snap, 0 = never snap if undefined the default user setting will be used
|
||||||
* @param {boolean=} useCorners Snap to grid cell corners
|
* @param {boolean=} useCorners Snap to grid cell corners
|
||||||
*/
|
*/
|
||||||
function useGridSnapping(snappingSensitivity, useCorners = true) {
|
function useGridSnapping(
|
||||||
const [defaultSnappingSensitivity] = useSetting(
|
snappingSensitivity: number | undefined = undefined,
|
||||||
|
useCorners: boolean = true
|
||||||
|
) {
|
||||||
|
const [defaultSnappingSensitivity] = useSetting<number>(
|
||||||
"map.gridSnappingSensitivity"
|
"map.gridSnappingSensitivity"
|
||||||
);
|
);
|
||||||
snappingSensitivity =
|
let gridSnappingSensitivity =
|
||||||
snappingSensitivity === undefined
|
snappingSensitivity === undefined
|
||||||
? defaultSnappingSensitivity
|
? defaultSnappingSensitivity
|
||||||
: snappingSensitivity;
|
: snappingSensitivity;
|
||||||
@ -36,7 +39,7 @@ function useGridSnapping(snappingSensitivity, useCorners = true) {
|
|||||||
/**
|
/**
|
||||||
* @param {Vector2} node The node to snap
|
* @param {Vector2} node The node to snap
|
||||||
*/
|
*/
|
||||||
function snapPositionToGrid(position) {
|
function snapPositionToGrid(position: Vector2) {
|
||||||
// Account for grid offset
|
// Account for grid offset
|
||||||
let offsetPosition = Vector2.subtract(
|
let offsetPosition = Vector2.subtract(
|
||||||
Vector2.subtract(position, gridOffset),
|
Vector2.subtract(position, gridOffset),
|
||||||
@ -70,7 +73,7 @@ function useGridSnapping(snappingSensitivity, useCorners = true) {
|
|||||||
const distanceToSnapPoint = Vector2.distance(offsetPosition, snapPoint);
|
const distanceToSnapPoint = Vector2.distance(offsetPosition, snapPoint);
|
||||||
if (
|
if (
|
||||||
distanceToSnapPoint <
|
distanceToSnapPoint <
|
||||||
Vector2.min(gridCellPixelSize) * snappingSensitivity
|
(Vector2.min(gridCellPixelSize) as number) * gridSnappingSensitivity
|
||||||
) {
|
) {
|
||||||
// Reverse grid offset
|
// Reverse grid offset
|
||||||
let offsetSnapPoint = Vector2.add(
|
let offsetSnapPoint = Vector2.add(
|
@ -28,6 +28,7 @@ import NetworkedMapAndTokens from "../network/NetworkedMapAndTokens";
|
|||||||
import NetworkedParty from "../network/NetworkedParty";
|
import NetworkedParty from "../network/NetworkedParty";
|
||||||
|
|
||||||
import Session from "../network/Session";
|
import Session from "../network/Session";
|
||||||
|
import { Stage } from "konva/types/Stage";
|
||||||
|
|
||||||
function Game() {
|
function Game() {
|
||||||
const { id: gameId }: { id: string } = useParams();
|
const { id: gameId }: { id: string } = useParams();
|
||||||
@ -110,7 +111,7 @@ function Game() {
|
|||||||
|
|
||||||
// A ref to the Konva stage
|
// A ref to the Konva stage
|
||||||
// the ref will be assigned in the MapInteraction component
|
// the ref will be assigned in the MapInteraction component
|
||||||
const mapStageRef: React.MutableRefObject<any> = useRef();
|
const mapStageRef = useRef<Stage | null>(null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AssetsProvider>
|
<AssetsProvider>
|
||||||
|
@ -37,7 +37,7 @@ export type ShapeData = PointsData | RectData | CircleData;
|
|||||||
|
|
||||||
export type BaseDrawing = {
|
export type BaseDrawing = {
|
||||||
blend: boolean;
|
blend: boolean;
|
||||||
color: string;
|
color: Color;
|
||||||
id: string;
|
id: string;
|
||||||
strokeWidth: number;
|
strokeWidth: number;
|
||||||
};
|
};
|
||||||
@ -46,8 +46,6 @@ export type BaseShape = BaseDrawing & {
|
|||||||
type: "shape";
|
type: "shape";
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ShapeType = "line" | "rectangle" | "circle" | "triangle";
|
|
||||||
|
|
||||||
export type Line = BaseShape & {
|
export type Line = BaseShape & {
|
||||||
shapeType: "line";
|
shapeType: "line";
|
||||||
data: PointsData;
|
data: PointsData;
|
||||||
@ -68,6 +66,12 @@ export type Triangle = BaseShape & {
|
|||||||
data: PointsData;
|
data: PointsData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ShapeType =
|
||||||
|
| Line["shapeType"]
|
||||||
|
| Rectangle["shapeType"]
|
||||||
|
| Circle["shapeType"]
|
||||||
|
| Triangle["shapeType"];
|
||||||
|
|
||||||
export type Shape = Line | Rectangle | Circle | Triangle;
|
export type Shape = Line | Rectangle | Circle | Triangle;
|
||||||
|
|
||||||
export type Path = BaseDrawing & {
|
export type Path = BaseDrawing & {
|
||||||
@ -77,3 +81,12 @@ export type Path = BaseDrawing & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type Drawing = Shape | Path;
|
export type Drawing = Shape | Path;
|
||||||
|
|
||||||
|
export function drawingToolIsShape(type: DrawingToolType): type is ShapeType {
|
||||||
|
return (
|
||||||
|
type === "line" ||
|
||||||
|
type === "rectangle" ||
|
||||||
|
type === "circle" ||
|
||||||
|
type === "triangle"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user