Preface The project requires a circular menu. I searched for it online but couldn't find a suitable one, so I wrote a very simple one myself and will optimize it later. This component is based on react, but the principle is the same. The expansion effect is as follows: accomplish 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, } /** * Show radial menu */ 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> ) } } Call <SectorMenu sectorMenuItems={['A1', 'A2', 'A3']} sectorMenuItemFunctions={[function () {console.log(0)}, function () {console.log(1)}, function () {console.log(2)}]} /> expect I originally wanted to write a flexible distribution, but I got stuck on how to calculate the position. The project time is tight, so I will find time to optimize it another day.
Pitfalls The transition animation didn't work until I realized it was because I used display:none in the sector-item class. I just needed to use the visibility property instead. The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM. |
<<: How to pass the value of the select drop-down box to the id to implement the code
>>: How to use react-color to implement the front-end color picker
Table of contents 0. The kernel tree that comes w...
1. Installation environment 1. HUAWEI mate x cpu ...
Recently, due to business reasons, I need to acce...
Since enabling https access for the entire site, ...
Table of contents 1. Background 2. Verification p...
Use v-model to bind the paging information object...
1. Going around in circles After going around in ...
In a front-end technology group before, a group m...
Copy code The code is as follows: <object id=&...
Table of contents 1. Overview 2. Download the Ngi...
Docker is becoming more and more mature and its f...
Connections can be used to query, update, and est...
Foregoing: This document is based on the assumpti...
First, let’s take a look at the general practices...
Uninstall MySQL 1. In the control panel, uninstal...