You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Framer Motion优化React导航栏动画的技术问询

解决方案:实现固定左侧+逐个从左到右入场的导航栏动画

你的核心问题在于:

  • 导航容器宽度扩展时,链接容器跟着整体移动,导致视觉上呈现从右侧滑入的效果
  • 所有链接同时显示,没有实现从左到右的序列入场动画

以下是具体改进方案:

关键修改点

  • 固定链接容器位置:让链接始终锚定在左侧,不受导航容器宽度变化的影响
  • 添加序列动画:给每个链接设置独立的位移动画,通过staggerChildren实现逐个从左到右显示
  • 优化容器动画逻辑:调整导航容器的过渡曲线,移除不必要的属性动画干扰

修改后的完整代码

import Link from "next/link";
import React, { useState } from "react";
import HamburgerIcon from "./icons/HamburgerIcon";
import { motion } from "framer-motion";

const MenuDesktop = () => {
  const [isHovered, setIsHovered] = useState(false);

  const navVariants = {
    initial: { width: "5rem", zIndex: 0 },
    hover: { width: "100%", zIndex: 1 },
  };

  // 单个链接的动画变体:从左侧偏移位置入场
  const linkItemVariants = {
    initial: { x: -20, opacity: 0 },
    hover: { x: 0, opacity: 1, transition: { duration: 0.4 } }
  };

  // 链接容器的变体:控制子元素的序列动画
  const linkContainerVariants = {
    initial: { opacity: 0 },
    hover: { 
      opacity: 1,
      transition: { 
        staggerChildren: 0.1, // 每个链接间隔0.1秒入场
        delayChildren: 0.2 // 等待导航容器展开一点后再开始链接动画
      }
    }
  };

  const iconVariants = {
    initial: { opacity: 1 },
    hover: { opacity: 0, transition: { duration: 0.3 } },
  };

  return (
    <div className="flex p-0.5 h-20 rounded-15px bg-cc-invert justify-center items-stretch overflow-hidden">
      <div className="relative">
        <motion.nav
          className="flex relative h-full overflow-hidden" // 改为overflow-hidden,避免滚动条
          initial="initial"
          animate={isHovered ? "hover" : "initial"}
          variants={navVariants}
          transition={{
            width: { duration: 0.75, ease: "easeInOut" },
          }}
          onHoverStart={() => setIsHovered(true)}
          onHoverEnd={() => setIsHovered(false)}
        >
          {/* 链接容器:设置flex-shrink:0固定位置,避免被挤压 */}
          <motion.div
            className="font-dmMono tracking-wider text-cc-dark-brown flex items-center gap-2 text-xs uppercase pl-4 bg-cc-invert flex-shrink-0"
            variants={linkContainerVariants}
            initial="initial"
            animate={isHovered ? "hover" : "initial"}
          >
            {/* 每个链接单独用motion包裹,应用单个动画变体 */}
            <motion.div variants={linkItemVariants}>
              <Link className="px-2 whitespace-nowrap" href="/development">
                Development
              </Link>
            </motion.div>
            <motion.div variants={linkItemVariants}>
              <Link className="px-2 whitespace-nowrap" href="/energo">
                Energo
              </Link>
            </motion.div>
            <motion.div variants={linkItemVariants}>
              <Link className="px-2 whitespace-nowrap" href="/company">
                Company
              </Link>
            </motion.div>
            <motion.div variants={linkItemVariants}>
              <Link className="px-2 whitespace-nowrap" href="/news">
                News
              </Link>
            </motion.div>
            <motion.div variants={linkItemVariants}>
              <Link className="px-2 whitespace-nowrap" href="/career">
                Career
              </Link>
            </motion.div>
          </motion.div>
        </motion.nav>
        <motion.div
          className="absolute top-7 right-7 flex items-center cursor-pointer z-10" // 提高z-index确保在导航上层
          initial="initial"
          animate={isHovered ? "hover" : "initial"}
          variants={iconVariants}
        >
          <HamburgerIcon className="h-5 cursor-pointer" />
        </motion.div>
      </div>
      <Link
        href="/"
        className="font-dmMono tracking-wider text-cc-dark-brown flex items-center justify-center p-4 bg-cc-light-brown rounded-15px"
      >
        <span className="uppercase text-xs px-2">Contact</span>
      </Link>
    </div>
  );
};

export default MenuDesktop;

核心优化说明

  1. 固定链接位置:给链接容器添加flex-shrink-0,确保它不会随着导航容器的宽度变化被挤压,始终锚定在左侧。
  2. 序列入场动画:
    • 单个链接的linkItemVariants设置初始向左偏移+透明,hover时回到原位并显示
    • 链接容器通过staggerChildren实现子元素逐个动画,delayChildren让导航容器先展开一部分再启动链接动画,视觉更自然
  3. 容器动画优化:移除导航容器的opacity动画,避免和链接的透明度过渡冲突;将overflow-auto改为overflow-hidden,消除不必要的滚动条。
  4. 汉堡图标调整:提高图标z-index,确保在导航展开过程中可正常交互,同时缩短动画时长让隐藏效果更流畅。

内容的提问来源于stack exchange,提问作者Filip Kuna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:28:10