旋转菜单3.0

效果图

在这里插入图片描述

JS

import {
    
     useState } from 'react';
import styles from './style.less'

import pu from '@/assets/common/pu.png'
import itemImg from '@/assets/common/item.png'
import itemActiveImg from '@/assets/common/itemActive.png'

import gl from '@/assets/common/gl.png'
import jy from '@/assets/common/jy.png'
import kj from '@/assets/common/kj.png'
import ms from '@/assets/common/ms.png'
import ty from '@/assets/common/ty.png'
import wgbj from '@/assets/common/wgbj.png'
import wgll from '@/assets/common/wgll.png'
import wl from '@/assets/common/wl.png'
import ws from '@/assets/common/ws.png'

// 二级导航图片
import gy from '@/assets/common/gy.png'
import mt from '@/assets/common/mt.png'
import hd from '@/assets/common/hd.png'
import tcc from '@/assets/common/tcc.png'
import xfs from '@/assets/common/xfs.png'
import bns from '@/assets/common/bns.png'
import ggcs from '@/assets/common/ggcs.png'
import ld from '@/assets/common/ld.png'
import wushui from '@/assets/common/wushui.png'
import xhd from '@/assets/common/xhd.png'
import ysss from '@/assets/common/ysss.png'

// 二级导航高亮图片
import gy_Active from '@/assets/common/gy_Active.png'
import mt_Active from '@/assets/common/mt_Active.png'
import hd_Active from '@/assets/common/hd_Active.png'
import tcc_Active from '@/assets/common/tcc_Active.png'
import xfs_Active from '@/assets/common/xfs_Active.png'
import bns_Active from '@/assets/common/bns_Active.png'
import ggcs_Active from '@/assets/common/ggcs_Active.png'
import ld_Active from '@/assets/common/ld_Active.png'
import wushui_Active from '@/assets/common/wushui_Active.png'
import xhd_Active from '@/assets/common/xhd_Active.png'
import ysss_Active from '@/assets/common/ysss_Active.png'

// 顶部弹框背景
import topGy from '@/assets/common/popBox/topGy.png'
import topMt from '@/assets/common/popBox/topMt.png'
import topHd from '@/assets/common/popBox/topHd.png'
import topTcc from '@/assets/common/popBox/topTcc.png'
import topXfs from '@/assets/common/popBox/topXfs.png'
import topBns from '@/assets/common/popBox/topBns.png'
import topGgcs from '@/assets/common/popBox/topGgcs.png'
import topLd from '@/assets/common/popBox/topLd.png'
import topWushui from '@/assets/common/popBox/topWushui.png'
import topXhd from '@/assets/common/popBox/topXhd.png'
import topYsss from '@/assets/common/popBox/topYsss.png'

const navData = [
    {
    
    
        name: '网格部件', id: 1, rotate: 0, child: [
            {
    
     name: '公园', id: 1, img: gy, activeImg: gy_Active, topImg: topGy },
            {
    
     name: '码头', id: 2, img: mt, activeImg: mt_Active, topImg: topMt },
            {
    
     name: '涵洞', id: 3, img: hd, activeImg: hd_Active, topImg: topHd },
            {
    
     name: '停车场', id: 4, img: tcc, activeImg: tcc_Active, topImg: topTcc },
            {
    
     name: '消防栓', id: 5, img: xfs, activeImg: xfs_Active, topImg: topXfs },
            {
    
     name: '避难所', id: 6, img: bns, activeImg: bns_Active, topImg: topBns },
            {
    
     name: '公共厕所', id: 7, img: ggcs, activeImg: ggcs_Active, topImg: topGgcs },
            {
    
     name: '路灯', id: 8, img: ld, activeImg: ld_Active, topImg: topLd },
            {
    
     name: '污水', id: 9, img: wushui, activeImg: wushui_Active, topImg: topWushui },
            {
    
     name: '信号灯', id: 10, img: xhd, activeImg: xhd_Active, topImg: topXhd },
            {
    
     name: '雨水设施', id: 11, img: ysss, activeImg: ysss_Active, topImg: topYsss },
        ],
        img: wgbj
    },
    {
    
    
        name: '网格力量', id: 2, ysss: gy, rotate: 40, child: [
            {
    
     name: '网格员', img: gy, id: 1 },
            {
    
     name: '保洁员', img: gy, id: 2 },
            {
    
     name: '律师', img: gy, id: 3 },
            {
    
     name: '警官', img: gy, id: 4 },
            {
    
     name: '法官', img: gy, id: 5 },
            {
    
     name: '检察官', img: gy, id: 6 }
        ],
        img: wgll
    },
    {
    
    
        name: '文旅', id: 3, rotate: 80,
        img: wl
    },
    {
    
    
        name: '民生', id: 4, rotate: 120, child: [
            {
    
     name: '网格员', img: gy, id: 1 },
            {
    
     name: '保洁员', img: gy, id: 2 },
            {
    
     name: '律师', img: gy, id: 3 },
            {
    
     name: '警官', img: gy, id: 4 },
            {
    
     name: '法官', img: gy, id: 5 },
            {
    
     name: '检察官', img: gy, id: 6 }
        ], img: ms
    },
    {
    
    
        name: '管理', id: 5, rotate: 160, child: [
            {
    
     name: '网格员', img: gy, id: 1 },
            {
    
     name: '保洁员', img: gy, id: 2 },
            {
    
     name: '警官', img: gy, id: 4 },
            {
    
     name: '检察官', img: gy, id: 6 }
        ], img: gl
    },
    {
    
    
        name: '体育', id: 6, rotate: 200, child: [
            {
    
     name: '网格员', img: gy, id: 1 },
            {
    
     name: '保洁员', img: gy, id: 2 },
            {
    
     name: '检察官', img: gy, id: 6 }
        ], img: ty
    },
    {
    
    
        name: '科技', id: 7, rotate: 240, child: [
            {
    
     name: '网格员', img: gy, id: 1 },
            {
    
     name: '保洁员', img: gy, id: 2 },
            {
    
     name: '律师', img: gy, id: 3 },
            {
    
     name: '警官', img: gy, id: 4 },
            {
    
     name: '法官', img: gy, id: 5 },
            {
    
     name: '检察官', img: gy, id: 6 }
        ], img: kj
    },
    {
    
    
        name: '教育', id: 8, rotate: 280, child: [
            {
    
     name: '网格员', img: gy, id: 1 },
            {
    
     name: '律师', img: gy, id: 3 },
            {
    
     name: '警官', img: gy, id: 4 },
            {
    
     name: '法官', img: gy, id: 5 },
            {
    
     name: '检察官', img: gy, id: 6 }
        ], img: jy
    },
    {
    
    
        name: '卫生', id: 9, rotate: 320, child: [
            {
    
     name: '网格员', img: gy, id: 1 },
            {
    
     name: '保洁员', img: gy, id: 2 },
            {
    
     name: '律师', img: gy, id: 3 },
            {
    
     name: '检察官', img: gy, id: 6 }
        ], img: ws
    },
]
const index = () =>
{
    
    
    const [isShow, setIsShow] = useState(false)
    const [rotate, setRotate] = useState(0)
    const [menuData, setMenuData] = useState(navData[0].child)
    const [navDataActive, setNavDataActive] = useState(1)
    const [menuDataActive, setMenuDataActive] = useState(null)

    const handleMouse = (flag) =>
    {
    
    
        return () =>
        {
    
    
            setIsShow(flag)
        }
    }
    const click = () =>
    {
    
    
        setIsShow(!isShow)

    }
    // 选中高亮以及更换2级菜单数据以及清空高亮状态
    const navClick = (data, rotate) =>
    {
    
    
        console.log(rotate, 222);
        setRotate(rotate)
        setNavDataActive(data.id)
        setMenuData(data.child)
        setMenuDataActive(null)
    }
    // 选中高亮
    const menuClick = (data) =>
    {
    
    
        setMenuDataActive(data.id)
    }
    return (
        <div
            // style={
    
    { transform: `rotate(-${rotate}deg)`, transition: 'all 1s' }}
            onMouseLeave={
    
    handleMouse(false)}
            className={
    
    isShow ? styles.container : styles.containerActive}>
            <a className={
    
    styles.menu_toggler} onClick={
    
    click}>
                <img onMouseEnter={
    
    handleMouse(true)} style={
    
    isShow ? {
    
     transform: 'scale(1)', transition: 'all 1s' } : {
    
     transform: 'scale(.8)', transition: 'all 1s' }} src={
    
    pu} alt="" />
            </a>
            <div style={
    
    isShow ? {
    
     transform: 'scale(1)', transition: 'all 1s' } : {
    
     transform: 'scale(.3)', transition: 'all 1s' }} className={
    
    isShow ? styles.menuWarp : styles.menuWarpActive}>
                <nav className={
    
    styles.menu}>
                    <ul>
                        {
    
    navData.map((data, index) => (
                            <li style={
    
    isShow ? {
    
     transform: `rotate(${
      
      360 / navData.length * index}deg) translateX(-150px)` } : null} key={
    
    index} className={
    
    `${
      
      styles.menu_item} ${
      
      isShow && styles.menu_item_active} `}  >
                                <a
                                    onClick={
    
    () => {
    
     navClick(data, 360 / navData.length * index) }}
                                    className={
    
    styles.nav_item}
                                    style={
    
    navDataActive === data.id ? {
    
     backgroundImage: `url(${
      
      itemActiveImg} )`, backgroundSize: '100% 100%', transform: `rotate(-${
      
      360 / navData.length * index}deg)`, transition: 'all 1s' } :
                                        {
    
     backgroundImage: `url(${
      
      itemImg} )`, backgroundSize: '100% 100%', transform: `rotate(-${
      
      360 / navData.length * index}deg)`, transition: 'all 1s' }}>
                                    <img style={
    
    {
    
     width: '20px', height: '20px' }} src={
    
    data.img} alt={
    
    data.name} />
                                    <span> {
    
    data.name}</span>
                                </a>
                            </li>
                        ))}
                    </ul>
                    <ul>
                        {
    
    menuData?.map((data, index) => (
                            <li style={
    
    isShow ? {
    
     transform: `rotate(${
      
      360 / menuData.length * index}deg) translateX(-270px)` } : null} key={
    
    index} className={
    
    `${
      
      styles.menu_item} ${
      
      isShow && styles.menu_item_active} `}  >
                                <a
                                    style={
    
    menuDataActive === data.id ? {
    
     flexFlow: 'column', backgroundImage: `url(${
      
      itemActiveImg} )`, backgroundSize: '100% 100%', transform: `rotate(-${
      
      360 / menuData.length * index}deg)`, transition: 'all 1s' } : {
    
     flexFlow: 'column', backgroundImage: `url(${
      
      itemImg} )`, backgroundSize: '100% 100%', transform: `rotate(-${
      
      360 / menuData.length * index}deg)`, transition: 'all 1s' }}
                                    className={
    
    styles.nav_item}
                                    onClick={
    
    () => {
    
     menuClick(data, index) }}>
                                    <img style={
    
    {
    
     width: '34px', height: '32px' }} src={
    
    menuDataActive === data.id ? data.activeImg : data.img} alt={
    
    data.name} />
                                    <span> {
    
    data.name}</span>
                                </a>
                            </li>
                        ))}
                    </ul>
                </nav>
            </div>
        </div >
    );
};
export default index

CSS

.container,
.containerActive {
    
    
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  background: linear-gradient(to right, #ed6ea0, #ec8c69);
  width: 700px;
  height: 700px;
  background: url('~@/assets/common/menu2.png') no-repeat;
  background-size: 100% 100%;
  margin: 0 auto;

  // 按钮
  .menu_toggler {
    
    
    position: absolute;
    display: block;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    // width: 40px;
    // height: 40px;
    width: 200px;
    height: 200px;
    z-index: 2;
    opacity: 1;
    cursor: pointer;

    img {
    
    
      width: 100%;
      height: 100%;
    }
  }

  .menuWarp,
  .menuWarpActive {
    
    
    width: 400px;
    height: 400px;
    background-color: red;
    background: url('~@/assets/common/menu2.png') no-repeat;
    background-size: 100% 100%;

    .menu_item {
    
    
      position: absolute;
      display: block;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      margin: auto;
      width: 80px;
      height: 80px;
      opacity: 0;
      transition: 0.5s;
    }

    // 活跃按钮
    .menu_item_active {
    
    
      opacity: 1;

      a {
    
    
        pointer-events: auto;
      }
    }

    .nav_item {
    
    
      display: flex;
      justify-content: space-evenly;
      padding: 8px;
      /* display: block; */
      width: inherit;
      height: inherit;
      /* line-height: 80px; */
      color: rgba(255, 255, 255, 0.7);
      background: rgba(255, 255, 255, 0.2);
      border-radius: 50%;
      text-align: center;
      text-decoration: none;
      font-size: 16px;
      transition: 0.2s;
      font-weight: 700;
      align-items: center;
    }

    .menu_item a:hover {
    
    
      box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3);
      color: #fff;
      background: rgba(255, 255, 255, 0.3);
      // font-size: 45px;
      font-size: 16px;
    }

    //   new

  }

  .menuWarpActive {
    
    
    width: 200px;
    height: 200px;
    background-color: red;
    background: url('~@/assets/common/menu2.png') no-repeat;
    background-size: 100% 100%;
  }
}

.containerActive {
    
    
  width: 700px;
  height: 700px;
  background: transparent;
}

猜你喜欢

转载自blog.csdn.net/chuan0106/article/details/125169773