diff --git a/web/src/components/layout/app-top-nav.tsx b/web/src/components/layout/app-top-nav.tsx index 13595fe48..25a45840d 100644 --- a/web/src/components/layout/app-top-nav.tsx +++ b/web/src/components/layout/app-top-nav.tsx @@ -1,5 +1,5 @@ import { Infinity as InfinityIcon } from "lucide-react"; -import { Fragment, useEffect, useState, type ReactNode } from "react"; +import { Fragment, useEffect, useRef, useState, type ReactNode } from "react"; import { Link, useLocation, useNavigate } from "react-router"; import { ModelSetupGuide } from "@/components/layout/model-setup-guide"; @@ -12,6 +12,11 @@ export function AppWorkspaceShell({ children }: { children: ReactNode }) { const { pathname } = useLocation(); const navigate = useNavigate(); const [mobileSidebarExpanded, setMobileSidebarExpanded] = useState(false); + const scrollRef = useRef(null); + const [scrollState, setScrollState] = useState({ + hasTopFade: false, + hasBottomFade: false, + }); const hideChrome = pathname.startsWith("/admin") || /^\/canvas\/[^/]+/.test(pathname); const spatialWorkbench = isSpatialWorkbenchPath(pathname); const creationWorkspace = pathname === "/create"; @@ -19,6 +24,16 @@ export function AppWorkspaceShell({ children }: { children: ReactNode }) { const activeToolSlug = navigationTools.some((tool) => tool.slug === slug) ? (slug as NavigationToolSlug) : undefined; const visibleNavigationTools = spatialWorkbench ? navigationTools : navigationTools.filter((tool) => tool.section === "创作空间"); + const handleScroll = () => { + const element = scrollRef.current; + if (!element) return; + const { scrollTop, scrollHeight, clientHeight } = element; + setScrollState({ + hasTopFade: scrollTop > 0, + hasBottomFade: scrollTop + clientHeight < scrollHeight - 1, + }); + }; + useEffect(() => { const handleWorkspaceNavigation = (rawEvent: Event) => { const event = rawEvent as CustomEvent<{ to?: string }>; @@ -30,6 +45,11 @@ export function AppWorkspaceShell({ children }: { children: ReactNode }) { return () => window.removeEventListener("workspace:navigate", handleWorkspaceNavigation); }, [navigate]); + useEffect(() => { + // 初始化滚动状态 + handleScroll(); + }, [visibleNavigationTools.length, mobileSidebarExpanded]); + return ( <>
@@ -49,7 +69,15 @@ export function AppWorkspaceShell({ children }: { children: ReactNode }) {
-