diff --git a/src/GlobalStates/PlotStore.ts b/src/GlobalStates/PlotStore.ts index e11e4997..d88b2834 100644 --- a/src/GlobalStates/PlotStore.ts +++ b/src/GlobalStates/PlotStore.ts @@ -62,6 +62,7 @@ type PlotState ={ borderTexture: THREE.Texture | undefined; useBorderTexture: boolean; maskValue: number; + cameraPosition: THREE.Vector3; setQuality: (quality: number) => void; setTimeScale: (timeScale : number) =>void; @@ -116,6 +117,7 @@ type PlotState ={ setInterpPixels: (interpPixels: boolean) => void; setUseOrtho: (useOrtho: boolean) => void; setFillValue: (fillValue: number | undefined) => void; + setCameraPosition: (cameraPosition: THREE.Vector3) => void; } export const usePlotStore = create((set, get) => ({ @@ -180,6 +182,7 @@ export const usePlotStore = create((set, get) => ({ useBorderTexture: false, maskValue: 0, borderWidth: 0.05, + cameraPosition: new THREE.Vector3(0, 0, 5), setVTransferRange: (vTransferRange) => set({ vTransferRange }), setVTransferScale: (vTransferScale) => set({ vTransferScale }), @@ -235,5 +238,6 @@ export const usePlotStore = create((set, get) => ({ setXSlice: (xSlice) => set({ xSlice }), setInterpPixels: (interpPixels) => set({ interpPixels }), setUseOrtho: (useOrtho) => set({ useOrtho }), - setFillValue: (fillValue) => set({ fillValue }) + setFillValue: (fillValue) => set({ fillValue }), + setCameraPosition: (cameraPosition) => set({ cameraPosition }), })) \ No newline at end of file diff --git a/src/app/globals.css b/src/app/globals.css index 16c76148..30daddfe 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -85,6 +85,7 @@ --play-background: rgba(200, 200, 200, 0.8); --notice-shadow: rgb(230, 230, 230); --warning-area: rgba(255, 205, 67, 0.616); + --axis-shadow: hsla(0, 0%, 0%, 0.5); } /* Dark Theme */ @@ -144,6 +145,7 @@ --play-background: rgba(200, 200, 200, 0.8); --notice-shadow: rgb(70, 70, 70); --warning-area: rgba(255, 183, 49, 0.555); + --axis-shadow: rgb(255, 255, 255); } @layer utilities { diff --git a/src/components/plots/Plot.tsx b/src/components/plots/Plot.tsx index 7c6f008e..0d4237aa 100644 --- a/src/components/plots/Plot.tsx +++ b/src/components/plots/Plot.tsx @@ -26,10 +26,11 @@ const TransectNotice = () =>{ } const Orbiter = ({isFlat} : {isFlat : boolean}) =>{ - const {resetCamera, useOrtho, displaceSurface} = usePlotStore(useShallow(state => ({ + const {resetCamera, useOrtho, displaceSurface, cameraPosition} = usePlotStore(useShallow(state => ({ resetCamera: state.resetCamera, useOrtho: state.useOrtho, - displaceSurface: state.displaceSurface + displaceSurface: state.displaceSurface, + cameraPosition:state.cameraPosition }))) const {setCameraRef} = useImageExportStore(useShallow(state=>({setCameraRef:state.setCameraRef}))) const orbitRef = useRef(null) @@ -78,7 +79,6 @@ const Orbiter = ({isFlat} : {isFlat : boolean}) =>{ return () => cancelAnimationFrame(frameId); } },[resetCamera, isFlat]) - useEffect(()=>{ if (hasMounted.current){ let newCamera; @@ -115,6 +115,25 @@ const Orbiter = ({isFlat} : {isFlat : boolean}) =>{ } },[useOrtho]) + useEffect(()=>{ + const cam = cameraRef.current + const controls = orbitRef.current + if (cam && controls){ + const wasDamping = controls.enableDamping; + controls.enableDamping = false; + controls.update() //Need this extra update to clear the internal inertia buffer. Cant seem to access it in code. + invalidate() + cam.position.copy(cameraPosition) + cam.lookAt(new THREE.Vector3(0, 0, 0)) + //@ts-ignore the check means it is ortho + if (useOrtho) cam.updateProjectionMatrix() + else cam.updateMatrix() + controls.update() + controls.enableDamping = wasDamping + invalidate() + } + },[cameraPosition]) + return ( { + const {setCameraPosition} = usePlotStore(useShallow(state =>({ + setCameraPosition: state.setCameraPosition + }))) + + return ( +
+
+ +
setCameraPosition(new THREE.Vector3(5, 0, 0))} + onDoubleClick={()=>setCameraPosition(new THREE.Vector3(-5, 0, 0))} + > +
+
+ X +
+ +
setCameraPosition(new THREE.Vector3(0, 5, 0))} + onDoubleClick={()=>setCameraPosition(new THREE.Vector3(0, -5, 0))} + > +
+
+ Y +
+ +
setCameraPosition(new THREE.Vector3(0, 0, 5))} + onDoubleClick={()=>setCameraPosition(new THREE.Vector3(0, 0, -5))} + > +
+
+ Z +
+
+ ) +} + + diff --git a/src/components/ui/Footer.tsx b/src/components/ui/Footer.tsx index 3e1f348c..aa417697 100644 --- a/src/components/ui/Footer.tsx +++ b/src/components/ui/Footer.tsx @@ -2,9 +2,17 @@ import Image from "next/image"; import { logoBGC_MPI, logoBGC, logoMPI } from "@/assets/index"; import './css/Footer.css'; +import { useImageExportStore } from "@/GlobalStates"; +import { useShallow } from "zustand/shallow"; -const Footer = () => ( -
+const Footer = () => { + const {previewExtent} = useImageExportStore(useShallow(state => ({ + previewExtent:state.previewExtent, + }))) + return( + -); +)} export default Footer; diff --git a/src/components/ui/NavBar/Navbar.tsx b/src/components/ui/NavBar/Navbar.tsx index ced1b0fc..d55fb7e6 100644 --- a/src/components/ui/NavBar/Navbar.tsx +++ b/src/components/ui/NavBar/Navbar.tsx @@ -10,7 +10,7 @@ import { useRef, useState } from "react"; import { MdFlipCameraIos } from "react-icons/md"; import { RiCloseLargeLine, RiMenu2Line } from "react-icons/ri"; import { useShallow } from "zustand/shallow"; -import { Button } from "@/components/ui/button"; +import { Button, AxisBars } from "@/components/ui"; import { Tooltip, TooltipContent, @@ -72,6 +72,7 @@ const Navbar = React.memo(function Navbar() {
{plotOn && ( <> +