Teach you how to implement a circular/fan-shaped menu in 2 minutes (basic version)

Teach you how to implement a circular/fan-shaped menu in 2 minutes (basic version)

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.

  1. Flexible layout of sectorMenuItem
  2. Flexible display of SectorMenu position (left, right, top, bottom...)

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

Recommend

Linux five-step build kernel tree

Table of contents 0. The kernel tree that comes w...

Solve the black screen problem after VMware installs Linux system and starts

1. Installation environment 1. HUAWEI mate x cpu ...

js to call the network camera and handle common errors

Recently, due to business reasons, I need to acce...

Solution for using Baidu share on Https page

Since enabling https access for the entire site, ...

Implementation of vue+drf+third-party sliding verification code access

Table of contents 1. Background 2. Verification p...

Vue uses v-model to encapsulate the entire process of el-pagination components

Use v-model to bind the paging information object...

Example code for CSS columns to achieve two-end alignment layout

1. Going around in circles After going around in ...

Determine the direction of mouse entry based on CSS

In a front-end technology group before, a group m...

Play mp3 or flash player code on the web page

Copy code The code is as follows: <object id=&...

Teach you how to quickly install Nginx in CentOS7

Table of contents 1. Overview 2. Download the Ngi...

Docker Stack deployment method steps for web cluster

Docker is becoming more and more mature and its f...

MySQL multi-table join introductory tutorial

Connections can be used to query, update, and est...

Hadoop 3.1.1 Fully Distributed Installation Guide under CentOS 6.8 (Recommended)

Foregoing: This document is based on the assumpti...

Docker completely deletes private library images

First, let’s take a look at the general practices...