Files
shanghai-residences/src/pages/Home.tsx
T
zhongyidianandClaude Opus 4.8 73f6df92ce chore: 更新素材和组件优化
- 更新展品图片(鲁迅/毛泽东/孙中山/黄炎培/聂耳/张乐平故居)
- 新增点击查看图标、报纸素材
- 优化视频组件、拼图组件、展品组件
- 更新陈云音频资源
- 新增输入验证文档和工具函数
- 组件布局和动画优化

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 21:50:40 +08:00

105 lines
3.5 KiB
TypeScript

import { useState } from 'react'
import { AnimatePresence, motion } from 'framer-motion'
import { getBackgroundImage, getPublicPath, getStaticImage } from '@/lib/utils'
import { Image, Video } from '@/components'
import { useNavigate } from 'react-router-dom'
const INTRO_VIEWED_KEY = 'home-intro-viewed'
const Home = () => {
const navigate = useNavigate()
const [showIntroVideo, setShowIntroVideo] = useState(false)
const [introViewed, setIntroViewed] = useState(
() => localStorage.getItem(INTRO_VIEWED_KEY) === 'true'
)
const handleIntroClick = () => {
setShowIntroVideo(true)
if (!introViewed) {
setIntroViewed(true)
localStorage.setItem(INTRO_VIEWED_KEY, 'true')
}
}
return (
<div
className="w-full h-full bg-cover bg-center bg-no-repeat"
style={{ backgroundImage: getBackgroundImage('home/首页底图') }}
>
{/* 课程简介 */}
<AnimatePresence>
{!showIntroVideo && (
<motion.div
className="absolute right-0 top-0"
initial={{ opacity: 0, scale: 0.92, x: 24 }}
animate={{ opacity: 1, scale: 1, x: 0 }}
exit={{ opacity: 0, scale: 0.92, x: 24 }}
transition={{ duration: 0.22, ease: 'easeOut' }}
>
<div className="relative">
<Image src={getStaticImage('home/课程简介')} button onClick={handleIntroClick} />
{!introViewed && (
<Image
className="absolute right-full top-1/2 z-20 mr-2 h-28 w-34 -translate-y-1/2 animate-finger-shake pointer-events-none"
src={getStaticImage('components/点击查看')}
/>
)}
</div>
</motion.div>
)}
</AnimatePresence>
<Image
onClick={() => {
navigate('/menu')
}}
className="absolute bottom-38 left-1/2 -translate-1/2"
button
src={getStaticImage('home/首页-进入')}
/>
<AnimatePresence>
{showIntroVideo && (
<motion.div
className="absolute inset-0 z-50 flex items-center justify-center bg-black/65"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.28, ease: 'easeInOut' }}
>
<motion.div
className="relative w-full h-full overflow-hidden bg-black"
initial={{ opacity: 0, scale: 1.04 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 1.02 }}
transition={{ duration: 0.32, ease: [0.25, 0.46, 0.45, 0.94] }}
>
<Video
className="w-full h-full"
src={getPublicPath('video/intro.mp4')}
autoPlay
controls
/>
<motion.div
className="absolute right-0 top-0 z-10"
initial={{ opacity: 0, scale: 0.92, x: 24 }}
animate={{ opacity: 1, scale: 1, x: 0 }}
exit={{ opacity: 0, scale: 0.92, x: 24 }}
transition={{ duration: 0.22, ease: 'easeOut', delay: 0.08 }}
>
<Image
src={getStaticImage('home/点击关闭')}
button
onClick={() => setShowIntroVideo(false)}
/>
</motion.div>
</motion.div>
</motion.div>
)}
</AnimatePresence>
</div>
)
}
export default Home