Vibe Coding 构建个人品牌作品集:Next.js + Framer Motion 滚动叙事实践

2026.07.19·10 分钟阅读Vibe Coding

项目背景

作为一名 Java 后端开发者 + Vibe Coding 实践者,我需要一个个人主页来展示作品和能力——既能拿来接外包时给客户看,也能在面试时让面试官快速了解我。传统的做法是:找设计师出稿 → 前端开发 → 联调 → 测试 → 部署,周期至少 2 周。而且我的 UI 设计能力不是强项,独立设计难以达到外包级视觉品质。

这个矛盾让我决定用 Vibe Coding 工作流来挑战:能不能用 AI 辅助编程,在 3 天内交付一个既有视觉冲击力又有技术深度的个人作品集?

技术选型

选型阶段我对比了三套方案:

  • 方案 A:HTML + CSS + Vanilla JS。最轻量,但动画能力和交互复杂度有限,难以实现复杂的滚动叙事效果。
  • 方案 B:Vue + GSAP。动画能力强,但 GSAP 授权在商业外包场景有合规风险。
  • 方案 C:Next.js + Tailwind + Framer Motion。React 生态成熟,Next.js 静态生成 SEO 友好,Tailwind 效率高,Framer Motion 声明式动画接口对 AI 生成非常友好。
  • 最终选择方案 C。回头看,这个选择非常正确——Framer Motion 的 useScroll + useTransform + useSpring 构成了整个滚动叙事引擎的支柱。

    滚动叙事引擎

    作品集页面需要在用户滚动时驱动 4 阶段叙事:业务点亮 → 技术轮盘 → 难点展开 → 成果大数字。每个阶段包含独立动画且需平滑过渡。

    直接使用 scroll 事件监听有两个问题:帧率抖动和阶段衔接生硬。Framer Motion 的 useScroll 获取页面滚动进度(0-1),配合 useTransform 映射到 4 个触发区间。每阶段内部用 useSpring(damping=20) 做弹性过渡:

  • 业务阶段: staggerChildren 交错节点入场
  • 技术轮盘: rotate(360° × progress) 驱动旋转
  • 难点卡片: whileInView 触发展开
  • 大数字: framer-motion animate 从 0 计数到目标值
  • 所有动画通过 requestAnimationFrame 调度,最终达到 60fps 流畅。

    DAG 自动布局引擎

    医疗平台项目中 16 个业务节点分 6 层,节点间含跨层依赖。手写布局坐标会导致连边交叉严重、节点碰撞。我不想引入 dagre/d3-dag 等重量级布局库来增加包体积。

    于是自研了四步布局算法:

    1. 拓扑排序确定每节点所在层(0-5)

    2. 同层内按 order 排序

    3. BFS 遍历检测并修正跨层边交叉

    4. 动态计算 x/y 坐标

    整算法 80 行 TypeScript,零外部依赖,渲染用悬垂曲线贝塞尔连线避免节点遮挡。

    踩坑记录

    最大的坑是 Framer Motion 的 layoutId 动画。项目选择器切换时,我用了 layoutId 来做平滑过渡动画,但当切换的项目从有 bizNodes 变为空(bizNodes:[])时,AnimatePresence 的 exit 动画和 layoutId 的 enter 动画会产生冲突,导致 DAG 区域闪现。

    解决办法:业务流舞台根据 hasBiz 条件渲染,整个 div 用 key={projectIndex} 强制重新挂载,而不是在内部做条件显隐。

    另外一个坑是 useScroll 的 target ref。当 sticky 控制栏通过条件渲染出现/消失时,它会改变轨道在文档流中的位置,导致滚动进度跳跃。后来改为控制栏始终占位渲染(仅切换 opacity),彻底解决。

    总结

    3 天从 PRD 到交付,包含完整的滚动叙事、DAG 可视化、交互博客、响应式适配,代码覆盖率 85%。这次实验验证了 Vibe Coding 工作流在中等复杂度前端项目上的可行性——关键不在于 AI 写了多少代码,而在于人如何设计 Prompt 和架构约束,让 AI 的输出始终在可控范围内。