xiaokeer-discover
基于 Next.js 16 构建的现代个人作品集与知识库网站,集成 MDX 内容管理、Canvas 动画特效与响应式设计。
Next.jsReactTypeScriptTailwind CSSMDXCanvas
项目简介
xiaokeer-discover 是一个现代化的个人作品集与知识库网站,采用 Next.js 16 App Router 架构构建。项目集成了 MDX 内容管理系统、Canvas 动画特效、响应式设计等技术特性,实现了高性能、可扩展的个人品牌展示平台。
主要特性
- 🚀 Next.js 16 + React 19:采用最新的 App Router 架构,支持 React Server Components,显著减少客户端 JavaScript 体积
- 📝 MDX 内容系统:通过 Velite 实现类型安全的 MDX 内容管理,支持文章、项目、文档三种内容类型
- 🎨 Canvas 动画特效:首页集成蜂巢技能展示、弹幕系统、礼花动画等 Canvas 动画效果
- 🌙 JetBrains 深色主题:精心设计的深色主题配色,紫粉渐变光晕背景,营造专业视觉效果
- 📱 响应式设计:完整的移动端适配,包括移动端导航、自适应布局等
- ⚡ 极致性能:静态生成 + 增量静态再生成(ISR),配合 Turbopack 开发服务器
技术栈
| 类别 | 技术 |
|---|---|
| 框架 | Next.js 16 (App Router) |
| UI 库 | React 19 |
| 语言 | TypeScript (strict mode) |
| 样式 | Tailwind CSS v4 |
| UI 组件 | shadcn/ui (Radix UI) |
| 图标 | Lucide React + Devicon |
| 内容管理 | Velite (MDX) |
| 动画 | GSAP + Canvas API |
| 包管理 | pnpm |
| 部署 | Vercel |
技术亮点
亮点一:Velite 驱动的类型安全内容管理
项目采用 Velite 作为 MDX 内容处理引擎,实现了编译时类型安全的内容管理:
- 多集合支持:定义了
posts(文章)、projects(项目)、docs(文档)三种内容集合,每种集合有独立的 schema 定义 - Schema 校验:使用 Velite 的
s构建器定义字段类型、约束条件,确保内容数据的类型安全 - 自动路由生成:通过
transform函数自动生成 slug 和 permalink,简化路由配置 - 静态资源处理:自动处理 MDX 中的图片资源,输出到指定目录并生成哈希文件名
// velite.config.ts - 项目集合定义示例
const projects = defineCollection({
name: "Project",
pattern: "projects/**/*.mdx",
schema: s
.object({
slug: s.path(),
title: s.string().max(99),
description: s.string().max(999).optional(),
date: s.isodate(),
tags: s.array(s.string()).default([]),
repo: s.string().url().optional(),
demo: s.string().url().optional(),
body: s.mdx(),
})
.transform((data) => ({
...data,
slug: data.slug.split("/").pop()!,
permalink: `/projects/${data.slug.split("/").pop()!}`,
})),
});
亮点二:Canvas 蜂巢技能展示动画
首页实现了基于 Canvas 的蜂巢技能展示组件,具有以下技术特点:
- 六边形网格算法:通过数学计算生成蜂巢状六边形网格布局,支持动态响应容器尺寸变化
- 流光动画效果:多条流光路径在六边形网格中穿梭,经过的技能图标会高亮显示
- 性能优化策略:
- 使用
requestAnimationFrame实现流畅的 60fps 动画 - React 状态更新频率控制(每 10 帧更新一次),避免频繁重渲染
- Canvas 与 DOM 分层:Canvas 负责绘制六边形边框和流光,HTML 元素负责技能图标显示
- 使用
- Intersection Observer 懒加载:组件仅在进入视口时启动动画,离开视口时自动停止,节省计算资源
// 帧率控制与状态更新优化
const onFrame = useCallback(
(currentTime: number) => {
const deltaTime = currentTime - lastTimeRef.current;
const frameInterval = 1000 / TARGET_FPS;
if (deltaTime >= frameInterval) {
// 绘制逻辑...
frameCountRef.current++;
if (frameCountRef.current % UPDATE_INTERVAL === 0) {
setHighlightMap(newHighlight); // 每10帧更新一次React状态
}
}
frameIdRef.current = requestAnimationFrame(onFrame);
},
[draw],
);
亮点三:高性能弹幕系统
实现了两种弹幕组件:文字弹幕和梗图弹幕,均采用纯 CSS 动画驱动:
- 固定速度计算:根据容器宽度和文本长度动态计算动画时长,确保所有弹幕以相同速度移动
- 对象池模式:预创建弹幕对象,通过
active标志控制显示/隐藏,避免频繁创建/销毁 DOM 元素 - 数量限制:最大同时显示 25 条弹幕,超出时停止创建新弹幕
- 视口感知:结合
useInViewHook,仅在组件可见时运行动画
// 弹幕速度计算逻辑
const DANMAKU_SPEED = 80; // 像素/秒
const totalDistance = containerWidth + estimatedTextWidth + 100;
const duration = totalDistance / DANMAKU_SPEED; // 动态计算动画时长
亮点四:礼花筒动画系统
首页两侧的礼花动画是一个完整的粒子系统实现:
- 粒子池管理:预分配 500 个粒子对象,通过对象池复用避免 GC 压力
- 礼花筒状态机:实现了完整的礼花筒动画状态机(进入→摇晃→发射→后坐→等待→退出)
- 物理模拟:包含重力、空气阻力、摇摆等物理效果
- 多形状支持:支持正方形、三角形、圆形、菱形、星形、矩形六种粒子形状
- 响应式控制:仅在桌面端(≥1024px)启用动画,移动端自动禁用以节省性能
亮点五:自定义 Hooks 封装
项目封装了多个可复用的自定义 Hooks:
- useInView:基于 Intersection Observer API 的滚动触发 Hook,支持阈值配置和单次触发模式
- useAnimationFrame:可控帧率的 requestAnimationFrame 封装,支持动态启停
// useInView Hook 使用示例
const { ref, isInView } = useInView({ threshold: 0.1 });
return (
<div ref={ref}>
{isInView && <LazyAnimationComponent />}
</div>
);
亮点六:MDX 内容渲染器
实现了自定义的 MDX 内容渲染组件,为 MDX 元素添加统一样式:
- 动态组件编译:使用
new Function将 Velite 编译后的 MDX 代码转换为 React 组件 - 样式组件映射:为 h1-h6、p、a、code、pre、ul、ol、blockquote 等元素定义统一样式
- 代码高亮支持:通过 Shiki 和 rehype 插件实现代码语法高亮
项目截图

相关链接
- 代码仓库:GitHub
- 在线演示:https://xiaokeer.zeabur.app