这种轮盘式可收起的按钮大家应该都见过的吧,对于一些平时使用频率不高的按钮组,我们就可以用这种轮盘按钮来处理,平时收缩起来只展示一个主按钮,点击主按钮之后才会将子按钮围绕主按钮显示出来
在线体验
码上掘金
codePen
代码实现
html部分
html 部分比较简单,主按钮在 html 中直接创建,子按钮根据配置信息在 js 中动态生成
<div class="wheel-btn-container">
<button class="main-btn" id="mainBtn">
<span>展开</span>
</button>
<ul class="sub-buttons" id="subButtons"></ul>
</div>
css部分
主按钮交互
- 动画效果:展开 / 收起 时主按钮旋转 360°,配合渐变颜色变化和文字切换
- 文字切换:通过伪元素 ::after 实现 “展开”→“收起” 的平滑过渡,避免 DOM 频繁操作
background: linear-gradient(135deg, #1a237e, #3949ab);
transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.main-btn.active {
transform: rotate(360deg);
background: linear-gradient(135deg, #0d47a1, #1976d2);
}
.main-btn span { opacity: 1; }
.main-btn.active span { opacity: 0; }
.main-btn::after {
content: "收起";
position: absolute;
opacity: 0;
}
.main-btn.active::after { opacity: 1; }
子按钮展开动画
- 贝塞尔曲线参数:cubic-bezier(0.34, 1.56, 0.64, 1) 模拟弹性效果,前半段加速,后半段减速
.sub-btn { transition: all 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); }
菜单配置
mainBtnText
mainBtnText: {
expand: "展开",
collapse: "收起",
}
- expand:收起状态时主按钮上显示的显示文字
- collapse:展开状态时主按钮上显示的文字
subBtns
子菜单组,这里简单用 emoji 来做 icon,需要使用 图片 或 svg 的话需要简单改下。
subBtns: [
{ icon: "📅", text: "日程" },
{ icon: "📞", text: "联系" },
{ icon: "📚", text: "文档" },
{ icon: "⚙️", text: "设置" },
{ icon: "🚀", text: "加速" },
{ icon: "💡", text: "反馈" },
{ icon: "📊", text: "统计" },
],
其它
const wheelConfig = {
…………,
radius: 120, // 子按钮分布半径
animationDuration: 0.6, // 动画时长(秒)
animationEasing: "cubic-bezier(0.34, 1.56, 0.64, 1)", // 弹性动画缓动函数
};
生成子按钮
根据配置信息动态生成子按钮。
子按钮弧度计算
每个子按钮的角度为 360°/子按钮数量×索引
角度转弧度 = 角度 × (π/180)
const btn = document.createElement("li");
btn.className = "sub-btn";
btn.innerHTML = `
<div class="sub-btn-icon">${item.icon}</div>
<div class="sub-btn-text">${item.text}</div>
`;
const angle =
(360 / this.config.subBtns.length) * index * (Math.PI / 180);
子按钮位置计算
转换为弧度后通过 Math.cos() 和 Math.sin() 计算相对位置坐标
const x = Math.cos(angle) * this.config.radius;
const y = Math.sin(angle) * this.config.radius;
btn.style.left = `calc(50% + ${x}px)`;
btn.style.top = `calc(50% + ${y}px)`;
源码
gitee
github
- 🌟 觉得有帮助的可以点个 star~
- 🖊 有什么问题或错误可以指出,欢迎 pr~
- 📬 有什么想要实现的功能或想法可以联系我~
公众号
关注公众号『 前端也能这么有趣 』,获取更多有趣内容。
发送 加群 还可以加入群聊,一起来学习(摸鱼)吧~
说在后面
🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『
前端也能这么有趣
』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。