"use client"; import { useState, useRef, useEffect } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { X } from "lucide-react"; import clsx from "clsx"; // 展台四模块视频配置(请将对应 mp4/webm 文件放入 public/videos/ 下) const videos = [ { key: "mechanics", title: "力学 · 单摆高精度测量", src: "/videos/mechanics.mp4", desc: "CV 追踪 + AI 拟合:g 误差压至 0.43%,提取阻尼 γ 与品质因数 Q。探究傅科摆效应。" }, { key: "circuit", title: "电路 · 实物 → 虚拟转换", src: "/videos/circuit.mp4", desc: "YOLO 识别元件与连线,自动生成可交互虚拟电路 + AI 问答辅导。" }, { key: "electromag", title: "电磁 · 能量转换优化", src: "/videos/electromag.mp4", desc: "视觉 + 单片机测电磁转换效率 + 未来 BO/RL 迭代脉冲参数,提高加速/制动能量效率。" }, { key: "optics", title: "光学 · 分光计智能辅助", src: "/videos/optics.mp4", desc: "十字像追踪 + 分步引导 + PID 调节。" } ]; interface VideoStateRef { currentTime: number; wasPlaying: boolean; } export default function ExpoPage() { const [active, setActive] = useState(null); const timeRefs = useRef>({}); const containerRefs = useRef>({}); // 记录时间用于在放大时继续播放(非严格同步,够展示用) const handleBeforeExpand = (key: string) => { const vid = containerRefs.current[key]; if (vid) { timeRefs.current[key] = { currentTime: vid.currentTime, wasPlaying: !vid.paused }; } setActive(key); }; const handleRestore = () => { setActive(null); }; // 在放大的 video 元素上恢复播放进度 const expandedVideoRef = useRef(null); useEffect(() => { if (active && expandedVideoRef.current) { const state = timeRefs.current[active]; if (state) { try { expandedVideoRef.current.currentTime = state.currentTime; } catch (_) { /* Safari 某些情况下可能阻止精确跳转,忽略 */ } if (state.wasPlaying) expandedVideoRef.current.play().catch(() => {}); } } }, [active]); // ESC 关闭 useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === "Escape" && active) setActive(null); }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [active]); return (
{/* 2x2 全屏栅格 */}
{videos.map(v => ( handleBeforeExpand(v.key)} > ))}
{active && ( <> {videos.filter(v => v.key === active).map(v => (
))} )}
); }