如何用Framer Motion实现向下滚动时汉堡按钮从右侧滑出?
实现向下滚动时汉堡按钮从右侧滑出的Framer Motion修改方案
我希望实现向下滚动时汉堡按钮(Hamburger button)从右侧滑出的效果,当前已使用Framer Motion的useScroll、useTransform等API编写了Header组件代码,但未达到预期效果,附上现有代码,请教如何修改以实现需求。
现有代码:
"use client"; import { motion, useScroll, useTransform } from "framer-motion"; export default function Header() { let { scrollY } = useScroll(); let y = useTransform(scrollY, [0, 1], ["0px", "200px"]); return ( <header> <div className="header-inner"> <a href="/"><img alt="Logo" src="/logo.png" /></a> <nav> <ul> <li><a href="/about" className="nav-item">About</a></li> <li><a href="/careers" className="nav-item">Careers</a></li> <motion.li initial={{ right: 200 }} style={{ y }} transition={{ ease: "easeInOut" }} > <button aria-label="Hamburger" className="nav-button"> Collapse button </button> </motion.li> </ul> </nav> </div> </header> ); }
问题分析与修改方案
现有代码存在3个核心问题:
- 错误使用
y属性控制垂直位移,需求是水平方向的右侧滑出/滑入,应改为控制right或x属性 useTransform的滚动区间[0,1]不合理,仅滚动1px就完成动画,视觉上几乎无效果- 未给元素添加定位规则,导致
right属性无法生效
修改后的代码
"use client"; import { motion, useScroll, useTransform } from "framer-motion"; export default function Header() { const { scrollY } = useScroll(); // 滚动0-100px时,按钮从右侧200px(隐藏)滑到0px(显示) const right = useTransform(scrollY, [0, 100], ["200px", "0px"]); return ( <header> <div className="header-inner"> <a href="/"><img alt="Logo" src="/logo.png" /></a> <nav> <ul> <li><a href="/about" className="nav-item">About</a></li> <li><a href="/careers" className="nav-item">Careers</a></li> <motion.li initial={{ right: "200px" }} style={{ right, position: "relative" }} transition={{ ease: "easeInOut" }} > <button aria-label="Hamburger" className="nav-button"> Collapse button </button> </motion.li> </ul> </nav> </div> </header> ); }
关键修改说明
- 替换
y变换为right变换,匹配右侧滑动的需求 - 调整
useTransform的滚动区间为[0, 100],让动画在滚动100px的过程中平滑完成 - 添加
position: relative,确保right属性能正确控制元素的水平位置 - 初始状态与变换起始值保持一致,保证按钮默认隐藏在右侧,滚动时逐渐滑入可视区域
如果需要实现滚动时按钮滑出右侧隐藏的效果,只需将useTransform的目标值反转:
const right = useTransform(scrollY, [0, 100], ["0px", "200px"]);
同时将初始值改为initial={{ right: "0px" }}即可。
内容的提问来源于stack exchange,提问作者Baljka Gan
相关产品推荐
相关产品推荐

