✨ 手把手带大家绘制 QQ 弹弹的圆环菜单,学不会找我!
前言
菜单是每个网站都有的功能,它可以帮助我们更快找到对应的功能。但是菜单想要做的特别做的好看,就需要下点功夫了,一步步带大家做一个环绕展开菜单的效果。
思路分析
接下来我们一步一步的分析环绕展开圆环菜单的实现过程。
准备图标
首先我们先将 8 个图标准备好,没有的不要怕,我放在后面 Github 小节里了,大家需要自取。
按钮
菜单分为主菜单以及子菜单,1 个大圆 + 8 个小圆,共 9 个圆。我们直接在正方形的基础上给个 border-radius: 50%
就可以实现圆形的效果了。
<div class="menu">
<div class="toggle">+</div>
<li style="--i: 0">
<a href="#">
<img src="./static/8.png" alt="" />
</a>
</li>
<li style="--i: 1">
<a href="#">
<img src="./static/1.png" alt="" />
</a>
</li>
<li style="--i: 2">
<a href="#">
<img src="./static/2.png" alt="" />
</a>
</li>
<li style="--i: 3">
<a href="#">
<img src="./static/3.png" alt="" />
</a>
</li>
<li style="--i: 4">
<a href="#">
<img src="./static/4.png" alt="" />
</a>
</li>
<li style="--i: 5">
<a href="#">
<img src="./static/5.png" alt="" />
</a>
</li>
<li style="--i: 6">
<a href="#">
<img src="./static/6.png" alt="" />
</a>
</li>
<li style="--i: 7">
<a href="#">
<img src="./static/7.png" alt="" />
</a>
</li>
</div>
这里我们需要将 .menu
设置为相对定位 relative
,然后将小圆 li
设置为绝对定位 absolute
,方便我们对按钮位置进行调整。
.menu {
position: relative;
width: 200px;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
}
.menu li {
list-style: none;
}
我们观察一下此时小按钮的排列情况:
可以发现显然和我们的预期不太一致。
围绕主按钮
接下来我们要让小按钮们都绕着主按钮进行排列。具体怎么做呢?
首先我们将小圆点们都设置为 绝对定位 。
.menu li {
position: absolute;
left: 0;
}
可以观察都此时所有小圆点都在起始位置。
我们知道,如果要让一个物体进行旋转,可以使用 transform
的 rotate
属性。
那么每个圆应该旋转多少度呢?我们知道一周是有 360° ,那么我们有 8 个小圆,平均分应当每个圆的旋转角度是 360 / 8,也就是 45°,因此 rotate
的值为 calc(var(--i) * 45deg)
。
可以发现旋转角度是有生效的,但是整体并没有如我们预期一样绕着主按钮排列。
这是因为 rotate
是围绕物体的原点作用的,圆的原点就是圆心,旋转的话它的位置必然是不变的。
为了让圆围绕着一个点进行旋转,我们需要改变所有圆的原点位置,让它们都围着这个原点进行旋转。
这里我们就要用到 transform-origin
属性了,这个属性可以 改变需要变换的元素的原点 。
我们将 transform-origin
的值设置为 100px 看看。
此时就符合预期了。不过小圆点的图标也跟着旋转了,这是因为我们刚刚给 li
设置了 rotate
,为了将图标摆正,我们需要让 img
标签反方向旋转对应的角度,即 calc(var(--i) * -45deg)
。
如此就符合预期了。
旋转动画
接下来我们要着手旋转动画了,小圆点们一开始是 “藏”在主按钮里面且没有围绕 的,这里我们可以使用 translateX
为 负值 实现,同时我们要将 rotate
的值设置为 0,这样 8 个小圆点就都 叠 在一起并且藏于主按钮身后。
.li {
...
transform: rotate(0deg) translateX(80px);
}
在点击主按钮之后,小圆点会旋转并围绕在主按钮周围。我们可以使用一个 .active
类,在点击时将类名进行切换,切换前后分别是“围绕”以及“收缩”两个状态。围绕态我们要将 rotate
以及 translateX
的值恢复:
.menu.active li {
transform: rotate(calc(var(--i) * 45deg));
}
js 代码如下:
<script>
const toggleBtn = document.querySelector(".toggle");
const menu = document.querySelector(".menu");
toggleBtn.onclick = () => {
menu.classList.toggle("active");
};
</script>
此时我们点击主按钮:
可以发现所有小圆点都是一下子蹦出来的,我们给它们分别加点延迟效果试试:
.menu li {
...
transition: 0.5s;
transition-delay: calc(0.1s * var(--i));
}
OK,大功告成!
Github 源码地址
关于本文的所有代码及素材,都已上传至 Github 仓库,小伙伴们有需要的自取:
juejin-demo/rotate-menu-demo at main · catwatermelon/juejin-demo (github.com)
结束语
本文就到此结束了,希望大家阅读本文能所收获。
如果小伙伴们有别的想法,欢迎留言,让我们共同学习进步💪💪。
如果文中有不对的地方,或是大家有不同的见解,欢迎指出🙏🙏。
如果大家觉得所有收获,欢迎一键三连💕💕。
转载自:https://juejin.cn/post/7158007433225306119