fix fix fix fix
This commit is contained in:
parent
4b20c94b70
commit
7c920eb81e
13212
package-lock.json
generated
13212
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,6 @@
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.8.2",
|
||||
"@emotion/styled": "^11.8.1",
|
||||
"@esbuild/win32-x64": "^0.25.3",
|
||||
"@hello-pangea/dnd": "^18.0.1",
|
||||
"@mui/icons-material": "^6.1.6",
|
||||
"@mui/lab": "^6.0.0-beta.14",
|
||||
|
@ -3,6 +3,7 @@ import { Component, ReactNode, useEffect, useState } from "react";
|
||||
import { useTransform } from "./TransformContext";
|
||||
import { useMapData } from "./MapDataContext";
|
||||
import { SCALE_FACTOR } from "./Constants";
|
||||
import { useApplication } from "@pixi/react";
|
||||
|
||||
class ErrorBoundary extends Component<{ children: ReactNode }, { hasError: boolean }> {
|
||||
state = { hasError: false };
|
||||
@ -22,14 +23,27 @@ class ErrorBoundary extends Component<{ children: ReactNode }, { hasError: boole
|
||||
|
||||
|
||||
export function InfiniteCanvas({children} : Readonly<{children?: ReactNode}>) {
|
||||
const { position, setPosition, scale, setScale, rotation, setRotation, applicationRef, getCenter } = useTransform();
|
||||
const { position, setPosition, scale, setScale, rotation, setRotation, setScreenCenter, screenCenter } = useTransform();
|
||||
const { routeData, originalRouteData } = useMapData();
|
||||
|
||||
const applicationRef = useApplication();
|
||||
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [startMousePosition, setStartMousePosition] = useState({ x: 0, y: 0 });
|
||||
const [startRotation, setStartRotation] = useState(0);
|
||||
const [startPosition, setStartPosition] = useState({ x: 0, y: 0 });
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = applicationRef?.app.canvas;
|
||||
if (!canvas) return;
|
||||
const canvasRect = canvas.getBoundingClientRect();
|
||||
const canvasLeft = canvasRect?.left ?? 0;
|
||||
const canvasTop = canvasRect?.top ?? 0;
|
||||
const centerX = window.innerWidth / 2 - canvasLeft;
|
||||
const centerY = window.innerHeight / 2 - canvasTop;
|
||||
setScreenCenter({x: centerX, y: centerY});
|
||||
}, [applicationRef?.app.canvas, window.innerWidth, window.innerHeight]);
|
||||
|
||||
const handlePointerDown = (e: FederatedMouseEvent) => {
|
||||
setIsDragging(true);
|
||||
setStartPosition({
|
||||
@ -53,7 +67,7 @@ export function InfiniteCanvas({children} : Readonly<{children?: ReactNode}>) {
|
||||
if (!isDragging) return;
|
||||
|
||||
if (e.shiftKey) {
|
||||
const center = getCenter();
|
||||
const center = screenCenter ?? {x: 0, y: 0};
|
||||
const startAngle = Math.atan2(startMousePosition.y - center.y, startMousePosition.x - center.x);
|
||||
const currentAngle = Math.atan2(e.globalY - center.y, e.globalX - center.x);
|
||||
|
||||
@ -117,17 +131,17 @@ export function InfiniteCanvas({children} : Readonly<{children?: ReactNode}>) {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
applicationRef?.current?.getApplication()?.render();
|
||||
applicationRef?.app.render();
|
||||
console.log(position, scale, rotation);
|
||||
}, [position, scale, rotation]);
|
||||
|
||||
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
{applicationRef?.current && (
|
||||
{applicationRef?.app && (
|
||||
<pixiGraphics
|
||||
draw={(g) => {
|
||||
const canvas = applicationRef.current!.getCanvas();
|
||||
const canvas = applicationRef.app.canvas;
|
||||
g.clear();
|
||||
g.rect(0, 0, canvas?.width ?? 0, canvas?.height ?? 0);
|
||||
g.fill("#111");
|
||||
@ -154,7 +168,7 @@ export function InfiniteCanvas({children} : Readonly<{children?: ReactNode}>) {
|
||||
|
||||
draw={(g) => {
|
||||
g.clear();
|
||||
const center = getCenter();
|
||||
const center = screenCenter ?? {x: 0, y: 0};
|
||||
g.circle(center.x, center.y, 1);
|
||||
g.fill("#fff");
|
||||
}}
|
||||
|
@ -6,7 +6,7 @@ import { coordinatesToLocal, localToCoordinates } from "./utils";
|
||||
|
||||
export function RightSidebar() {
|
||||
const { routeData, setScaleRange, saveChanges, originalRouteData, setMapRotation, setMapCenter } = useMapData();
|
||||
const { rotation, position, screenToLocal, getCenter, rotateToAngle, setTransform } = useTransform();
|
||||
const { rotation, position, screenToLocal, screenCenter, rotateToAngle, setTransform } = useTransform();
|
||||
const [minScale, setMinScale] = useState<number>(1);
|
||||
const [maxScale, setMaxScale] = useState<number>(10);
|
||||
const [localCenter, setLocalCenter] = useState<{x: number, y: number}>({x: 0, y: 0});
|
||||
@ -36,7 +36,7 @@ export function RightSidebar() {
|
||||
}, [rotationDegrees]);
|
||||
|
||||
useEffect(() => {
|
||||
const center = getCenter();
|
||||
const center = screenCenter ?? {x: 0, y: 0};
|
||||
const localCenter = screenToLocal(center.x, center.y);
|
||||
const coordinates = localToCoordinates(localCenter.x, localCenter.y);
|
||||
setLocalCenter({x: coordinates.latitude, y: coordinates.longitude});
|
||||
|
@ -1,7 +1,4 @@
|
||||
import { createContext, ReactNode, RefObject, useContext, useMemo, useRef, useState } from "react";
|
||||
import {
|
||||
ApplicationRef
|
||||
} from '@pixi/react';
|
||||
import { createContext, ReactNode, useContext, useMemo, useState } from "react";
|
||||
import { SCALE_FACTOR, UP_SCALE } from "./Constants";
|
||||
|
||||
|
||||
@ -9,30 +6,29 @@ const TransformContext = createContext<{
|
||||
position: { x: number, y: number },
|
||||
scale: number,
|
||||
rotation: number,
|
||||
applicationRef: RefObject<ApplicationRef> | null,
|
||||
screenCenter?: { x: number, y: number },
|
||||
|
||||
setPosition: React.Dispatch<React.SetStateAction<{ x: number, y: number }>>,
|
||||
setScale: React.Dispatch<React.SetStateAction<number>>,
|
||||
setRotation: React.Dispatch<React.SetStateAction<number>>,
|
||||
screenToLocal: (x: number, y: number) => { x: number, y: number },
|
||||
localToScreen: (x: number, y: number) => { x: number, y: number },
|
||||
getCenter: () => { x: number, y: number },
|
||||
rotateToAngle: (to: number, fromPosition?: {x: number, y: number}) => void,
|
||||
setTransform: (latitude: number, longitude: number, rotationDegrees?: number, scale?: number) => void
|
||||
setTransform: (latitude: number, longitude: number, rotationDegrees?: number, scale?: number) => void,
|
||||
setScreenCenter: React.Dispatch<React.SetStateAction<{ x: number, y: number } | undefined>>
|
||||
}>({
|
||||
position: { x: 0, y: 0 },
|
||||
scale: 1,
|
||||
rotation: 0,
|
||||
applicationRef: null,
|
||||
|
||||
screenCenter: undefined,
|
||||
setPosition: () => {},
|
||||
setScale: () => {},
|
||||
setRotation: () => {},
|
||||
screenToLocal: () => ({ x: 0, y: 0 }),
|
||||
localToScreen: () => ({ x: 0, y: 0 }),
|
||||
getCenter: () => ({ x: 0, y: 0 }),
|
||||
rotateToAngle: () => {},
|
||||
setTransform: () => {}
|
||||
setTransform: () => {},
|
||||
setScreenCenter: () => {}
|
||||
});
|
||||
|
||||
// Provider component
|
||||
@ -40,7 +36,7 @@ export const TransformProvider = ({ children }: { children: ReactNode }) => {
|
||||
const [position, setPosition] = useState({ x: 0, y: 0 });
|
||||
const [scale, setScale] = useState(1);
|
||||
const [rotation, setRotation] = useState(0);
|
||||
const applicationRef = useRef<ApplicationRef>(null);
|
||||
const [screenCenter, setScreenCenter] = useState<{x: number, y: number}>();
|
||||
|
||||
function screenToLocal(screenX: number, screenY: number) {
|
||||
// Translate point relative to current pan position
|
||||
@ -79,21 +75,13 @@ export const TransformProvider = ({ children }: { children: ReactNode }) => {
|
||||
};
|
||||
}
|
||||
|
||||
function getCenter() {
|
||||
const canvas = applicationRef?.current?.getCanvas();
|
||||
const canvasRect = canvas?.getBoundingClientRect();
|
||||
const canvasLeft = canvasRect?.left ?? 0;
|
||||
const canvasTop = canvasRect?.top ?? 0;
|
||||
const centerX = window.innerWidth / 2 - canvasLeft;
|
||||
const centerY = window.innerHeight / 2 - canvasTop;
|
||||
return {x: centerX, y: centerY};
|
||||
}
|
||||
|
||||
|
||||
function rotateToAngle(to: number, fromPosition?: {x: number, y: number}) {
|
||||
setRotation(to);
|
||||
const rotationDiff = to - rotation;
|
||||
|
||||
const center = getCenter();
|
||||
const center = screenCenter ?? {x: 0, y: 0};
|
||||
const cosDelta = Math.cos(rotationDiff);
|
||||
const sinDelta = Math.sin(rotationDiff);
|
||||
|
||||
@ -108,7 +96,7 @@ export const TransformProvider = ({ children }: { children: ReactNode }) => {
|
||||
function setTransform(latitude: number, longitude: number, rotationDegrees?: number, useScale ?: number) {
|
||||
const selectedRotation = rotationDegrees ? (rotationDegrees * Math.PI / 180) : rotation;
|
||||
const selectedScale = useScale ? useScale/SCALE_FACTOR : scale;
|
||||
const center = getCenter();
|
||||
const center = screenCenter ?? {x: 0, y: 0};
|
||||
console.log("center", center.x, center.y);
|
||||
const newPosition = {
|
||||
x: -latitude * UP_SCALE * selectedScale,
|
||||
@ -134,16 +122,16 @@ export const TransformProvider = ({ children }: { children: ReactNode }) => {
|
||||
position,
|
||||
scale,
|
||||
rotation,
|
||||
applicationRef,
|
||||
getCenter,
|
||||
screenCenter,
|
||||
setPosition,
|
||||
setScale,
|
||||
setRotation,
|
||||
rotateToAngle,
|
||||
screenToLocal,
|
||||
localToScreen,
|
||||
setTransform
|
||||
}), [position, scale, rotation, applicationRef]);
|
||||
setTransform,
|
||||
setScreenCenter
|
||||
}), [position, scale, rotation, screenCenter]);
|
||||
|
||||
return (
|
||||
<TransformContext.Provider value={value}>
|
||||
|
@ -2,6 +2,7 @@ import { useRef, useEffect, useState } from "react";
|
||||
|
||||
import {
|
||||
Application,
|
||||
ApplicationRef,
|
||||
extend
|
||||
} from '@pixi/react';
|
||||
import {
|
||||
@ -54,7 +55,7 @@ export const RoutePreview = () => {
|
||||
|
||||
|
||||
export function RouteMap() {
|
||||
const { applicationRef, setPosition, screenToLocal, setTransform } = useTransform();
|
||||
const { setPosition, screenToLocal, setTransform, screenCenter } = useTransform();
|
||||
const {
|
||||
routeData, stationData, sightData, originalRouteData
|
||||
} = useMapData();
|
||||
@ -72,10 +73,12 @@ export function RouteMap() {
|
||||
}, [originalRouteData]);
|
||||
|
||||
useEffect(() => {
|
||||
if(!applicationRef?.current?.getCanvas() || isSetup) {
|
||||
if(isSetup || !screenCenter) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Use effect fired")
|
||||
|
||||
if (
|
||||
originalRouteData?.center_latitude === originalRouteData?.center_longitude &&
|
||||
originalRouteData?.center_latitude === 0
|
||||
@ -96,6 +99,7 @@ export function RouteMap() {
|
||||
y: -(boundingBox.from.y + boundingBox.to.y) / 2
|
||||
};
|
||||
setPosition(newCenter);
|
||||
console.log("Taking easy way out", originalRouteData)
|
||||
setIsSetup(true);
|
||||
}
|
||||
} else if (
|
||||
@ -103,15 +107,18 @@ export function RouteMap() {
|
||||
originalRouteData?.center_longitude
|
||||
) {
|
||||
const coordinates = coordinatesToLocal(originalRouteData?.center_latitude, originalRouteData?.center_longitude);
|
||||
|
||||
setTransform(
|
||||
coordinates.x,
|
||||
coordinates.y,
|
||||
originalRouteData?.rotate,
|
||||
originalRouteData?.scale_min
|
||||
);
|
||||
console.log("Setup complete")
|
||||
setIsSetup(true);
|
||||
}
|
||||
}, [points, originalRouteData?.center_latitude, originalRouteData?.center_longitude, originalRouteData?.rotate, applicationRef?.current?.getCanvas(), isSetup]);
|
||||
}, [points, originalRouteData?.center_latitude, originalRouteData?.center_longitude, originalRouteData?.rotate, isSetup, screenCenter]);
|
||||
|
||||
|
||||
if (!routeData || !stationData || !sightData) {
|
||||
console.error("routeData, stationData or sightData is null");
|
||||
@ -122,7 +129,6 @@ export function RouteMap() {
|
||||
return (
|
||||
<div style={{width: "100%", height:"100%"}} ref={parentRef}>
|
||||
<Application
|
||||
ref={applicationRef}
|
||||
resizeTo={parentRef}
|
||||
background="#fff"
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user