Format
This commit is contained in:
parent
62686136ab
commit
123ebd880a
@ -31,72 +31,70 @@ import Session from "../../network/Session";
|
|||||||
import { Grid } from "../../helpers/grid";
|
import { Grid } from "../../helpers/grid";
|
||||||
import { ImageFile } from "../../helpers/image";
|
import { ImageFile } from "../../helpers/image";
|
||||||
|
|
||||||
export type Resolutions = Record<string, ImageFile>
|
export type Resolutions = Record<string, ImageFile>;
|
||||||
export type Map = {
|
export type Map = {
|
||||||
id: string,
|
id: string;
|
||||||
name: string,
|
name: string;
|
||||||
owner: string,
|
owner: string;
|
||||||
file?: Uint8Array,
|
file?: Uint8Array;
|
||||||
quality?: string,
|
quality?: string;
|
||||||
resolutions?: Resolutions,
|
resolutions?: Resolutions;
|
||||||
grid: Grid,
|
grid: Grid;
|
||||||
group: string,
|
group: string;
|
||||||
width: number,
|
width: number;
|
||||||
height: number,
|
height: number;
|
||||||
type: string,
|
type: string;
|
||||||
lastUsed: number,
|
lastUsed: number;
|
||||||
lastModified: number,
|
lastModified: number;
|
||||||
created: number,
|
created: number;
|
||||||
showGrid: boolean,
|
showGrid: boolean;
|
||||||
snapToGrid: boolean,
|
snapToGrid: boolean;
|
||||||
thumbnail?: ImageFile,
|
thumbnail?: ImageFile;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type Note = {
|
export type Note = {
|
||||||
id: string,
|
id: string;
|
||||||
color: string,
|
color: string;
|
||||||
lastModified: number,
|
lastModified: number;
|
||||||
lastModifiedBy: string,
|
lastModifiedBy: string;
|
||||||
locked: boolean,
|
locked: boolean;
|
||||||
size: number,
|
size: number;
|
||||||
text: string,
|
text: string;
|
||||||
textOnly: boolean,
|
textOnly: boolean;
|
||||||
visible: boolean,
|
visible: boolean;
|
||||||
x: number,
|
x: number;
|
||||||
y: number,
|
y: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type TokenState = {
|
export type TokenState = {
|
||||||
id: string,
|
id: string;
|
||||||
tokenId: string,
|
tokenId: string;
|
||||||
owner: string,
|
owner: string;
|
||||||
size: number,
|
size: number;
|
||||||
label: string,
|
category: string;
|
||||||
status: string[],
|
label: string;
|
||||||
x: number,
|
statuses: string[];
|
||||||
y: number,
|
x: number;
|
||||||
lastModifiedBy: string,
|
y: number;
|
||||||
lastModified: number,
|
lastModifiedBy: string;
|
||||||
rotation: number,
|
lastModified: number;
|
||||||
locked: boolean,
|
rotation: number;
|
||||||
visible: boolean
|
locked: boolean;
|
||||||
}
|
visible: boolean;
|
||||||
|
type: "default" | "file";
|
||||||
|
outline: any;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
};
|
||||||
|
|
||||||
interface PathId extends Path {
|
|
||||||
id: string
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ShapeId extends Shape {
|
|
||||||
id: string
|
|
||||||
}
|
|
||||||
export type MapState = {
|
export type MapState = {
|
||||||
tokens: Record<string, TokenState>,
|
tokens: Record<string, TokenState>;
|
||||||
drawShapes: PathId | ShapeId,
|
drawShapes: Record<string, Path | Shape>;
|
||||||
fogShapes: Fog[],
|
fogShapes: Record<string, Fog>;
|
||||||
editFlags: ["drawing", "tokens", "notes", "fog"],
|
editFlags: ["drawing", "tokens", "notes", "fog"];
|
||||||
notes: Note[],
|
notes: Record<string, Note>;
|
||||||
mapId: string,
|
mapId: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
function Map({
|
function Map({
|
||||||
map,
|
map,
|
||||||
@ -121,34 +119,35 @@ function Map({
|
|||||||
disabledTokens,
|
disabledTokens,
|
||||||
session,
|
session,
|
||||||
}: {
|
}: {
|
||||||
map: any
|
map: any;
|
||||||
mapState: MapState
|
mapState: MapState;
|
||||||
mapActions: any,
|
mapActions: any;
|
||||||
onMapTokenStateChange: any,
|
onMapTokenStateChange: any;
|
||||||
onMapTokenStateRemove: any,
|
onMapTokenStateRemove: any;
|
||||||
onMapChange: any,
|
onMapChange: any;
|
||||||
onMapReset: any,
|
onMapReset: any;
|
||||||
onMapDraw: any,
|
onMapDraw: any;
|
||||||
onMapDrawUndo: any,
|
onMapDrawUndo: any;
|
||||||
onMapDrawRedo: any,
|
onMapDrawRedo: any;
|
||||||
onFogDraw: any,
|
onFogDraw: any;
|
||||||
onFogDrawUndo: any,
|
onFogDrawUndo: any;
|
||||||
onFogDrawRedo: any,
|
onFogDrawRedo: any;
|
||||||
onMapNoteChange: any,
|
onMapNoteChange: any;
|
||||||
onMapNoteRemove: any,
|
onMapNoteRemove: any;
|
||||||
allowMapDrawing: boolean,
|
allowMapDrawing: boolean;
|
||||||
allowFogDrawing: boolean,
|
allowFogDrawing: boolean;
|
||||||
allowMapChange: boolean,
|
allowMapChange: boolean;
|
||||||
allowNoteEditing: boolean,
|
allowNoteEditing: boolean;
|
||||||
disabledTokens: any,
|
disabledTokens: any;
|
||||||
session: Session
|
session: Session;
|
||||||
}) {
|
}) {
|
||||||
const { addToast } = useToasts();
|
const { addToast } = useToasts();
|
||||||
|
|
||||||
const { tokensById } = useTokenData();
|
const { tokensById } = useTokenData();
|
||||||
|
|
||||||
const [selectedToolId, setSelectedToolId] = useState("move");
|
const [selectedToolId, setSelectedToolId] = useState("move");
|
||||||
const { settings, setSettings }: { settings: any, setSettings: any} = useSettings();
|
const { settings, setSettings }: { settings: any; setSettings: any } =
|
||||||
|
useSettings();
|
||||||
|
|
||||||
function handleToolSettingChange(tool: any, change: any) {
|
function handleToolSettingChange(tool: any, change: any) {
|
||||||
setSettings((prevSettings: any) => ({
|
setSettings((prevSettings: any) => ({
|
||||||
@ -224,7 +223,10 @@ function Map({
|
|||||||
disabledControls.push("note");
|
disabledControls.push("note");
|
||||||
}
|
}
|
||||||
|
|
||||||
const disabledSettings: { fog: any[], drawing: any[]} = { fog: [], drawing: [] };
|
const disabledSettings: { fog: any[]; drawing: any[] } = {
|
||||||
|
fog: [],
|
||||||
|
drawing: [],
|
||||||
|
};
|
||||||
if (drawShapes.length === 0) {
|
if (drawShapes.length === 0) {
|
||||||
disabledSettings.drawing.push("erase");
|
disabledSettings.drawing.push("erase");
|
||||||
}
|
}
|
||||||
@ -263,9 +265,18 @@ function Map({
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const [isTokenMenuOpen, setIsTokenMenuOpen]: [ isTokenMenuOpen: boolean, setIsTokenMenuOpen: React.Dispatch<React.SetStateAction<boolean>>] = useState<boolean>(false);
|
const [isTokenMenuOpen, setIsTokenMenuOpen]: [
|
||||||
const [tokenMenuOptions, setTokenMenuOptions]: [ tokenMenuOptions: any, setTokenMenuOptions: any ] = useState({});
|
isTokenMenuOpen: boolean,
|
||||||
const [tokenDraggingOptions, setTokenDraggingOptions]: [ tokenDraggingOptions: any, setTokenDragginOptions: any ] = useState();
|
setIsTokenMenuOpen: React.Dispatch<React.SetStateAction<boolean>>
|
||||||
|
] = useState<boolean>(false);
|
||||||
|
const [tokenMenuOptions, setTokenMenuOptions]: [
|
||||||
|
tokenMenuOptions: any,
|
||||||
|
setTokenMenuOptions: any
|
||||||
|
] = useState({});
|
||||||
|
const [tokenDraggingOptions, setTokenDraggingOptions]: [
|
||||||
|
tokenDraggingOptions: any,
|
||||||
|
setTokenDragginOptions: any
|
||||||
|
] = useState();
|
||||||
function handleTokenMenuOpen(tokenStateId: string, tokenImage: any) {
|
function handleTokenMenuOpen(tokenStateId: string, tokenImage: any) {
|
||||||
setTokenMenuOptions({ tokenStateId, tokenImage });
|
setTokenMenuOptions({ tokenStateId, tokenImage });
|
||||||
setIsTokenMenuOpen(true);
|
setIsTokenMenuOpen(true);
|
||||||
@ -338,10 +349,7 @@ function Map({
|
|||||||
const mapGrid = map && map.showGrid && <MapGrid map={map} />;
|
const mapGrid = map && map.showGrid && <MapGrid map={map} />;
|
||||||
|
|
||||||
const mapMeasure = (
|
const mapMeasure = (
|
||||||
<MapMeasure
|
<MapMeasure map={map} active={selectedToolId === "measure"} />
|
||||||
map={map}
|
|
||||||
active={selectedToolId === "measure"}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const mapPointer = (
|
const mapPointer = (
|
||||||
@ -353,7 +361,7 @@ function Map({
|
|||||||
|
|
||||||
const [isNoteMenuOpen, setIsNoteMenuOpen] = useState<boolean>(false);
|
const [isNoteMenuOpen, setIsNoteMenuOpen] = useState<boolean>(false);
|
||||||
const [noteMenuOptions, setNoteMenuOptions] = useState<any>({});
|
const [noteMenuOptions, setNoteMenuOptions] = useState<any>({});
|
||||||
const [noteDraggingOptions, setNoteDraggingOptions]= useState<any>();
|
const [noteDraggingOptions, setNoteDraggingOptions] = useState<any>();
|
||||||
function handleNoteMenuOpen(noteId: string, noteNode: any) {
|
function handleNoteMenuOpen(noteId: string, noteNode: any) {
|
||||||
setNoteMenuOptions({ noteId, noteNode });
|
setNoteMenuOptions({ noteId, noteNode });
|
||||||
setIsNoteMenuOpen(true);
|
setIsNoteMenuOpen(true);
|
||||||
|
@ -11,12 +11,8 @@ import { getGroupItems } from "../../helpers/group";
|
|||||||
import { useGroup } from "../../contexts/GroupContext";
|
import { useGroup } from "../../contexts/GroupContext";
|
||||||
|
|
||||||
function MapTiles({ mapsById, onMapEdit, onMapSelect, subgroup }) {
|
function MapTiles({ mapsById, onMapEdit, onMapSelect, subgroup }) {
|
||||||
const {
|
const { selectedGroupIds, selectMode, onGroupOpen, onGroupSelect } =
|
||||||
selectedGroupIds,
|
useGroup();
|
||||||
selectMode,
|
|
||||||
onGroupOpen,
|
|
||||||
onGroupSelect,
|
|
||||||
} = useGroup();
|
|
||||||
|
|
||||||
function renderTile(group) {
|
function renderTile(group) {
|
||||||
if (group.type === "item") {
|
if (group.type === "item") {
|
||||||
@ -66,4 +62,8 @@ function MapTiles({ mapsById, onMapEdit, onMapSelect, subgroup }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MapTiles.defaultProps = {
|
||||||
|
subgroup: false,
|
||||||
|
};
|
||||||
|
|
||||||
export default MapTiles;
|
export default MapTiles;
|
||||||
|
@ -12,12 +12,8 @@ import { getGroupItems } from "../../helpers/group";
|
|||||||
import { useGroup } from "../../contexts/GroupContext";
|
import { useGroup } from "../../contexts/GroupContext";
|
||||||
|
|
||||||
function TokenTiles({ tokensById, onTokenEdit, subgroup }) {
|
function TokenTiles({ tokensById, onTokenEdit, subgroup }) {
|
||||||
const {
|
const { selectedGroupIds, selectMode, onGroupOpen, onGroupSelect } =
|
||||||
selectedGroupIds,
|
useGroup();
|
||||||
selectMode,
|
|
||||||
onGroupOpen,
|
|
||||||
onGroupSelect,
|
|
||||||
} = useGroup();
|
|
||||||
|
|
||||||
function renderTile(group) {
|
function renderTile(group) {
|
||||||
if (group.type === "item") {
|
if (group.type === "item") {
|
||||||
@ -70,4 +66,8 @@ function TokenTiles({ tokensById, onTokenEdit, subgroup }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TokenTiles.defaultProps = {
|
||||||
|
subgroup: false,
|
||||||
|
};
|
||||||
|
|
||||||
export default TokenTiles;
|
export default TokenTiles;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
|
|
||||||
const MapStageContext = React.createContext({
|
const MapStageContext = React.createContext({ current: null });
|
||||||
mapStageRef: { current: null },
|
|
||||||
});
|
|
||||||
export const MapStageProvider: any = MapStageContext.Provider;
|
export const MapStageProvider: any = MapStageContext.Provider;
|
||||||
|
|
||||||
export function useMapStage() {
|
export function useMapStage() {
|
||||||
|
@ -44,10 +44,11 @@ class Vector2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns the length of vector `p` Note: magnitude to not conflict with native length property
|
||||||
* @param {Vector2} p
|
* @param {Vector2} p
|
||||||
* @returns {number} Length of `p`
|
* @returns {number} Length of `p`
|
||||||
*/
|
*/
|
||||||
static setLength(p: Vector2): number {
|
static magnitude(p: Vector2): number {
|
||||||
return Math.sqrt(this.lengthSquared(p));
|
return Math.sqrt(this.lengthSquared(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ class Vector2 {
|
|||||||
* @returns {Vector2} `p` normalized, if length of `p` is 0 `{x: 0, y: 0}` is returned
|
* @returns {Vector2} `p` normalized, if length of `p` is 0 `{x: 0, y: 0}` is returned
|
||||||
*/
|
*/
|
||||||
static normalize(p: Vector2): Vector2 {
|
static normalize(p: Vector2): Vector2 {
|
||||||
const l = this.setLength(p);
|
const l = this.magnitude(p);
|
||||||
if (l === 0) {
|
if (l === 0) {
|
||||||
return { x: 0, y: 0 };
|
return { x: 0, y: 0 };
|
||||||
}
|
}
|
||||||
@ -271,7 +272,7 @@ class Vector2 {
|
|||||||
const pa = this.subtract(p, a);
|
const pa = this.subtract(p, a);
|
||||||
const ba = this.subtract(b, a);
|
const ba = this.subtract(b, a);
|
||||||
const h = Math.min(Math.max(this.dot(pa, ba) / this.dot(ba, ba), 0), 1);
|
const h = Math.min(Math.max(this.dot(pa, ba) / this.dot(ba, ba), 0), 1);
|
||||||
const distance = this.setLength(this.subtract(pa, this.multiply(ba, h)));
|
const distance = this.magnitude(this.subtract(pa, this.multiply(ba, h)));
|
||||||
const point = this.add(a, this.multiply(ba, h));
|
const point = this.add(a, this.multiply(ba, h));
|
||||||
return { distance, point };
|
return { distance, point };
|
||||||
}
|
}
|
||||||
@ -443,7 +444,7 @@ class Vector2 {
|
|||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
static distance(a: Vector2, b: Vector2): number {
|
static distance(a: Vector2, b: Vector2): number {
|
||||||
return this.setLength(this.subtract(a, b));
|
return this.magnitude(this.subtract(a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,7 +6,7 @@ import Color from "color";
|
|||||||
import Vector2 from "./Vector2";
|
import Vector2 from "./Vector2";
|
||||||
|
|
||||||
// Holes should be wound in the opposite direction as the containing points array
|
// Holes should be wound in the opposite direction as the containing points array
|
||||||
export function HoleyLine({ holes, ...props }: { holes: any, props: []}) {
|
export function HoleyLine({ holes, ...props }: { holes: any; props: [] }) {
|
||||||
// Converted from https://github.com/rfestag/konva/blob/master/src/shapes/Line.ts
|
// Converted from https://github.com/rfestag/konva/blob/master/src/shapes/Line.ts
|
||||||
function drawLine(points: number[], context: any, shape: any) {
|
function drawLine(points: number[], context: any, shape: any) {
|
||||||
const length = points.length;
|
const length = points.length;
|
||||||
@ -109,7 +109,19 @@ export function HoleyLine({ holes, ...props }: { holes: any, props: []}) {
|
|||||||
return <Line sceneFunc={sceneFunc} {...props} />;
|
return <Line sceneFunc={sceneFunc} {...props} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Tick({ x, y, scale, onClick, cross }: { x: any, y: any, scale: any, onClick: any, cross: any}) {
|
export function Tick({
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
scale,
|
||||||
|
onClick,
|
||||||
|
cross,
|
||||||
|
}: {
|
||||||
|
x: any;
|
||||||
|
y: any;
|
||||||
|
scale: any;
|
||||||
|
onClick: any;
|
||||||
|
cross: any;
|
||||||
|
}) {
|
||||||
const [fill, setFill] = useState("white");
|
const [fill, setFill] = useState("white");
|
||||||
function handleEnter() {
|
function handleEnter() {
|
||||||
setFill("hsl(260, 100%, 80%)");
|
setFill("hsl(260, 100%, 80%)");
|
||||||
@ -145,10 +157,22 @@ export function Tick({ x, y, scale, onClick, cross }: { x: any, y: any, scale: a
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface TrailPoint extends Vector2 {
|
interface TrailPoint extends Vector2 {
|
||||||
lifetime: number
|
lifetime: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Trail({ position, size, duration, segments, color }: { position: Vector2, size: any, duration: number, segments: any, color: string }) {
|
export function Trail({
|
||||||
|
position,
|
||||||
|
size,
|
||||||
|
duration,
|
||||||
|
segments,
|
||||||
|
color,
|
||||||
|
}: {
|
||||||
|
position: Vector2;
|
||||||
|
size: any;
|
||||||
|
duration: number;
|
||||||
|
segments: any;
|
||||||
|
color: string;
|
||||||
|
}) {
|
||||||
const trailRef: React.MutableRefObject<Konva.Line | undefined> = useRef();
|
const trailRef: React.MutableRefObject<Konva.Line | undefined> = useRef();
|
||||||
const pointsRef: React.MutableRefObject<TrailPoint[]> = useRef([]);
|
const pointsRef: React.MutableRefObject<TrailPoint[]> = useRef([]);
|
||||||
const prevPositionRef = useRef(position);
|
const prevPositionRef = useRef(position);
|
||||||
@ -259,7 +283,7 @@ export function Trail({ position, size, duration, segments, color }: { position:
|
|||||||
// Create a radial gradient from the center of the trail to the tail
|
// Create a radial gradient from the center of the trail to the tail
|
||||||
const gradientCenter = resampledPoints[resampledPoints.length - 1];
|
const gradientCenter = resampledPoints[resampledPoints.length - 1];
|
||||||
const gradientEnd = resampledPoints[0];
|
const gradientEnd = resampledPoints[0];
|
||||||
const gradientRadius = Vector2.setLength(
|
const gradientRadius = Vector2.magnitude(
|
||||||
Vector2.subtract(gradientCenter, gradientEnd)
|
Vector2.subtract(gradientCenter, gradientEnd)
|
||||||
);
|
);
|
||||||
let gradient = context.createRadialGradient(
|
let gradient = context.createRadialGradient(
|
||||||
@ -302,7 +326,9 @@ Trail.defaultProps = {
|
|||||||
* @param {Konva.Node} node
|
* @param {Konva.Node} node
|
||||||
* @returns {Vector2}
|
* @returns {Vector2}
|
||||||
*/
|
*/
|
||||||
export function getRelativePointerPosition(node: Konva.Node): { x: number, y: number } | undefined {
|
export function getRelativePointerPosition(
|
||||||
|
node: Konva.Node
|
||||||
|
): { x: number; y: number } | undefined {
|
||||||
let transform = node.getAbsoluteTransform().copy();
|
let transform = node.getAbsoluteTransform().copy();
|
||||||
transform.invert();
|
transform.invert();
|
||||||
// TODO: handle possible null value
|
// TODO: handle possible null value
|
||||||
@ -314,7 +340,9 @@ export function getRelativePointerPosition(node: Konva.Node): { x: number, y: nu
|
|||||||
return transform.point(position);
|
return transform.point(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRelativePointerPositionNormalized(node: Konva.Node): { x: number, y: number } | undefined {
|
export function getRelativePointerPositionNormalized(
|
||||||
|
node: Konva.Node
|
||||||
|
): { x: number; y: number } | undefined {
|
||||||
const relativePosition = getRelativePointerPosition(node);
|
const relativePosition = getRelativePointerPosition(node);
|
||||||
if (!relativePosition) {
|
if (!relativePosition) {
|
||||||
// TODO: handle possible null value
|
// TODO: handle possible null value
|
||||||
|
Loading…
Reference in New Issue
Block a user