mirror of
https://github.com/stan-smith/FossFLOW.git
synced 2026-04-23 16:42:54 -04:00
fix: removes references to window size, replaces with renderer size
This commit is contained in:
@@ -1,34 +1,26 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Box } from '@mui/material';
|
||||
import { Connector as ConnectorI, Node, Coords, Scroll, Size } from 'src/types';
|
||||
import { Svg } from 'src/components/Svg/Svg';
|
||||
import { Connector as ConnectorI, Node, Coords } from 'src/types';
|
||||
import { UNPROJECTED_TILE_SIZE } from 'src/config';
|
||||
import {
|
||||
pathfinder,
|
||||
getBoundingBox,
|
||||
getBoundingBoxSize,
|
||||
getTilePosition
|
||||
} from 'src/utils';
|
||||
import { pathfinder, getBoundingBox, getBoundingBoxSize } from 'src/utils';
|
||||
import { IsoTileArea } from 'src/components/IsoTileArea/IsoTileArea';
|
||||
import { useGetTilePosition } from 'src/hooks/useGetTilePosition';
|
||||
import { useUiStateStore } from 'src/stores/useUiStateStore';
|
||||
|
||||
interface Props {
|
||||
connector: ConnectorI;
|
||||
fromNode: Node;
|
||||
toNode: Node;
|
||||
scroll: Scroll;
|
||||
zoom: number;
|
||||
}
|
||||
|
||||
// How far a connector can be outside the grid area that covers two nodes
|
||||
const BOUNDS_OFFSET: Coords = { x: 3, y: 3 };
|
||||
|
||||
export const Connector = ({
|
||||
connector,
|
||||
fromNode,
|
||||
toNode,
|
||||
zoom,
|
||||
scroll
|
||||
}: Props) => {
|
||||
export const Connector = ({ fromNode, toNode }: Props) => {
|
||||
const zoom = useUiStateStore((state) => {
|
||||
return state.zoom;
|
||||
});
|
||||
const { getTilePosition } = useGetTilePosition();
|
||||
const connectorParams = useMemo(() => {
|
||||
const searchArea = getBoundingBox(
|
||||
[fromNode.position, toNode.position],
|
||||
@@ -46,13 +38,11 @@ export const Connector = ({
|
||||
}`;
|
||||
}, '');
|
||||
const position = getTilePosition({
|
||||
tile: fromNode.position,
|
||||
zoom,
|
||||
scroll
|
||||
tile: fromNode.position
|
||||
});
|
||||
|
||||
return { path, connectorAreaSize, position };
|
||||
}, [fromNode.position, toNode.position, zoom, scroll]);
|
||||
}, [fromNode.position, toNode.position, getTilePosition, zoom]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
import React, { useEffect, useRef, useCallback, useState } from 'react';
|
||||
import { Box, useTheme } from '@mui/material';
|
||||
import gsap from 'gsap';
|
||||
import { getTilePosition } from 'src/utils';
|
||||
import { Coords, TileOriginEnum, Scroll } from 'src/types';
|
||||
import { Coords, TileOriginEnum } from 'src/types';
|
||||
import { IsoTileArea } from 'src/components/IsoTileArea/IsoTileArea';
|
||||
import { useUiStateStore } from 'src/stores/useUiStateStore';
|
||||
import { useGetTilePosition } from 'src/hooks/useGetTilePosition';
|
||||
|
||||
interface Props {
|
||||
tile: Coords;
|
||||
scroll: Scroll;
|
||||
zoom: number;
|
||||
}
|
||||
|
||||
export const Cursor = ({ tile, zoom, scroll }: Props) => {
|
||||
export const Cursor = ({ tile }: Props) => {
|
||||
const zoom = useUiStateStore((state) => {
|
||||
return state.zoom;
|
||||
});
|
||||
const theme = useTheme();
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
const containerRef = useRef<HTMLDivElement>();
|
||||
const { getTilePosition } = useGetTilePosition();
|
||||
|
||||
const setPosition = useCallback(
|
||||
({
|
||||
@@ -28,9 +31,7 @@ export const Cursor = ({ tile, zoom, scroll }: Props) => {
|
||||
|
||||
const position = getTilePosition({
|
||||
tile: _tile,
|
||||
origin: TileOriginEnum.TOP,
|
||||
scroll,
|
||||
zoom
|
||||
origin: TileOriginEnum.TOP
|
||||
});
|
||||
|
||||
gsap.to(containerRef.current, {
|
||||
@@ -39,7 +40,7 @@ export const Cursor = ({ tile, zoom, scroll }: Props) => {
|
||||
top: position.y
|
||||
});
|
||||
},
|
||||
[zoom, scroll]
|
||||
[getTilePosition]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import chroma from 'chroma-js';
|
||||
import { Box } from '@mui/material';
|
||||
import { Node, Scroll, TileOriginEnum, Group as GroupI } from 'src/types';
|
||||
import { getBoundingBox, getTilePosition, getBoundingBoxSize } from 'src/utils';
|
||||
import { Node, TileOriginEnum, Group as GroupI } from 'src/types';
|
||||
import { getBoundingBox, getBoundingBoxSize } from 'src/utils';
|
||||
import { IsoTileArea } from 'src/components/IsoTileArea/IsoTileArea';
|
||||
import { useGetTilePosition } from 'src/hooks/useGetTilePosition';
|
||||
import { useUiStateStore } from 'src/stores/useUiStateStore';
|
||||
|
||||
interface Props {
|
||||
nodes: Node[];
|
||||
group: GroupI;
|
||||
zoom: number;
|
||||
scroll: Scroll;
|
||||
}
|
||||
|
||||
export const Group = ({ nodes, zoom, scroll, group }: Props) => {
|
||||
export const Group = ({ nodes, group }: Props) => {
|
||||
const zoom = useUiStateStore((state) => {
|
||||
return state.zoom;
|
||||
});
|
||||
const { getTilePosition } = useGetTilePosition();
|
||||
const nodePositions = useMemo(() => {
|
||||
return nodes.map((node) => {
|
||||
return node.position;
|
||||
@@ -25,13 +29,11 @@ export const Group = ({ nodes, zoom, scroll, group }: Props) => {
|
||||
|
||||
const position = getTilePosition({
|
||||
tile: corners[2],
|
||||
zoom,
|
||||
scroll,
|
||||
origin: TileOriginEnum.TOP
|
||||
});
|
||||
|
||||
return { size, position };
|
||||
}, [nodePositions, zoom, scroll]);
|
||||
}, [nodePositions, getTilePosition]);
|
||||
|
||||
if (!groupAttrs) return null;
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import React, { useEffect, useRef, useCallback, useMemo } from 'react';
|
||||
import { Box } from '@mui/material';
|
||||
import gsap from 'gsap';
|
||||
import { Size, Coords, TileOriginEnum, Node as NodeI, Scroll } from 'src/types';
|
||||
import {
|
||||
getTilePosition,
|
||||
getProjectedTileSize,
|
||||
getColorVariant
|
||||
} from 'src/utils';
|
||||
import { Size, Coords, TileOriginEnum, Node as NodeI } from 'src/types';
|
||||
import { getProjectedTileSize, getColorVariant } from 'src/utils';
|
||||
import { useResizeObserver } from 'src/hooks/useResizeObserver';
|
||||
import { IsoTileArea } from 'src/components/IsoTileArea/IsoTileArea';
|
||||
import { useUiStateStore } from 'src/stores/useUiStateStore';
|
||||
import { useGetTilePosition } from 'src/hooks/useGetTilePosition';
|
||||
import { LabelContainer } from './LabelContainer';
|
||||
import { MarkdownLabel } from './LabelTypes/MarkdownLabel';
|
||||
|
||||
interface Props {
|
||||
node: NodeI;
|
||||
iconUrl?: string;
|
||||
zoom: number;
|
||||
scroll: Scroll;
|
||||
}
|
||||
|
||||
export const Node = ({ node, iconUrl, zoom, scroll }: Props) => {
|
||||
export const Node = ({ node, iconUrl }: Props) => {
|
||||
const zoom = useUiStateStore((state) => {
|
||||
return state.zoom;
|
||||
});
|
||||
const nodeRef = useRef<HTMLDivElement>();
|
||||
const iconRef = useRef<HTMLImageElement>();
|
||||
const { observe, size: iconSize } = useResizeObserver();
|
||||
const { getTilePosition } = useGetTilePosition();
|
||||
|
||||
useEffect(() => {
|
||||
if (!iconRef.current) return;
|
||||
@@ -46,8 +46,6 @@ export const Node = ({ node, iconUrl, zoom, scroll }: Props) => {
|
||||
|
||||
const position = getTilePosition({
|
||||
tile,
|
||||
zoom,
|
||||
scroll,
|
||||
origin: TileOriginEnum.BOTTOM
|
||||
});
|
||||
|
||||
@@ -63,7 +61,7 @@ export const Node = ({ node, iconUrl, zoom, scroll }: Props) => {
|
||||
y: position.y
|
||||
});
|
||||
},
|
||||
[zoom, scroll]
|
||||
[getTilePosition]
|
||||
);
|
||||
|
||||
const onImageLoaded = useCallback(() => {
|
||||
|
||||
@@ -10,6 +10,7 @@ import { Node } from 'src/components/Node/Node';
|
||||
import { Group } from 'src/components/Group/Group';
|
||||
import { Connector } from 'src/components/Connector/Connector';
|
||||
import { DebugUtils } from 'src/components/DebugUtils/DebugUtils';
|
||||
import { useResizeObserver } from 'src/hooks/useResizeObserver';
|
||||
|
||||
export const Renderer = () => {
|
||||
const [isDebugModeOn] = useState(false);
|
||||
@@ -32,7 +33,11 @@ export const Renderer = () => {
|
||||
const scroll = useUiStateStore((state) => {
|
||||
return state.scroll;
|
||||
});
|
||||
const { setRendererSize } = useUiStateStore((state) => {
|
||||
return state.actions;
|
||||
});
|
||||
const { setElement } = useInteractionManager();
|
||||
const { observe, size: rendererSize } = useResizeObserver();
|
||||
|
||||
const getNodesFromIds = useCallback(
|
||||
(nodeIds: string[]) => {
|
||||
@@ -52,8 +57,13 @@ export const Renderer = () => {
|
||||
useEffect(() => {
|
||||
if (!containerRef.current) return;
|
||||
|
||||
observe(containerRef.current);
|
||||
setElement(containerRef.current);
|
||||
}, [setElement]);
|
||||
}, [setElement, observe]);
|
||||
|
||||
useEffect(() => {
|
||||
setRendererSize(rendererSize);
|
||||
}, [rendererSize, setRendererSize]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@@ -67,19 +77,9 @@ export const Renderer = () => {
|
||||
{scene.groups.map((group) => {
|
||||
const nodes = getNodesFromIds(group.nodeIds);
|
||||
|
||||
return (
|
||||
<Group
|
||||
key={group.id}
|
||||
group={group}
|
||||
nodes={nodes}
|
||||
zoom={zoom}
|
||||
scroll={scroll}
|
||||
/>
|
||||
);
|
||||
return <Group key={group.id} group={group} nodes={nodes} />;
|
||||
})}
|
||||
{mode.showCursor && (
|
||||
<Cursor tile={mouse.position.tile} zoom={zoom} scroll={scroll} />
|
||||
)}
|
||||
{mode.showCursor && <Cursor tile={mouse.position.tile} />}
|
||||
{/* {scene.connectors.map((connector) => {
|
||||
const nodes = getNodesFromIds([connector.from, connector.to]);
|
||||
|
||||
@@ -103,8 +103,6 @@ export const Renderer = () => {
|
||||
return icon.id === node.iconId;
|
||||
})?.url
|
||||
}
|
||||
zoom={zoom}
|
||||
scroll={scroll}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -2,12 +2,8 @@ import { useCallback } from 'react';
|
||||
import { useSceneStore } from 'src/stores/useSceneStore';
|
||||
import { useUiStateStore } from 'src/stores/useUiStateStore';
|
||||
import { Size, Coords } from 'src/types';
|
||||
import {
|
||||
getBoundingBox,
|
||||
getBoundingBoxSize,
|
||||
sortByPosition,
|
||||
getTilePosition
|
||||
} from 'src/utils';
|
||||
import { getBoundingBox, getBoundingBoxSize, sortByPosition } from 'src/utils';
|
||||
import { useGetTilePosition } from 'src/hooks/useGetTilePosition';
|
||||
|
||||
const BOUNDING_BOX_PADDING = 4;
|
||||
|
||||
@@ -29,6 +25,7 @@ export const useDiagramUtils = () => {
|
||||
const uiStateActions = useUiStateStore((state) => {
|
||||
return state.actions;
|
||||
});
|
||||
const { getTilePosition } = useGetTilePosition();
|
||||
|
||||
const getDiagramBoundingBox = useCallback((): Size & Coords => {
|
||||
if (scene.nodes.length === 0) return { width: 0, height: 0, x: 0, y: 0 };
|
||||
@@ -43,9 +40,7 @@ export const useDiagramUtils = () => {
|
||||
});
|
||||
const cornerPositions = corners.map((corner) => {
|
||||
return getTilePosition({
|
||||
scroll,
|
||||
tile: corner,
|
||||
zoom
|
||||
tile: corner
|
||||
});
|
||||
});
|
||||
const sortedCorners = sortByPosition(cornerPositions);
|
||||
@@ -58,7 +53,7 @@ export const useDiagramUtils = () => {
|
||||
x: topLeft.x,
|
||||
y: topLeft.y
|
||||
};
|
||||
}, [scene, scroll, zoom]);
|
||||
}, [scene, getTilePosition]);
|
||||
|
||||
const fitDiagramToScreen = useCallback(() => {
|
||||
const boundingBox = getDiagramBoundingBox();
|
||||
|
||||
29
src/hooks/useGetTilePosition.ts
Normal file
29
src/hooks/useGetTilePosition.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useUiStateStore } from 'src/stores/useUiStateStore';
|
||||
import { Coords, TileOriginEnum } from 'src/types';
|
||||
import { getTilePosition as getTilePositionUtil } from 'src/utils';
|
||||
|
||||
export const useGetTilePosition = () => {
|
||||
const { scroll, zoom, rendererSize } = useUiStateStore((state) => {
|
||||
return {
|
||||
scroll: state.scroll,
|
||||
zoom: state.zoom,
|
||||
rendererSize: state.rendererSize
|
||||
};
|
||||
});
|
||||
|
||||
const getTilePosition = useCallback(
|
||||
({ tile, origin }: { tile: Coords; origin?: TileOriginEnum }) => {
|
||||
return getTilePositionUtil({
|
||||
tile,
|
||||
scroll,
|
||||
zoom,
|
||||
origin,
|
||||
rendererSize
|
||||
});
|
||||
},
|
||||
[scroll, zoom, rendererSize]
|
||||
);
|
||||
|
||||
return { getTilePosition };
|
||||
};
|
||||
@@ -17,7 +17,7 @@ const reducers: { [k in string]: InteractionReducer } = {
|
||||
};
|
||||
|
||||
export const useInteractionManager = () => {
|
||||
const elementRef = useRef<HTMLElement>();
|
||||
const rendererRef = useRef<HTMLElement>();
|
||||
const mode = useUiStateStore((state) => {
|
||||
return state.mode;
|
||||
});
|
||||
@@ -42,9 +42,14 @@ export const useInteractionManager = () => {
|
||||
const scene = useSceneStore(({ nodes, connectors, groups, icons }) => {
|
||||
return { nodes, connectors, groups, icons };
|
||||
});
|
||||
const rendererSize = useUiStateStore((state) => {
|
||||
return state.rendererSize;
|
||||
});
|
||||
|
||||
const onMouseEvent = useCallback(
|
||||
(e: MouseEvent) => {
|
||||
if (!rendererRef.current) return;
|
||||
|
||||
const reducer = reducers[mode.type];
|
||||
|
||||
if (
|
||||
@@ -58,7 +63,7 @@ export const useInteractionManager = () => {
|
||||
return;
|
||||
|
||||
const reducerAction = reducer[e.type];
|
||||
const componentOffset = elementRef.current?.getBoundingClientRect();
|
||||
const componentOffset = rendererRef.current?.getBoundingClientRect();
|
||||
const offset: Coords = {
|
||||
x: componentOffset?.left ?? 0,
|
||||
y: componentOffset?.top ?? 0
|
||||
@@ -74,7 +79,8 @@ export const useInteractionManager = () => {
|
||||
tile: screenToIso({
|
||||
mouse: mousePosition,
|
||||
zoom,
|
||||
scroll
|
||||
scroll,
|
||||
rendererSize
|
||||
})
|
||||
};
|
||||
|
||||
@@ -134,21 +140,23 @@ export const useInteractionManager = () => {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!elementRef.current) return;
|
||||
if (!rendererRef.current) return;
|
||||
|
||||
window.addEventListener('mousemove', onMouseEvent);
|
||||
window.addEventListener('mousedown', onMouseEvent);
|
||||
window.addEventListener('mouseup', onMouseEvent);
|
||||
const el = rendererRef.current;
|
||||
|
||||
el.addEventListener('mousemove', onMouseEvent);
|
||||
el.addEventListener('mousedown', onMouseEvent);
|
||||
el.addEventListener('mouseup', onMouseEvent);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('mousemove', onMouseEvent);
|
||||
window.removeEventListener('mousedown', onMouseEvent);
|
||||
window.removeEventListener('mouseup', onMouseEvent);
|
||||
el.removeEventListener('mousemove', onMouseEvent);
|
||||
el.removeEventListener('mousedown', onMouseEvent);
|
||||
el.removeEventListener('mouseup', onMouseEvent);
|
||||
};
|
||||
}, [onMouseEvent]);
|
||||
|
||||
const setElement = useCallback((element: HTMLElement) => {
|
||||
elementRef.current = element;
|
||||
rendererRef.current = element;
|
||||
}, []);
|
||||
|
||||
return {
|
||||
|
||||
@@ -31,6 +31,7 @@ export const useUiStateStore = create<UseUiStateStore>((set, get) => {
|
||||
offset: { x: 0, y: 0 }
|
||||
},
|
||||
zoom: 1,
|
||||
rendererSize: { width: 0, height: 0 },
|
||||
actions: {
|
||||
setMode: (mode) => {
|
||||
set({ mode });
|
||||
@@ -62,6 +63,9 @@ export const useUiStateStore = create<UseUiStateStore>((set, get) => {
|
||||
},
|
||||
setMouse: (mouse) => {
|
||||
set({ mouse });
|
||||
},
|
||||
setRendererSize: (rendererSize) => {
|
||||
set({ rendererSize });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Coords } from './common';
|
||||
import { Coords, Size } from './common';
|
||||
import { SceneItem } from './scene';
|
||||
|
||||
export enum SidebarTypeEnum {
|
||||
@@ -87,6 +87,7 @@ export interface UiState {
|
||||
zoom: number;
|
||||
scroll: Scroll;
|
||||
mouse: Mouse;
|
||||
rendererSize: Size;
|
||||
}
|
||||
|
||||
export interface UiStateActions {
|
||||
@@ -99,4 +100,5 @@ export interface UiStateActions {
|
||||
setSidebar: (itemControls: ItemControls) => void;
|
||||
setContextMenu: (contextMenu: ContextMenu) => void;
|
||||
setMouse: (mouse: Mouse) => void;
|
||||
setRendererSize: (rendererSize: Size) => void;
|
||||
}
|
||||
|
||||
@@ -18,20 +18,24 @@ interface ScreenToIso {
|
||||
mouse: Coords;
|
||||
zoom: number;
|
||||
scroll: Scroll;
|
||||
rendererSize: Size;
|
||||
}
|
||||
|
||||
// converts a mouse position to a tile position
|
||||
export const screenToIso = ({ mouse, zoom, scroll }: ScreenToIso) => {
|
||||
const editorWidth = window.innerWidth;
|
||||
const editorHeight = window.innerHeight;
|
||||
export const screenToIso = ({
|
||||
mouse,
|
||||
zoom,
|
||||
scroll,
|
||||
rendererSize
|
||||
}: ScreenToIso) => {
|
||||
const projectedTileSize = getProjectedTileSize({ zoom });
|
||||
const halfW = projectedTileSize.width / 2;
|
||||
const halfH = projectedTileSize.height / 2;
|
||||
|
||||
// The origin is the center of the project.
|
||||
const projectPosition = {
|
||||
x: mouse.x - scroll.position.x - editorWidth * 0.5,
|
||||
y: mouse.y - scroll.position.y - editorHeight * 0.5
|
||||
x: mouse.x - scroll.position.x - rendererSize.width * 0.5,
|
||||
y: mouse.y - scroll.position.y - rendererSize.height * 0.5
|
||||
};
|
||||
|
||||
const tile = {
|
||||
@@ -53,26 +57,29 @@ interface GetTilePosition {
|
||||
scroll: Scroll;
|
||||
zoom: number;
|
||||
origin?: TileOriginEnum;
|
||||
rendererSize: Size;
|
||||
}
|
||||
|
||||
export const getTilePosition = ({
|
||||
tile,
|
||||
scroll,
|
||||
zoom,
|
||||
origin = TileOriginEnum.CENTER
|
||||
origin = TileOriginEnum.CENTER,
|
||||
rendererSize
|
||||
}: GetTilePosition) => {
|
||||
// TODO: Refactor editorWidth to not use window width
|
||||
const editorWidth = window.innerWidth;
|
||||
const editorHeight = window.innerHeight;
|
||||
const projectedTileSize = getProjectedTileSize({ zoom });
|
||||
const halfW = projectedTileSize.width / 2;
|
||||
const halfH = projectedTileSize.height / 2;
|
||||
|
||||
const position: Coords = {
|
||||
x:
|
||||
editorWidth * 0.5 + (halfW * tile.x - halfW * tile.y) + scroll.position.x,
|
||||
rendererSize.width * 0.5 +
|
||||
(halfW * tile.x - halfW * tile.y) +
|
||||
scroll.position.x,
|
||||
y:
|
||||
editorHeight * 0.5 - (halfH * tile.x + halfH * tile.y) + scroll.position.y
|
||||
rendererSize.height * 0.5 -
|
||||
(halfH * tile.x + halfH * tile.y) +
|
||||
scroll.position.y
|
||||
};
|
||||
|
||||
switch (origin) {
|
||||
|
||||
Reference in New Issue
Block a user