framer-motion动画技巧全解析:nextjs-portfolio中variants、useInView与交错入场的完整指南

发布时间:2026/8/25 9:40:38
framer-motion动画技巧全解析:nextjs-portfolio中variants、useInView与交错入场的完整指南 framer-motion动画技巧全解析nextjs-portfolio中variants、useInView与交错入场的完整指南【免费下载链接】nextjs-portfolioportfolio website in nextjs 13项目地址: https://gitcode.com/gh_mirrors/ne/nextjs-portfolionextjs-portfolio是一个用 Next.js 13 Tailwind CSS 打造的高颜值个人作品集网站。它最大的亮点就是用framer-motion这套 React 动画库让页面拥有了丝滑的缩放入场、滚动触发和卡片交错入场效果。本文带你完整拆解其中 3 个核心技巧variants 动画状态、useInView 视口检测与交错入场Stagger效果零基础也能看懂 快速上手如何安装 framer-motion 动画想在自己的 Next.js 项目里复刻这套动效只需一步npm install framer-motion在 package.json 中可以看到本项目使用的版本是framer-motion^10.16.1。安装完成后把普通标签换成motion提供的组件如motion.div、motion.li动画能力就自动解锁了。 小贴士使用motion组件的文件顶部记得加use client因为动画依赖浏览器环境。 技巧一用 variants 定义可复用的动画状态variants变体是 framer-motion 的核心概念把从哪来、到哪去的动画状态写成一份配置组件只需要切换状态名即可。HeroSection缩放淡入的经典写法在 src/app/components/HeroSection.jsx 中首屏的文字和人物图都用motion.div包裹initial{{ opacity: 0, scale: 0.5 }} animate{{ opacity: 1, scale: 1 }} transition{{ duration: 0.5 }}意思是初始透明且缩小到 50%入场时恢复为完全不透明、正常大小整个过程 0.5 秒——一个轻盈的弹出效果。TabButton切换按钮下的动态下划线更妙的是 src/app/components/TabButton.jsx。这里把 variants 真正用出了状态机的味道const variants { default: { width: 0 }, active: { width: calc(100% - 0.75rem) }, };default状态下下划线宽度为 0看不见切换到active时宽度平滑展开到几乎整行按钮下方那条会生长出来的紫色下划线就这么诞生了 技巧二useInView 让动画只在滚动到视图时播放如果所有元素在页面加载时就动完了用户滚动时反而看不到任何效果。useInView就是解决这个问题的钩子判断元素是否进入浏览器视口。在 src/app/components/ProjectsSection.jsx 中const ref useRef(null); const isInView useInView(ref, { once: true }); // ... ul ref{ref} motion.li animate{isInView ? animate : initial}三个关键点要点说明useRef(null)创建一个引用稍后绑定到ul上useInView(ref, { once: true })监听该元素是否进入视口once: true表示只触发一次避免来回滚动反复播放animate{isInView ? animate : initial}在视口内播放animate状态否则保持initial✨ 技巧三交错入场——让卡片依次排队登场项目列表区域是全文最出彩的动效6 张项目卡片不是同时出现而是像多米诺骨牌一样依次上浮入场。这靠的就是交错延迟Stagger Delay。在 src/app/components/ProjectsSection.jsx 中const cardVariants { initial: { y: 50, opacity: 0 }, // 初始下沉50px且透明 animate: { y: 0, opacity: 1 }, // 入场回到原位并显形 }; // 渲染时 transition{{ duration: 0.3, delay: index * 0.4 }}delay: index * 0.4是灵魂所在第 1 张卡片延迟 0 秒第 2 张延迟 0.4 秒第 3 张延迟 0.8 秒……每张都晚一点出场形成流畅的波浪节奏 framer-motion 动画参数速查表参数作用本项目中的例子opacity透明度0 透明 → 1 不透明淡入淡出scale缩放比例Hero 区 0.5 → 1 放大登场x/y水平 / 垂直位移卡片从下方 50px 处上浮duration动画时长秒0.3s / 0.5sdelay延迟启动秒交错入场的关键width宽度Tab 下划线生长效果 新手常见问题Qvariants 和直接写initial/animate有什么区别A直接写适合一次性动画variants 把状态命名成对象方便在多个animate值之间切换如 TabButton 的active/default也便于父组件统一编排子动画。Q为什么useInView要加once: trueA不加的话每次滚出再滚回视口都会重播动画容易让用户感到页面在抽搐加once: true后只播一次体验更从容。Q交错延迟设多大合适A经验值是 0.1s ~ 0.5s 起步。延迟太大如每张 1s 以上后面的卡片要等很久才出现太小则交错感不明显。✅ 总结nextjs-portfolio 用不到 10 行核心动画代码就为静态页面注入了生命力variants—— 把动画状态写成可复用的配置Hero 缩放入场与 Tab 下划线都靠它useInView—— 滚动到哪儿、动画播到哪儿once: true避免重复触发交错入场——delay: index * 0.4一行代码让项目卡片依次排队登场。照着这三个技巧你的下一个 Next.js 项目也能拥有同样高级的动效 ✨【免费下载链接】nextjs-portfolioportfolio website in nextjs 13项目地址: https://gitcode.com/gh_mirrors/ne/nextjs-portfolio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考