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

环形菜单中子菜单按钮文字直立显示问题求助

环形菜单中子菜单按钮文字直立显示问题求助

大家好,我最近在做一个环形交互菜单,遇到了个卡壳的问题:当鼠标悬停在带数字的.menu-item圆形按钮上时,弹出的子菜单.submenu里的按钮文字应该是直立显示的,但现在除了第一个子菜单(对应主菜单的“1”)文字默认正常外,其他子菜单的字母都是倾斜的。我已经找ChatGPT帮忙排查过了,但没解决问题,所以来这里求助各位大佬!

目前子菜单的字母位置是居中的,就是方向不对,全部是倾斜状态,我只需要把这些字母调整成直立的就行。

我的代码

JavaScript 部分

let menuItems = document.querySelectorAll(".menu-item");
let itemCount = menuItems.length;
let radius = 100;

menuItems.forEach((item, index) => {
  let angle = (index / itemCount) * (2 * Math.PI);
  let x = radius * Math.cos(angle);
  let y = radius * Math.sin(angle);
  item.style.left = `calc(50% + ${x}px)`;
  item.style.top = `calc(50% + ${y}px)`;
  item.style.transform = `translate(-50%, -50%) rotate(${angle}rad)`;
  
  let text = item.querySelector("span");
  if (text) {
    text.style.transform = `rotate(${-angle}rad)`;
    text.style.display = "inline-block";
  }
});

document.querySelectorAll(".submenu").forEach((submenu) => {
  let buttons = submenu.querySelectorAll("button");
  let btnCount = buttons.length;
  let btnRadius = 60;
  
  buttons.forEach((btn, i) => {
    let angle = (i / btnCount) * (2 * Math.PI);
    let x = btnRadius * Math.cos(angle);
    let y = btnRadius * Math.sin(angle);
    btn.style.left = `calc(50% + ${x}px)`;
    btn.style.top = `calc(50% + ${y}px)`;
    btn.style.setProperty("--angle", `${angle}rad`);
    btn.style.transform = `translate(-50%, -50%) rotate(${angle}rad)`;
    
    let text = btn.querySelector("span");
    if (text) {
      text.style.transform = `rotate(${-angle}rad)`;
      text.style.display = "inline-block";
    }
  });
});

CSS 部分

body {
  background: linear-gradient(135deg, #1e1e2f, #292940);
  height: 100vh;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  font-family: "Segoe UI", sans-serif;
}

.menu-center {
  position: relative;
  width: 220px;
  height: 220px;
}

.central-button {
  position: absolute;
  width: 90px;
  height: 90px;
  background: linear-gradient(135deg, #3498db, #2980b9);
  border-radius: 50%;
  color: white;
  font-weight: bold;
  font-size: 16px;
  display: flex;
  justify-content: center;
  align-items: center;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  cursor: pointer;
  box-shadow: 0 0 15px rgba(52, 152, 219, 0.4);
  z-index: 2;
  transition: transform 0.3s ease;
}

.central-button:hover {
  transform: translate(-50%, -50%) scale(1.1);
  box-shadow: 0 0 20px rgba(52, 152, 219, 0.8);
}

.menu-item {
  position: absolute;
  width: 20px;
  height: 20px;
  top: 40%;
  left: 40%;
  background: linear-gradient(135deg, #f39c12, #e67e22);
  transform-origin: center center;
  border-radius: 50%;
  color: white;
  font-weight: bold;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: all 0.4s ease;
  box-shadow: 0 0 10px rgba(243, 156, 18, 0.4);
}

.menu-label, button span {
  display: inline-block;
  transform-origin: center;
}

.menu-item span {
  display: inline-block;
  transform-origin: center center;
  position: absolute;
  white-space: nowrap;
}

.submenu button span {
  display: inline-block;
  transform-origin: center;
  position: absolute;
  white-space: nowrap;
}

.menu-center:hover .menu-item {
  opacity: 1;
  pointer-events: auto;
}

.menu-center:hover .menu-item:nth-child(2) {
  transition-delay: 0s;
}

.menu-center:hover .menu-item:nth-child(3) {
  transition-delay: 0.1s;
}

.menu-center:hover .menu-item:nth-child(4) {
  transition-delay: 0.2s;
}

.menu-center:hover .menu-item:nth-child(5) {
  transition-delay: 0.3s;
}

.menu-center:hover .menu-item:nth-child(6) {
  transition-delay: 0.4s;
}

.menu-center:hover .menu-item:nth-child(7) {
  transition-delay: 0.5s;
}

.menu-center:hover .menu-item:nth-child(8) {
  transition-delay: 0.6s;
}

.menu-center:hover .menu-item:nth-child(9) {
  transition-delay: 0.7s;
}

.menu-item:hover {
  transform: scale(1.15);
  box-shadow: 0 0 15px rgba(243, 156, 18, 0.8);
  z-index: 1;
}

.submenu {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.menu-item:hover .submenu button {
  opacity: 1;
  pointer-events: auto;
}

.menu-item:hover .submenu button:nth-child(1) {
  transition-delay: 0s;
}

.menu-item:hover .submenu button:nth-child(2) {
  transition-delay: 0.1s;
}

.menu-item:hover .submenu button:nth-child(3) {
  transition-delay: 0.2s;
}

.menu-item:hover .submenu button:nth-child(4) {
  transition-delay: 0.3s;
}

.menu-item:hover .submenu button:nth-child(5) {
  transition-delay: 0.4s;
}

.menu-item:hover .submenu button:nth-child(6) {
  transition-delay: 0.5s;
}

.menu-item:hover .submenu button:nth-child(7) {
  transition-delay: 0.6s;
}

.menu-item:hover .submenu button:nth-child(8) {
  transition-delay: 0.7s;
}

.submenu button {
  position: absolute;
  width: 30px;
  height: 30px;
  background: linear-gradient(135deg, #2ecc71, #27ae60);
  top: 45%;
  left: 45%;
  transform-origin: center;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  opacity: 0;
  pointer-events: none;
  transition: all 0.4s ease;
}

我原本的思路是给每个子菜单按钮旋转对应角度后,让内部的span反向旋转抵消角度,从而让文字直立,但实际效果不对。希望各位能帮我找出问题所在,让所有子菜单的文字都能正常直立显示!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 14:12:58