前言
项目需要用到环形菜单,初略在网上找了一下,没有找到合适的,于是自己写了一个很简单的,后续再优化。
这个组件是基于react,但是原理都一样。
展开效果如下:

实现
css(less)
@centericonsize: 30px;
.flex(@justify: flex-start, @align: center) {
justify-content: @justify;
align-items: @align;
display: flex;
}
.sector-menu-wrapper {
position: relative;
width: @centericonsize;
margin: auto;
.center-icon {
.flex(center);
width: @centericonsize;
height: @centericonsize;
border-radius: 50%;
background: rgba(0, 0, 0, 0.3);
color: white;
cursor: pointer;
}
.sector-item {
position: absolute;
.flex(center);
width: @centericonsize;
height: @centericonsize;
border-radius: 50%;
background: rgba(0, 0, 0, 0.3);
cursor: pointer;
color: white;
top: 0;
left: 0;
transition: all linear 0.5s;
transform: translate(0, 0);
// display: none;
visibility: hidden;
}
.sector-list {
&.sector-list-active {
transition: all linear 0.5s;
.sector-item {
.flex(center);
transition: all linear 0.5s;
transform: translate(0, 0);
visibility: visible;
&:first-child {
transform: translate(0, -@centericonsize * 1.5);
}
&:nth-child(2) {
transform: translate(-@centericonsize * 1.5, 0);
}
&:nth-child(3) {
transform: translate(0, @centericonsize * 1.5);
}
}
}
}
}
sectormenu.js
import react from 'react';
export default class sectormenu extends react.component {
state = {
direction: 'left',
sectormenuvisible: false,
centericonsize: 30,
sectoritemsize: 30,
}
/**
* 显示环形菜单
*/
showsectormenu = () => {
const { sectormenuvisible } = this.state;
this.setstate({
sectormenuvisible: !sectormenuvisible,
})
}
onclicksectormenuitem = (index) => {
const { sectormenuitemfunctions } = this.props;
if (!sectormenuitemfunctions || typeof(sectormenuitemfunctions[index]) !== 'function') {
return;
}
sectormenuitemfunctions[index]();
}
getsectorjsx = () => {
const { sectormenuitems } = this.props;
if (!sectormenuitems || !array.isarray(sectormenuitems) || sectormenuitems.length === 0) {
return;
}
const styles = {};
const { sectormenuvisible } = this.state;
return sectormenuitems.map((item, i) => {
// const styles = {
// transform: translate(0, -centericonsize * 2);
// };
return (<div
classname={`sector-item ${sectormenuvisible && 'sector-item-active'}`}
style={styles}
onclick={() => this.onclicksectormenuitem(i)}
key={i}
>
{item}
</div>)
});
}
render() {
const { sectormenuvisible } = this.state;
return (
<div classname="sector-menu-wrapper">
<div classname="center-icon" onclick={this.showsectormenu}>
{
sectormenuvisible ? 'x' : '···'
}
</div>
<div classname={`sector-list ${sectormenuvisible && 'sector-list-active'}`}>
{this.getsectorjsx()}
</div>
</div>
)
}
}
调用
<sectormenu
sectormenuitems={['a1', 'a2', 'a3']}
sectormenuitemfunctions={[function () {console.log(0)}, function () {console.log(1)}, function () {console.log(2)}]}
/>
期望
本来是想写成灵活分布,在怎么计算位置这里稍稍卡了一下,项目时间紧,改天抽空优化一下
- 灵活布局sectormenuitem
- 灵活展示sectormenu的位置(left,right, top, bottom...)
踩坑
过渡动画一直没有用,后来才知道是我在sector-item这个类里使用了display:none导致的,改用visibility属性就可以了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持代码网。
发表评论