From 487341aba4760e62a47f96ffefc219e3a3b24967 Mon Sep 17 00:00:00 2001 From: SII-123qwe-asd-ux <1120240220@mail.nankai.edu.cn> Date: Thu, 13 Nov 2025 23:59:29 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=A8=20feat:=20Add=20Xyzen=20chat=20la?= =?UTF-8?q?nding=20page=20with=20HeroParallax=20and=20CTA=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ♻️ refactor:Create /chat route with HeroParallax component for product showcase - Add products.ts with Xyzen product data - Implement chat page layout with animated parallax effect - Add CTA button linking to Bohrium Xyzen application - Update Navbar to include Projects menu with 5 ScienceOL products - Add dark mode styling for better visual appearance - Integrate React Router with new /chat route in router.tsx --- web/index.css | 118 +++++++++- web/src/app/chat/page.tsx | 37 +++ web/src/app/chat/products.ts | 95 ++++++++ web/src/app/navbar/Navbar.tsx | 13 +- web/src/app/navbar/Projects.tsx | 285 +++++++++++++++--------- web/src/app/navbar/Tutorials.tsx | 119 +++++----- web/src/components/ui/hero-parallax.tsx | 155 +++++++++++++ web/src/lib/utils.ts | 6 + web/src/router.tsx | 2 + 9 files changed, 672 insertions(+), 158 deletions(-) create mode 100644 web/src/app/chat/page.tsx create mode 100644 web/src/app/chat/products.ts create mode 100644 web/src/components/ui/hero-parallax.tsx create mode 100644 web/src/lib/utils.ts diff --git a/web/index.css b/web/index.css index a64ab83..ca79076 100644 --- a/web/index.css +++ b/web/index.css @@ -1,4 +1,5 @@ @import "tailwindcss"; +@import "tw-animate-css"; @source "node_modules/@sciol/xyzen/dist/xyzen.css"; @custom-variant dark (&:where(.dark, .dark *)); @@ -196,10 +197,125 @@ body { border-radius: 0.5rem; } - @media (prefers-reduced-motion: reduce) { .animate-sheen { animation: none; opacity: .25; } } + +@theme inline { + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +:root { + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); +} + +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.205 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.205 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.922 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.556 0 0); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/web/src/app/chat/page.tsx b/web/src/app/chat/page.tsx new file mode 100644 index 0000000..452fd45 --- /dev/null +++ b/web/src/app/chat/page.tsx @@ -0,0 +1,37 @@ +'use client'; + +import { HeroParallax } from '@/components/ui/hero-parallax'; +import { products } from './products'; + +export default function ChatPage() { + return ( +
+ 点击下方按钮,立即体验 Xyzen AI Agent +
++ Xyzen 是一个 Agent, 他是一个会创造 Agent 的 Agent。 Xyzen + 可以为你开启一个通往Agent 与MCP无限可能的大门。 +
++
点击下方按钮,立即体验 Xyzen AI Agent
+
Xyzen 是一个 Agent, 他是一个会创造 Agent 的 Agent。 Xyzen 可以为你开启一个通往Agent 与MCP无限可能的大门。
diff --git a/web/src/hooks/useTheme.ts b/web/src/hooks/useTheme.ts new file mode 100644 index 0000000..3e2f4b0 --- /dev/null +++ b/web/src/hooks/useTheme.ts @@ -0,0 +1,28 @@ +'use client'; + +import { useUI } from '@/hooks/useUI'; +import { useEffect, useState } from 'react'; + +export function useTheme() { + const { theme } = useUI(); + const [isDark, setIsDark] = useState(false); + + useEffect(() => { + // 根据主题设置 isDark + const updateIsDark = () => { + setIsDark(theme === 'dark' || (theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)); + }; + + updateIsDark(); + + // 监听系统主题变化(当主题设置为 system 时) + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + mediaQuery.addEventListener('change', updateIsDark); + + return () => { + mediaQuery.removeEventListener('change', updateIsDark); + }; + }, [theme]); + + return { isDark }; +} From ecea6aea113e92d2bafedf8588dd2422f0313fd1 Mon Sep 17 00:00:00 2001 From: SII-123qwe-asd-ux <1120240220@mail.nankai.edu.cn> Date: Tue, 16 Dec 2025 11:42:00 +0800 Subject: [PATCH 3/4] feat: Add 3D Lab interactive visualization with device components - Create interactive 3D lab scene using React Three Fiber - Implement 12+ device components (liquid handler, microscope, centrifuge, AGV robot, etc.) - Add device detail modal with 3D preview and specifications - Support device animations and interactive highlighting - Include device information database - Update navbar with 3D Lab navigation links - Enhance scrollbar styling for better UX --- web/index.css | 30 + web/src/app/3D_lab/DeviceDetailModal.tsx | 341 +++++++++ web/src/app/3D_lab/InteractiveLabScene.tsx | 805 +++++++++++++++++++++ web/src/app/3D_lab/deviceComponents.tsx | 505 +++++++++++++ web/src/app/3D_lab/deviceInfo.ts | 118 +++ web/src/app/3D_lab/page.tsx | 224 ++++++ web/src/app/3D_lab/styles.css | 104 +++ web/src/app/navbar/Navbar.tsx | 4 +- web/src/app/navbar/NavbarFullWidth.tsx | 27 +- web/src/app/navbar/Projects.tsx | 13 +- web/src/router.tsx | 2 + 11 files changed, 2161 insertions(+), 12 deletions(-) create mode 100644 web/src/app/3D_lab/DeviceDetailModal.tsx create mode 100644 web/src/app/3D_lab/InteractiveLabScene.tsx create mode 100644 web/src/app/3D_lab/deviceComponents.tsx create mode 100644 web/src/app/3D_lab/deviceInfo.ts create mode 100644 web/src/app/3D_lab/page.tsx create mode 100644 web/src/app/3D_lab/styles.css diff --git a/web/index.css b/web/index.css index 0e92213..32af51e 100644 --- a/web/index.css +++ b/web/index.css @@ -110,6 +110,36 @@ scrollbar-color: rgba(156, 163, 175, 0.4) transparent; } +/* Webkit 浏览器滚动条样式补充 */ +.custom-scrollbar::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +.custom-scrollbar::-webkit-scrollbar-track { + background: transparent; + border-radius: 4px; +} + +.custom-scrollbar::-webkit-scrollbar-thumb { + background-color: rgba(156, 163, 175, 0.4); + border-radius: 4px; + border: 2px solid transparent; + background-clip: padding-box; +} + +.custom-scrollbar::-webkit-scrollbar-thumb:hover { + background-color: rgba(156, 163, 175, 0.6); +} + +.dark .custom-scrollbar::-webkit-scrollbar-thumb { + background-color: rgba(156, 163, 175, 0.5); +} + +.dark .custom-scrollbar::-webkit-scrollbar-thumb:hover { + background-color: rgba(156, 163, 175, 0.7); +} + /* 全局背景色设置,防止滚动时出现白色 */ html, body { diff --git a/web/src/app/3D_lab/DeviceDetailModal.tsx b/web/src/app/3D_lab/DeviceDetailModal.tsx new file mode 100644 index 0000000..7e9349f --- /dev/null +++ b/web/src/app/3D_lab/DeviceDetailModal.tsx @@ -0,0 +1,341 @@ +'use client'; + +import LogoLoading from '@/components/basic/loading'; +import { XMarkIcon } from '@heroicons/react/24/outline'; +import { OrbitControls, PerspectiveCamera } from '@react-three/drei'; +import { Canvas } from '@react-three/fiber'; +import { Suspense } from 'react'; +import { getDeviceInfo } from './deviceInfo'; + +// 导入设备组件 +import { + AGVRobot, + Beaker, + Centrifuge, + LiquidHandlerModel, + Microscope, + Monitor, + PetriDishStack, + PipetteRack, + ReagentBottle, + ReagentRack, + SampleRack, + StorageCabinet, +} from './deviceComponents'; + +interface DeviceDetailModalProps { + deviceId: string; + onClose: () => void; + isAnimating?: boolean; + onToggleAnimation?: () => void; +} + +// 设备渲染映射 +function DeviceRenderer({ + deviceId, + isAnimating = false, +}: { + deviceId: string; + isAnimating?: boolean; +}) { + const position: [number, number, number] = [0, 0, 0]; + + switch (deviceId) { + case 'liquid-handler': + return ( ++ 🖱️ 拖动旋转 | 滚轮缩放 | 右键平移 +
++ {deviceInfo.nameEn} +
++ {deviceInfo.description} +
++ {deviceInfo.usage} +
++ 正在演示设备工作流程 +
+ )} ++ Interactive Laboratory Visualization +
+{item.description}
diff --git a/web/src/app/navbar/Projects.tsx b/web/src/app/navbar/Projects.tsx index 6db9cb6..14cdb78 100644 --- a/web/src/app/navbar/Projects.tsx +++ b/web/src/app/navbar/Projects.tsx @@ -134,7 +134,7 @@ import { // RectangleGroupIcon, } from '@heroicons/react/24/outline'; -import { SiUnrealengine,SiUnity,SiProton,SiX,SiStmicroelectronics } from 'react-icons/si'; +import { SiUnrealengine,SiUnity,SiProton,SiX,SiStmicroelectronics,SiBlender } from 'react-icons/si'; import { GitHubIcon } from '@/assets/SocialIcons'; import NavbarFullWidth from './NavbarFullWidth'; import type { NavbarFullWidthProps } from './types'; @@ -165,7 +165,7 @@ const resources = [ { name: 'Anti', description: '用于实验室模拟的3D数字孪生平台', - href: `/deepmd-kit`, + href: `/3D_lab`, icon: SiUnity, color:'text-rose-500', }, @@ -175,7 +175,14 @@ const resources = [ href: `/deepmd-kit`, icon: SiUnrealengine, color:'text-emerald-500', - } + }, + { + name:'3D Lab', + description: '展示3D实验室的实验仪器和场景', + href: `/3D_lab`, + icon: SiBlender, + color:'text-purple-500', + }, ]; const callsToAction = [ diff --git a/web/src/router.tsx b/web/src/router.tsx index 8c9ac81..c0cd42c 100644 --- a/web/src/router.tsx +++ b/web/src/router.tsx @@ -1,4 +1,5 @@ import { BrowserRouter, Route, Routes } from 'react-router-dom'; +import Lab3DPage from './app/3D_lab/page'; import App from './app/App'; import ChatPage from './app/chat/page'; import { EnvironmentPage } from './app/dashboard/environment'; @@ -22,6 +23,7 @@ export default function Router() {