h3R3 名片网站项目
该项目是一个基于 React 和 Vite 构建的现代 Web 应用,采用了 TypeScript 进行开发,利用 Tailwind CSS 进行样式设计,并通过 Framer Motion 实现了流畅的交互动画。
本项目只是作为和弦对偶像喜爱的杰作
1. 项目目录结构
项目采用了标准的 Vite + React 结构,核心代码集中在 src 目录下,静态资源管理清晰。
h3R3/
├── public/ # 静态资源目录
│ └── assets/
│ ├── Imager/ # 画廊图片
│ ├── Lyrics/ # LRC 歌词文件
│ ├── Music/ # 音频文件 (.flac)
│ └── ZhuanJiFengMian/ # 专辑封面
├── src/
│ ├── components/ # 核心组件库
│ │ ├── GallerySection.tsx # 画廊展示模块
│ │ ├── HeroSection.tsx # 首页视觉模块
│ │ ├── MusicPlayerSection.tsx # 音乐播放器核心逻辑
│ │ └── ProfileSection.tsx # 个人简介与专辑列表
│ ├── utils/
│ │ └── assets.ts # 资源动态加载工具
│ ├── App.tsx # 主入口与路由控制器
│ ├── main.tsx # React 渲染入口
│ └── index.css # 全局样式 (Tailwind 指令)
├── vite.config.ts # Vite 构建配置
└── package.json # 依赖管理
2. 核心模块解析
2.1 主控制器:App.tsx
App.tsx 是整个应用的“大脑”,它没有使用传统的 react-router-dom 进行路由跳转,而是实现了一个自定义的全屏滚动(Full-page Scroll)系统。
核心逻辑:
使用
useState管理当前激活的板块索引currentSection。监听
wheel滚轮事件,通过计算deltaY来判断用户的滚动意图。使用 CSS
transform: translateY实现平滑的页面切换效果。
// src/App.tsx 核心片段
const App: React.FC = () => {
const [currentSection, setCurrentSection] = useState(0);
const [currentAlbum, setCurrentAlbum] = useState<{ path: string; name: string } | null>(null);
// 滚轮事件处理
useEffect(() => {
const handleWheel = (e: WheelEvent) => {
// 特殊处理 Gallery 内部滚动逻辑
if (currentSection === 3 && galleryRef.current) {
// ... 判断是否滚动到底部或顶部,决定是否阻止默认行为
} else {
e.preventDefault(); // 阻止默认滚动,接管为全屏切换
}
// 切换逻辑(防抖处理)
if (Math.abs(e.deltaY) > 20 && !isScrolling.current) {
if (e.deltaY > 0 && currentSection < totalSections - 1) {
setCurrentSection(prev => prev + 1);
} else if (e.deltaY < 0 && currentSection > 0) {
setCurrentSection(prev => prev - 1);
}
}
};
window.addEventListener('wheel', handleWheel, { passive: false });
return () => window.removeEventListener('wheel', handleWheel);
}, [currentSection]);
return (
<main className="w-full bg-black h-screen overflow-hidden relative">
<div
className="transition-transform duration-700 ease-in-out"
style={{ transform: `translateY(-${currentSection * 100}vh)` }}
>
{/* 各个全屏组件 */}
<HeroSection />
<ProfileSection onAlbumClick={handleAlbumClick} />
<MusicPlayerSection currentAlbum={currentAlbum} />
<GallerySection />
</div>
</main>
);
};
2.2 音乐播放核心:MusicPlayerSection.tsx
这是逻辑最复杂的组件,负责音频播放、歌词解析和状态同步。
关键功能:LRC 歌词解析
通过正则表达式将 .lrc 文件内容解析为可用的 JS 对象数组。
// src/components/MusicPlayerSection.tsx
const parseLrcLine = (line: string) => {
// 匹配格式:[00:12.34]歌词内容
const match = line.match(/\[(\d{2}):(\d{2})\.(\d{2,3})\](.*)/);
if (!match) return null;
const minutes = parseInt(match[1], 10);
const seconds = parseInt(match[2], 10);
const milliseconds = parseInt(match[3], 10);
// 转换为秒数,用于播放器同步
const time = minutes * 60 + seconds + milliseconds / (match[3].length === 3 ? 1000 : 100);
return { time, text: match[4].trim() };
};
2.3 资源动态加载:utils/assets.ts
利用 Vite 的 import.meta.glob 特性,实现了自动化的资源导入,无需手动 import 每一个文件。
// src/utils/assets.ts
// 自动扫描目录下的所有封面图片
const albumCoverModules = import.meta.glob('../../public/assets/ZhuanJiFengMian/*.{jpg,jpeg,png,webp}', { eager: true });
export const albumList = Object.entries(albumCoverModules).map(([path, mod]: [string, any]) => {
const filename = path.split('/').pop() || '';
// 解码文件名作为专辑名称
const name = decodeURIComponent(filename.split('.')[0]);
return {
name,
coverPath: mod.default
};
});
3. 路由与数据流架构
3.1 路由实现
本项目没有使用 URL 路由(如 /about),而是采用了视差滚动单页应用(SPA) 模式。
优点:沉浸感强,转场流畅,像是在浏览一张精心设计的海报。
实现:通过
App.tsx中的transform属性控制视口位置,模拟页面跳转。
3.2 数据流与状态管理
虽然项目中安装了 zustand,但核心逻辑目前主要依赖 React Context 思想的“状态提升(State Lifting)”。
数据流向图:

交互触发:用户在
ProfileSection点击专辑。状态提升:事件冒泡至
App,更新currentAlbum状态,并自动切换currentSection至播放器页面。单向数据流:
MusicPlayerSection接收新的currentAlbum属性,触发useEffect重新加载音频和歌词。
4. 性能与安全优化
资源按需加载:
歌词文件 (
.lrc) 仅在切歌时通过fetch动态请求,避免首屏加载过多文本数据。图片资源通过 Vite 的 glob 导入,构建时自动处理哈希和路径。
交互性能:
使用
requestAnimationFrame或 React 的useRef(在滚动监听中) 来避免频繁触发重渲染。滚动事件通过
isScrolling标志位实现了防抖(Debounce),防止一次滚轮滑动触发多次翻页。
动画优化:
使用
framer-motion的whileInView和viewport={{ once: true }},确保画廊图片仅在首次进入视口时渲染动画,减少 GPU 消耗。
5. 项目总结
h3R3 个人主页是一个典型的高视觉冲击力 Web 项目。源码结构清晰,充分利用了 Vite 的构建特性简化了资源管理。
亮点总结:
交互细腻:自定义的滚轮阻尼效果和全屏切换逻辑,提供了原生 App 般的体验。
自动化程度高:通过文件名自动生成专辑列表和歌词关联,极大降低了后续维护成本(只需上传文件即可更新内容)。
组件解耦:播放器逻辑与 UI 分离,状态由上层容器管理,易于扩展。
该项目非常适合作为个人作品集或艺术家展示页的开发模板。
6. 项目预览
在线地址:
图片预览:



