phylab-home/app/page.tsx
2025-08-20 13:31:55 +08:00

485 lines
30 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import dynamic from "next/dynamic";
import { motion } from "framer-motion";
import { Cpu, CircuitBoard, Sparkles, Atom, Waves, Camera, Brain } from "lucide-react";
import Link from "next/link";
import clsx from "clsx";
const Scene = dynamic(() => import("@/components/Scene"), { ssr: false });
// 已移除浮动花哨徽章组件,保留简洁风格
const moduleLinks = [
{ title: "力学实验模块", href: "#mechanics", icon: Waves, desc: "单摆精密测量 / 大摆角与阻尼修正 / 傅科摆进动 / 多参数智能拟合" },
{ title: "电路实验模块", href: "#circuit", icon: CircuitBoard, desc: "YOLO 电路识别 → 拓扑重建 → 虚拟仿真 → AI 智能辅导闭环" },
{ title: "电磁学实验模块", href: "#electromag", icon: Atom, desc: "气垫导轨 + 视觉测量 + BO/RL 迭代优化电磁能量转换效率" },
{ title: "光学实验模块", href: "#optics", icon: Camera, desc: "分光计视觉十字像追踪 + PID/步骤引导提升调节精度与效率" },
];
export default function Home() {
return (
<main className="relative w-full h-full text-slate-100 overflow-x-hidden">
{/* 3D Background */}
<Scene />
{/* Hero Section */}
<section className="snap-section min-h-screen relative flex flex-col items-center justify-center px-6 pt-24 text-center">
<div className="absolute inset-0 pointer-events-none bg-[radial-gradient(circle_at_40%_30%,rgba(59,130,246,0.25),transparent_65%)]" />
<motion.h1
initial={{ opacity: 0, y: 40 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 1 }}
className="text-5xl md:text-7xl font-bold leading-tight gradient-text drop-shadow-lg tracking-tight"
>
AI视觉驱动的智慧物理实验创新平台
</motion.h1>
<motion.p
initial={{ opacity: 0, y: 40 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 1, delay: 0.3 }}
className="mt-8 max-w-3xl mx-auto text-lg md:text-xl leading-relaxed text-slate-300"
>
AI + CVWeb端轻量化
</motion.p>
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.45 }}
className="mt-10 flex flex-wrap items-center justify-center gap-4"
>
<Link href="/expo" className="group relative">
<span className="inline-flex items-center gap-2 rounded-full bg-gradient-to-r from-sky-600/80 to-cyan-500/70 px-6 py-3 text-sm font-semibold tracking-wide text-white shadow-lg shadow-sky-900/30 backdrop-blur-md transition hover:from-sky-500 hover:to-cyan-400 focus:outline-none focus:ring-2 focus:ring-sky-400/70">
<Sparkles className="w-4 h-4" />
</span>
<span className="pointer-events-none absolute -inset-px rounded-full border border-sky-300/30 group-hover:border-cyan-200/40 transition" />
</Link>
</motion.div>
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.6, type: "spring" }}
className="mt-14 flex flex-wrap justify-center gap-6"
>
{moduleLinks.map((m) => (
<Link key={m.title} href={m.href}>
<motion.div
whileHover={{ y: -6, boxShadow: "0 12px 40px -8px rgba(56,189,248,0.4)" }}
whileTap={{ scale: 0.95 }}
className={clsx(
"relative group rounded-xl px-6 py-5 w-64 overflow-hidden cursor-pointer transition-all card-hover",
"panel"
)}
>
<div className="relative flex items-center gap-3">
<m.icon className="w-7 h-7 text-slate-200" />
<h3 className="font-semibold tracking-wide text-base text-slate-100">{m.title}</h3>
</div>
<p className="relative mt-3 text-xs leading-relaxed text-slate-400 min-h-12">{m.desc}</p>
<div className="relative mt-4 flex items-center gap-2 text-[10px] text-slate-400">
<Sparkles className="w-4 h-4 text-slate-500" />
</div>
</motion.div>
</Link>
))}
</motion.div>
</section>
{/* Architecture Section */}
<section id="architecture" className="snap-section relative py-28 px-6 md:px-16">
<div className="max-w-7xl mx-auto">
<div className="grid md:grid-cols-2 gap-20 items-start">
<div>
<motion.h2
initial={{ opacity: 0, x: -40 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.8 }}
className="text-3xl md:text-5xl font-bold gradient-text mb-8"
>
</motion.h2>
<motion.div
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
viewport={{ once: true }}
transition={{ delay: 0.3, duration: 0.8 }}
className="space-y-6 text-sm leading-relaxed text-slate-400"
>
<p className="indent-4">
AI + CV/
</p>
<div className="grid grid-cols-2 gap-5 pt-4">
{[
{ t: "CV 感知", d: "Hough/轮廓/YOLO 追踪摆球、电路元件识别" },
{ t: "AI 分析", d: "非线性拟合 / 符号回归 / 误差自适应校正" },
{ t: "智能交互", d: "Agent 提示步骤 / 故障诊断 / 学习引导" },
{ t: "可视化", d: "WebGL & 交互式参数变化动态渲染" },
].map((b) => (
<div key={b.t} className="relative p-4 rounded-lg panel card-hover">
<h4 className="text-sm font-semibold mb-1 text-slate-200">{b.t}</h4>
<p className="text-xs text-slate-500 leading-snug">{b.d}</p>
<span className="absolute -top-px -left-px h-2 w-2 bg-gradient-to-br from-sky-400 to-fuchsia-500 rounded-full shadow" />
</div>
))}
</div>
</motion.div>
</div>
<div className="relative">
<div className="relative panel rounded-2xl p-10 space-y-8 card-hover">
<h3 className="text-xl font-semibold flex items-center gap-3 text-slate-100"><Sparkles className="text-sky-400" />AI + CV</h3>
<ul className="space-y-4 text-xs leading-relaxed text-slate-400">
<li>CV /姿/YOLO + </li>
<li>AI </li>
<li>线WebAssembly/OpenCV.js TensorFlow.js / WebGPU </li>
<li></li>
<li> Web / / </li>
</ul>
<div className="grid grid-cols-3 gap-4 pt-2 text-center text-[10px] font-mono">
{['Capture','Track','Fit','Correct','Explain','Feedback'].map(s => (
<div key={s} className="p-2 rounded-md bg-[#18202b] border border-[#223042]">
<span className="text-[10px] text-slate-300 font-semibold tracking-wide">{s}</span>
</div>
))}
</div>
</div>
</div>
</div>
</div>
</section>
{/* Module Overview Section */}
<section id="modules" className="snap-section relative py-24 px-6 md:px-16">
<div className="max-w-7xl mx-auto">
<motion.h2
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.8 }}
className="text-3xl md:text-5xl font-bold gradient-text mb-14 text-center"
>
&
</motion.h2>
<div className="grid lg:grid-cols-4 md:grid-cols-2 gap-10">
{moduleLinks.map((m) => (
<Link key={m.title} href={m.href} className="group block relative">
<div className="relative rounded-xl panel p-6 h-full flex flex-col overflow-hidden card-hover">
<div className="flex items-center gap-3">
<m.icon className="w-6 h-6 text-slate-200" />
<h3 className="font-semibold text-sm tracking-wide text-slate-100">{m.title}</h3>
</div>
<p className="mt-3 text-[11px] leading-relaxed text-slate-500 flex-1">{m.desc}</p>
<div className="mt-4 text-[10px] tracking-wider text-slate-500 flex items-center gap-2">
<Sparkles className="w-4 h-4 text-slate-600" />
</div>
</div>
</Link>
))}
</div>
<div className="mt-20 grid md:grid-cols-3 gap-8">
{[
{ icon: Waves, t: '统一“AI + CV”技术底座', d: '共享采集 → 追踪 → 拟合 → 校正 → 交互流水线,跨力学 / 电学 / 电磁 / 光学复用。' },
{ icon: Camera, t: '纯 Web 端实时推理', d: '浏览器即可完成摄像采集 + OpenCV.js 处理 + 轻量模型推理,无需本地安装。' },
{ icon: Brain, t: '智能实验助手', d: '误差分析、参数解释、探索性提问引导,支持未来符号回归自动方程发现。' },
].map(card => (
<div key={card.t} className="relative rounded-xl panel p-6 overflow-hidden card-hover">
<card.icon className="w-8 h-8 text-slate-300 mb-4" />
<h4 className="font-semibold text-sm mb-2 text-slate-200">{card.t}</h4>
<p className="text-[11px] leading-relaxed text-slate-500">{card.d}</p>
</div>
))}
</div>
</div>
</section>
{/* Mechanics Module Detail */}
<section id="mechanics" className="snap-section relative py-28 px-6 md:px-16">
<div className="max-w-6xl mx-auto space-y-10">
<h2 className="text-3xl md:text-4xl font-bold gradient-text"> · & </h2>
<div className="grid lg:grid-cols-3 gap-10">
<div className="lg:col-span-2 space-y-8">
<div className="space-y-4 text-sm text-slate-400 leading-relaxed">
<p> / / / <span className="text-slate-200"></span> <span className="text-slate-200"> + </span> </p>
<ul className="list-disc pl-5 space-y-2">
<li><span className="text-slate-200"></span> </li>
<li><span className="text-slate-200"></span> +1.7% +3.7%</li>
<li><span className="text-slate-200"></span> 线 γ & Q</li>
<li><span className="text-slate-200"></span> 1.9%</li>
</ul>
<p className="text-slate-300">AI 线</p>
<ol className="list-decimal pl-5 space-y-1 text-xs md:text-sm">
<li>CV HSV + + (30240fps)</li>
<li>LSTM / </li>
<li>线 + (A, γ, ω<sub>d</sub>, φ)</li>
<li> / / </li>
<li>gγQ</li>
</ol>
</div>
<div className="grid md:grid-cols-3 gap-4 text-[11px]">
{[
{ k: 'g 相对误差', v: '0.43%' },
{ k: 'Q 典型值', v: '≈ 900+' },
{ k: '进动偏差', v: '≈ 1.9%' },
{ k: 'FPS 需求', v: '≥ 60 fps' },
{ k: '拟合优度 R²', v: '≈ 1.0000' },
{ k: 'γ 精度', v: '1e-4 s⁻¹ 级' },
].map(x => (
<div key={x.k} className="panel p-3 rounded-lg flex flex-col">
<span className="text-slate-500">{x.k}</span>
<span className="text-slate-200 font-semibold text-sm">{x.v}</span>
</div>
))}
</div>
</div>
<div className="space-y-6 text-xs md:text-sm text-slate-500">
<h3 className="text-slate-200 font-semibold"> & </h3>
<ul className="list-disc pl-5 space-y-2">
<li>- &gt;50% + </li>
<li> g ~0.5% </li>
<li> γ + </li>
<li> + </li>
</ul>
<h3 className="text-slate-200 font-semibold pt-4"></h3>
<p> / / 线</p>
</div>
</div>
</div>
</section>
{/* Circuit Module Detail */}
<section id="circuit" className="snap-section relative py-28 px-6 md:px-16">
<div className="max-w-6xl mx-auto space-y-10">
<h2 className="text-3xl md:text-4xl font-bold gradient-text"> · </h2>
<div className="grid lg:grid-cols-3 gap-10">
<div className="lg:col-span-2 space-y-6 text-sm text-slate-400">
<p> / / <span className="text-slate-200"> 仿 AI </span> </p>
<h3 className="text-slate-200 font-semibold"></h3>
<ol className="list-decimal pl-5 space-y-1 text-xs md:text-sm">
<li> / </li>
<li>YOLO + ( &gt; 90%)</li>
<li>线 + + </li>
<li>JSON(, , ) </li>
<li> / & </li>
</ol>
<h3 className="text-slate-200 font-semibold pt-2">AI (Agent)</h3>
<ul className="list-disc pl-5 space-y-1 text-xs md:text-sm">
<li></li>
<li> / / ( &gt;85%)</li>
<li> + </li>
<li></li>
</ul>
<h3 className="text-slate-200 font-semibold pt-2"></h3>
<p> / / </p>
</div>
<div className="space-y-6 text-xs md:text-sm text-slate-500">
<h4 className="text-slate-200 font-semibold"></h4>
<ul className="list-disc pl-5 space-y-2">
<li> + </li>
<li>线</li>
<li> </li>
</ul>
<h4 className="text-slate-200 font-semibold pt-4"></h4>
<div className="grid grid-cols-2 gap-3 text-[11px]">
{[
{ k: '识别置信度', v: '>90%' },
{ k: '故障诊断', v: '>85%' },
{ k: '转换延迟', v: '< 3 s' },
{ k: '数据格式', v: 'JSON 标准化' },
].map(x => (
<div key={x.k} className="panel p-3 rounded-lg"><p className="text-slate-500">{x.k}</p><p className="text-slate-200 font-semibold">{x.v}</p></div>
))}
</div>
</div>
</div>
</div>
</section>
{/* Electromagnetics Module Detail */}
<section id="electromag" className="snap-section relative py-28 px-6 md:px-16">
<div className="max-w-6xl mx-auto space-y-10">
<h2 className="text-3xl md:text-4xl font-bold gradient-text"> · </h2>
<div className="grid lg:grid-cols-3 gap-10">
<div className="lg:col-span-2 space-y-6 text-sm text-slate-400">
<p> + + 线 + + <span className="text-slate-200"> / </span> </p>
<h3 className="text-slate-200 font-semibold"> & </h3>
<ul className="list-disc pl-5 space-y-1 text-xs md:text-sm">
<li> + HSV + </li>
<li> / 线</li>
<li> 0.1 px</li>
</ul>
<h3 className="text-slate-200 font-semibold pt-2"></h3>
<ol className="list-decimal pl-5 space-y-1 text-xs md:text-sm">
<li> Δt τ U/I</li>
<li>V / I / dI/dt / 线</li>
<li> v<sub>out</sub>/ /</li>
<li> 58 </li>
<li> 3050 </li>
</ol>
<h3 className="text-slate-200 font-semibold pt-2"></h3>
<p> <span className="text-slate-200"></span>线</p>
</div>
<div className="space-y-6 text-xs md:text-sm text-slate-500">
<h4 className="text-slate-200 font-semibold"></h4>
<ul className="list-disc pl-5 space-y-2">
<li> / </li>
<li>60 fps 16.67ms </li>
<li>RL </li>
</ul>
<div className="grid grid-cols-2 gap-3 text-[11px] pt-2">
{[
{ k: '像素精度', v: '0.1 px' },
{ k: '收敛迭代', v: '≤ 50' },
{ k: '参数维度', v: '3~5 可扩展' },
{ k: '奖励形式', v: '可插拔' },
].map(x => (
<div key={x.k} className="panel p-3 rounded-lg"><p className="text-slate-500">{x.k}</p><p className="text-slate-200 font-semibold">{x.v}</p></div>
))}
</div>
</div>
</div>
</div>
</section>
{/* Optics Module Detail */}
<section id="optics" className="snap-section relative py-28 px-6 md:px-16">
<div className="max-w-6xl mx-auto space-y-10">
<h2 className="text-3xl md:text-4xl font-bold gradient-text"> · </h2>
<div className="grid lg:grid-cols-3 gap-10">
<div className="lg:col-span-2 space-y-6 text-sm text-slate-400">
<p> / / <span className="text-slate-200"> + / + PID </span></p>
<h3 className="text-slate-200 font-semibold"></h3>
<ul className="list-disc pl-5 space-y-1 text-xs md:text-sm">
<li>HSV + </li>
<li> </li>
<li> </li>
<li>PID P + I + D </li>
</ul>
<h3 className="text-slate-200 font-semibold pt-2"></h3>
<div className="grid grid-cols-3 gap-4 text-[11px]">
{[
{ k: '光轴垂直度误差', v: '±1 (改进自 ±5)' },
{ k: '光谱测量误差', v: '0.8% (原 3%)' },
{ k: '调节练习次数', v: '3 次 (原 8 次)' },
].map(x => (
<div key={x.k} className="panel p-3 rounded-lg"><p className="text-slate-500">{x.k}</p><p className="text-slate-200 font-semibold">{x.v}</p></div>
))}
</div>
<p> / </p>
</div>
<div className="space-y-6 text-xs md:text-sm text-slate-500">
<h4 className="text-slate-200 font-semibold"></h4>
<ul className="list-disc pl-5 space-y-2">
<li> / </li>
<li></li>
<li> + 姿</li>
</ul>
</div>
</div>
</div>
</section>
{/* Innovation Section */}
<section id="innovation" className="snap-section relative py-28 px-6 md:px-16">
<div className="max-w-6xl mx-auto space-y-10">
<h2 className="text-3xl md:text-4xl font-bold gradient-text"></h2>
<div className="grid md:grid-cols-2 gap-12 text-sm text-slate-400">
<div className="space-y-5">
<h3 className="text-slate-200 font-semibold"></h3>
<ul className="list-disc pl-5 space-y-2">
<li> Web / / / </li>
<li> / / / </li>
<li>AI 穿 </li>
<li> & 便广</li>
</ul>
<h3 className="text-slate-200 font-semibold pt-4"></h3>
<p>CV AI / / Agent </p>
</div>
<div className="space-y-5">
<h3 className="text-slate-200 font-semibold"></h3>
<ol className="list-decimal pl-5 space-y-2">
<li>YOLO + </li>
<li> (g, γ, Q) & </li>
<li> 仿</li>
<li>BO / RL </li>
<li> / </li>
<li> / / </li>
</ol>
<h3 className="text-slate-200 font-semibold pt-4"></h3>
<p>AI </p>
</div>
</div>
</div>
</section>
{/* Outlook Section */}
<section id="outlook" className="snap-section relative py-28 px-6 md:px-16">
<div className="max-w-5xl mx-auto space-y-8 text-sm text-slate-400">
<h2 className="text-3xl md:text-4xl font-bold gradient-text"></h2>
<p>AI + CV <span className="text-slate-200"> / / / </span> g 0.43%</p>
<ul className="list-disc pl-5 space-y-2">
<li><span className="text-slate-200"></span> (SINDy / AI Feynman) </li>
<li><span className="text-slate-200"></span> </li>
<li><span className="text-slate-200"></span> AI </li>
<li><span className="text-slate-200"></span> </li>
</ul>
<p> <span className="text-slate-200"> AI </span></p>
</div>
</section>
{/* Web Deployment Section */}
<section id="web" className="snap-section relative py-24 px-6 md:px-16">
<div className="max-w-7xl mx-auto">
<div className="grid lg:grid-cols-2 gap-20 items-center">
<div>
<motion.h2
initial={{ opacity: 0, x: -40 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.8 }}
className="text-3xl md:text-5xl font-bold gradient-text mb-8"
>
Web
</motion.h2>
<ul className="space-y-4 text-sm text-slate-300/90 leading-relaxed">
<li> / PC / / </li>
<li>TensorFlow.js / WebGPU 使 YOLO / Transformer </li>
<li> CVgetUserMedia + OpenCV.js </li>
<li> & API </li>
<li> / / </li>
</ul>
</div>
<div className="relative">
<div className="relative panel p-10 rounded-2xl card-hover">
<h3 className="font-semibold mb-6 flex items-center gap-2 text-slate-100"><Cpu className="text-sky-400" /> </h3>
<div className="grid grid-cols-2 gap-4 text-[11px] font-mono">
{[
'WebGL','WebGPU','WASM','OpenCV.js','TensorFlow.js','MediaPipe','YOLOv8-tiny','Edge Agent'
].map(s => (
<div key={s} className="p-2 rounded-md bg-[#18202b] border border-[#223042] text-center text-slate-300 tracking-wide">
{s}
</div>
))}
</div>
<div className="mt-8 relative">
<div className="relative h-40 w-40 mx-auto rounded-full flex items-center justify-center bg-[#18202b] border border-[#223042]">
<div className="text-center text-[10px] leading-relaxed text-slate-400">
<span className="text-slate-200 font-semibold">Edge Inference Core</span><br />
Capture Track Fit Insight
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Footer */}
<footer className="relative py-14 text-center text-[11px] text-slate-500">
<div className="max-w-5xl mx-auto px-6">
<p>© {new Date().getFullYear()} AI · · </p>
</div>
</footer>
</main>
);
}