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

JavaScript+html to implement front-end page sliding verification (2)

This article example shares the specific code of ...

MySQL performance optimization: how to use indexes efficiently and correctly

Practice is the only way to test the truth. This ...

Analysis and solution of MySQL connection throwing Authentication Failed error

[Problem description] On the application side, th...

Complete steps for mounting a new data disk in CentOS7

Preface I just bought a new VPS. The data disk of...

MySQL 5.7.17 winx64 installation and configuration tutorial

Today I installed the MySQL database on my comput...

Implementing a table scrolling carousel effect through CSS animation

An application of CSS animation, with the same co...

Ten Experiences in Presenting Chinese Web Content

<br /> Focusing on the three aspects of text...

How to use Celery and Docker to handle periodic tasks in Django

As you build and scale your Django applications, ...

XHTML three document type declarations

XHTML defines three document type declarations. T...

MySQL performance optimization tips

MySQL Performance Optimization MySQL is widely us...

Tomcat common exceptions and solution code examples

The company project was developed in Java and the...

Two ways to achieve horizontal arrangement of ul and li using CSS

Because li is a block-level element and occupies ...