diff --git a/src/app/ClientRoot.tsx b/src/app/ClientRoot.tsx index 2b2846f2..d7950a33 100644 --- a/src/app/ClientRoot.tsx +++ b/src/app/ClientRoot.tsx @@ -5,14 +5,28 @@ import MobileUIHider from "@/components/ui/MobileUIHider"; import { Footer } from "@/components/ui"; import { BrowZarrPopover } from "./BrowZarrPopover"; import { VersionSelector } from "@/components/ui"; +import Link from "next/link"; +import ThemeSwitch from "@/components/ui/ThemeSwitch"; +import HomeButton from "@/components/ui/HomeButton"; +import GithubButton from "@/components/ui/GithubButton"; export default function ClientRoot({ children }: { children: React.ReactNode }) { return ( -
- + {/* left menu */} +
+ + + docs + +
+ {/* right menu */} +
+ + +
{children} diff --git a/src/app/docs/page.tsx b/src/app/docs/page.tsx new file mode 100644 index 00000000..0533c9c4 --- /dev/null +++ b/src/app/docs/page.tsx @@ -0,0 +1,97 @@ +import Link from "next/link"; + +export const metadata = { + title: "browzarr.io/docs", + description: "Tutorial and documentation for Browzarr", +}; + +import { FaStar, FaThumbtack, FaGithub } from "react-icons/fa"; +import { IoCloseCircleSharp, IoImage } from "react-icons/io5"; +import { RxReset } from "react-icons/rx"; +import { FaPlus, FaMinus } from "react-icons/fa"; +import { HiHomeModern } from "react-icons/hi2"; +import { HiInformationCircle } from "react-icons/hi"; +import { MdFlipCameraIos, MdOutlineRocketLaunch, MdOutlineSwapVert, MdOutlineSquare } from "react-icons/md"; +import { FaCarSide } from "react-icons/fa6"; +import { VscGraphLine } from "react-icons/vsc"; +import { BsMoonStarsFill, BsSunFill, BsFillQuestionCircleFill, BsTags } from "react-icons/bs"; +import { FaCheck, FaPlay, FaPause, FaForwardStep, FaBackwardStep } from "react-icons/fa6"; +import { LuChevronDown, LuSettings } from "react-icons/lu"; +import { PiMathOperationsBold, PiPlayPauseFill, PiSphereThin, PiCubeLight } from "react-icons/pi"; +import { CiUndo } from "react-icons/ci"; +import { CgMenuGridO } from "react-icons/cg"; +import { TbDatabasePlus, TbVariable } from "react-icons/tb"; + +export default function DocsPage() { + return ( +
+

Browzarr’s features

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

Getting started

+

+ Open a dataset via the UI, pick a variable and use the controls to pan, zoom and animate. + This page is a good place to add step-by-step guides and screenshots. +

+
+ +
+

Animation

+
    +
  1. Click the play icon in the top-right to open animation controls.
  2. +
  3. Use the slider or FPS controls to adjust playback.
  4. +
  5. Use "Grab Prev/Next Chunk" to load additional time chunks.
  6. +
+
+ +
+

Contributing

+

+ Add docs in this folder (src/app/docs). For larger docs, add sub-pages or a layout at src/app/docs/layout.tsx. +

+
+ +
+ + ← Back to app + +
+
+ ); +} \ No newline at end of file diff --git a/src/components/plots/CountryBorders.tsx b/src/components/plots/CountryBorders.tsx index 86a626bf..b8622f50 100644 --- a/src/components/plots/CountryBorders.tsx +++ b/src/components/plots/CountryBorders.tsx @@ -29,14 +29,10 @@ function Spherize([lon, lat] : [number, number]){ function Borders({features}:{features: any}){ const {xRange, yRange, plotType, borderColor, lonExtent, latExtent, lonResolution, latResolution} = usePlotStore(useShallow(state => ({ - xRange: state.xRange, - yRange: state.yRange, - plotType: state.plotType, - borderColor: state.borderColor, - lonExtent: state.lonExtent, - latExtent: state.latExtent, - lonResolution: state.lonResolution, - latResolution: state.latResolution + xRange: state.xRange, yRange: state.yRange, + plotType: state.plotType, borderColor: state.borderColor, + lonExtent: state.lonExtent, latExtent: state.latExtent, + lonResolution: state.lonResolution, latResolution: state.latResolution, }))) const {flipY, shape } = useGlobalStore(useShallow(state => ({ flipY: state.flipY, @@ -52,7 +48,6 @@ function Borders({features}:{features: any}){ return [newLonBounds as [number, number], newLatBounds as [number, number]] },[latExtent, lonExtent, lonResolution, latResolution]) - const [spherize, setSpherize] = useState(false) useEffect(()=>{ @@ -192,11 +187,10 @@ const CountryBorders = () => { dataShape: state.dataShape, is4D: state.is4D }))) - const {zRange, plotType, showBorders, timeScale} = usePlotStore(useShallow(state => ({ - zRange: state.zRange, - plotType: state.plotType, - showBorders: state.showBorders, - timeScale: state.timeScale + const {zRange, plotType, showBorders, timeScale, rotateFlat, pointSize} = usePlotStore(useShallow(state => ({ + zRange: state.zRange, plotType: state.plotType, + showBorders: state.showBorders, timeScale: state.timeScale, + rotateFlat: state.rotateFlat, pointSize:state.pointSize }))) const {analysisMode, axis} = useAnalysisStore(useShallow(state => ({ analysisMode: state.analysisMode, @@ -238,10 +232,20 @@ const CountryBorders = () => { const isPC = plotType == 'point-cloud' const isFlatMap = plotType == "flat" const depthScale = dataShape[0]/dataShape[2]*timeScale + const globalScale = isPC ? dataShape[2]/500 : 1 + return( - - {coastLines && } - {borders && } + + + {coastLines && } + {borders && } + ) } diff --git a/src/components/ui/GithubButton.tsx b/src/components/ui/GithubButton.tsx new file mode 100644 index 00000000..4937c3d9 --- /dev/null +++ b/src/components/ui/GithubButton.tsx @@ -0,0 +1,23 @@ +"use client"; + +import { FaGithub } from "react-icons/fa"; +import Link from "next/link"; +import { Button } from "@/components/ui/button"; +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; + +export default function GithubButton() { + return ( + + + + + + + + github + + + ); +} \ No newline at end of file diff --git a/src/components/ui/HomeButton.tsx b/src/components/ui/HomeButton.tsx new file mode 100644 index 00000000..61a295de --- /dev/null +++ b/src/components/ui/HomeButton.tsx @@ -0,0 +1,29 @@ +"use client"; + +import { HiHomeModern } from "react-icons/hi2"; +import Link from "next/link"; +import { Button } from "@/components/ui/button"; +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; +import { usePathname } from "next/navigation"; + +export default function HomeButton() { + const pathname = usePathname(); + // Don't show Home button on home page + if (pathname === "/") { + return null; + } + return ( + + + + + + + + Home + + + ); +} \ No newline at end of file diff --git a/src/components/ui/Navbar.tsx b/src/components/ui/Navbar.tsx index b9516023..20d4b4ed 100644 --- a/src/components/ui/Navbar.tsx +++ b/src/components/ui/Navbar.tsx @@ -113,8 +113,6 @@ const Navbar = React.memo(function Navbar(){ } - -
diff --git a/src/components/ui/ThemeSwitch.tsx b/src/components/ui/ThemeSwitch.tsx index 378f3ca5..228c42be 100644 --- a/src/components/ui/ThemeSwitch.tsx +++ b/src/components/ui/ThemeSwitch.tsx @@ -36,13 +36,13 @@ const ThemeSwitch = () => { - + {current === 'dark' ? Switch to Light Mode : Switch to Dark Mode diff --git a/src/components/ui/css/Footer.css b/src/components/ui/css/Footer.css index fe2dba3e..bab0822a 100644 --- a/src/components/ui/css/Footer.css +++ b/src/components/ui/css/Footer.css @@ -73,7 +73,7 @@ } /* Responsive design for screens below 600px */ -@media (max-width: 600px) { +@media (max-width: 768px) { .footer { display: none; } diff --git a/src/components/ui/css/MainPanel.css b/src/components/ui/css/MainPanel.css index e763c4c2..2272319f 100644 --- a/src/components/ui/css/MainPanel.css +++ b/src/components/ui/css/MainPanel.css @@ -10,7 +10,7 @@ width: 60px; max-height: 500px; scroll-behavior: smooth; - right: 1.25rem; + right: 8px; top: 25vh; transform: none; user-select: none; diff --git a/src/components/ui/css/Navbar.css b/src/components/ui/css/Navbar.css index 53df5ddb..cdd0556f 100644 --- a/src/components/ui/css/Navbar.css +++ b/src/components/ui/css/Navbar.css @@ -6,7 +6,7 @@ align-content: center; left: 8px; right: auto; - top: 8px; + top: 42px; z-index: 10; user-select: none; background: var(--glass-bg);