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

如何实现围绕用户头像下半部分的环形导航菜单及逐项加载动画?

实现头像下半部环形导航及加载动画

问题说明

需用<ul>和<li>构建围绕用户头像下半部分的环形导航栏,当前导航项全部显示在头像左侧;同时要实现页面加载时导航项逐个出现的动画效果。

解决方案

1. 环形布局实现(下半部分)

核心逻辑是将.navMenu设为相对定位容器,通过CSS transform: rotate() + translate() 计算每个导航项的位置,让它们分布在头像下半部分的圆弧上:

  • 把.navMenu设为相对定位,固定宽高并居中,作为导航项和头像的定位基准
  • 头像居中放置在.navMenu内部
  • 针对5个导航项,计算出不同的旋转角度,让它们均匀分布在头像下半区域的圆弧上

2. 逐个加载动画实现

通过CSS关键帧动画定义显示过渡效果,给每个导航项设置递增的动画延迟,实现依次出现的顺序动画。


修改后的代码

JSX 文件

const Profile = () => {
  const { currentUser } = useContext(AuthContext);

  // 导航项数据,便于后续扩展
  const navItems = [
    { icon: <EmailIcon />, text: "Email" },
    { icon: <EmailIcon />, text: "Email" },
    { icon: <EmailIcon />, text: "Email" },
    { icon: <EmailIcon />, text: "Email" },
    { icon: <EmailIcon />, text: "Email" },
  ];

  return (
    <div className="profile">
      <ul className="navMenu">
        <div className="avatarContainer">
          <img
            src="https://w7.pngwing.com/pngs/81/570/png-transparent-profile-logo-computer-icons-user-user-blue-heroes-logo-thumbnail.png"
            alt="用户头像"
            className="avatarPic"
          />
        </div>
        {navItems.map((item, index) => (
          <li key={index} className="navItem">
            {item.icon}
            <span className="navText">{item.text}</span>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default Profile;

SCSS 文件

.profile {
  @include themify($themes) {
    background-color: themed("bgSoft");
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;

    .navMenu {
      list-style-type: none;
      position: relative;
      width: 400px;
      height: 400px;
      padding: 0;
      margin: 0;
    }

    .avatarContainer {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 200px;
      height: 200px;

      .avatarPic {
        width: 100%;
        height: 100%;
        border-radius: 50%;
        object-fit: cover;
      }
    }

    .navItem {
      position: absolute;
      top: 50%;
      left: 50%;
      width: 95px;
      height: 95px;
      border: solid 2px black;
      border-radius: 50%;
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;
      transition: transform 0.3s ease;
      // 初始状态:透明+缩放0,用于动画
      opacity: 0;
      transform: translate(-50%, -50%) scale(0);
      animation: fadeInScale 0.5s ease forwards;

      .navIcon {
        font-size: 3.5rem;
      }

      .navText {
        position: absolute;
        bottom: -20px;
        font-size: 1rem;
        opacity: 0;
        transition: opacity 0.3s ease;
      }

      &:hover {
        transform: translate(-50%, -50%) scale(1.1);

        .navText {
          opacity: 1;
        }
      }

      // 逐个设置位置和动画延迟
      &:nth-child(2) {
        transform: translate(-50%, -50%) rotate(45deg) translateX(150px) rotate(-45deg);
        animation-delay: 0.1s;
      }
      &:nth-child(3) {
        transform: translate(-50%, -50%) rotate(90deg) translateX(150px) rotate(-90deg);
        animation-delay: 0.2s;
      }
      &:nth-child(4) {
        transform: translate(-50%, -50%) rotate(135deg) translateX(150px) rotate(-135deg);
        animation-delay: 0.3s;
      }
      &:nth-child(5) {
        transform: translate(-50%, -50%) rotate(-135deg) translateX(150px) rotate(135deg);
        animation-delay: 0.4s;
      }
      &:nth-child(6) {
        transform: translate(-50%, -50%) rotate(-45deg) translateX(150px) rotate(45deg);
        animation-delay: 0.5s;
      }
    }
  }
}

// 加载动画关键帧
@keyframes fadeInScale {
  to {
    opacity: 1;
    transform: translate(-50%, -50%) rotate(var(--rotate)) translateX(150px) rotate(calc(-1 * var(--rotate)));
  }
}

代码说明

  1. 环形布局:

    • .navMenu作为相对定位容器,宽高设为400px(足够容纳头像和导航项)
    • 头像通过transform: translate(-50%, -50%)居中在容器内
    • 每个.navItem先旋转方向,再平移到圆弧位置,最后反向旋转保持图标正向,5个项分别对应不同角度,均匀分布在头像下半区域
  2. 加载动画:

    • 定义fadeInScale关键帧,实现从透明、缩放0到完全显示的过渡
    • 给每个.navItem设置递增的animation-delay,实现逐个出现的顺序效果
    • 保留原有hover时的缩放和文本显示逻辑

内容的提问来源于stack exchange,提问作者Pisa Ponente

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:52:03