vue2 弧形半圆菜单

需求描述:

一个圆的容器形容器内有6个小圆点,一半隐藏一半显示,默认一个对象有两种状态,img为未选中imgs为选中状态进行效果展示

实现效果:

代码实现:

 组件代码 curvedMenu.vue

<template>
  <div class="overall">
    <div class="circle-box">
      <div class="circle" :style="`width:${circle_w}px;height:${circle_h}px`">
        <div
          class="origin"
          :style="`width:${box_w}px;height:${box_h}px;transform: rotate(${stard}deg);`"
        >
          <div
            :style="`width:${box_w}px;height:${box_h}px;transform: rotate(${-stard}deg);`"
            class="img-box"
            v-for="(i, index) in list"
            :key="index"
            @click="Turn(index)"
          >
            <h1>{{ index }}</h1>
            <div class="box">
              <img
                :class="selectInd == index ? 'curImgs' : 'curImg'"
                :src="selectInd == index ? i.imgs : i.img"
                :alt="i.text"
              />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
  
  <script>
export default {
  name: "curvedMenu",
  data() {
    return {
      circle_w: 760, //圆盘的宽
      circle_h: 760, //圆盘的高
      box_w: 165, //圆盘上覆盖的小圆点宽
      box_h: 165, //圆盘上覆盖的小圆点高
      PI: 230, //分布角度,默认为360deg
      stard: 180, //起始角度
      stard_s: null, //用来默认储存第一个初始值
      // boxNum: 6, //圆盘上覆盖的小圆点个数
      activeIndex: 3, // 默认下标
      touchStartX: 0, // 触摸起始位置 X 坐标
      touchEndX: 0, // 触摸结束位置 X 坐标
      list: [
        {
          text: "诗",
          img: require("../assets/module/shi.png"),
          imgs: require("../assets/module/shi1.png"),
        },
        {
          text: "书",
          img: require("../assets/module/shu.png"),
          imgs: require("../assets/module/shu1.png"),
        },
        {
          text: "画",
          img: require("../assets/module/hua.png"),
          imgs: require("../assets/module/hua1.png"),
        },
        {
          text: "节",
          img: require("../assets/module/jie.png"),
          imgs: require("../assets/module/jie1.png"),
        },
        {
          text: "典",
          img: require("../assets/module/dian.png"),
          imgs: require("../assets/module/dian1.png"),
        },
        {
          text: "版",
          img: require("../assets/module/ban.png"),
          imgs: require("../assets/module/ban1.png"),
        },
      ],
      selectInd: "",
      lastClickValue: null,
    };
  },
  created() {
    this.stard_s = this.stard;
  },
  mounted() {
    this.init();
    this.Turn(this.activeIndex);
  },
  methods: {
    //初始化小圆点,根据计算使其分布到对应位置
    init() {
      let box = document.querySelectorAll(".img-box");
      let avd = this.PI / box.length; //每一个 img-box 对应的角度
      let ahd = (avd * Math.PI) / 180; //每一个 img-box 对应的弧度
      let radius = this.circle_w / 2; //圆的半径
      for (let i = 0; i < box.length; i++) {
        box[i].style.left = Math.sin(ahd * i) * radius + "px";
        box[i].style.top = Math.cos(ahd * i) * radius + "px";
      }
    },
    //点击相对应小圆点,圆盘进行相对应角度的转动
    // 半圆形状参数需要修改: 分布角度230 起始角度180
    Turn(index) {
      let _this = this;
      let bx = document.querySelectorAll(".box");
      _this.stard = index * (_this.PI / _this.list.length) + _this.stard_s;

      console.log(_this.stard);
      for (let i = 0; i < bx.length; i++) {
        if (i == index) {
          this.selectInd = index;
          bx[i].classList.add("box-active");
        } else {
          bx[i].classList.remove("box-active");
        }
      }
    },
    // 一个圆参数需要修改: 分布角度360 起始角度180
    // Turn(index) {
    //   let _this = this;
    //   let bx = document.querySelectorAll(".box");
    //   if (_this.lastClickValue + 1 === _this.list.length && index === 0) {
    //     _this.activeIndex += 1;
    //   } else if (
    //     index + 1 === _this.list.length &&
    //     _this.lastClickValue === 0
    //   ) {
    //     _this.activeIndex -= 1;
    //   } else if (_this.lastClickValue - index < 0) {
    //     _this.activeIndex += 1;
    //   } else if (_this.lastClickValue - index > 0) {
    //     _this.activeIndex -= 1;
    //   }
    //   _this.stard =
    //     this.activeIndex * (_this.PI / _this.list.length) + _this.stard_s;
    //   for (let i = 0; i < bx.length; i++) {
    //     if (i == index) {
    //       this.selectInd = index;
    //       bx[i].classList.add("box-active");
    //     } else {
    //       bx[i].classList.remove("box-active");
    //     }
    //   }
    //   this.lastClickValue = index;
    // },
  },
};
</script>
  
  <style lang="less" scoped>
.overall {
  width: 100%;
  height: 600px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;//控制半圆或一整个圆
}
.circle-box {
  height: 800px;
  margin-top: -150px;
  .circle {
    transform: scale(0.5);
    width: 100%;
    height: 100%;
    border-radius: 50%;
    box-sizing: border-box;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    .origin {
      position: relative;
      transition: 0.5s; //控制圆盘的的旋转速率
      .img-box {
        user-select: none;
        position: absolute;
        top: 0;
        left: 0;
        transition: none !important;
        pointer-events: none;
        .box {
          pointer-events: all !important;
          width: 100%;
          height: 100%;
          transition: 0.3s;
          display: flex;
          justify-content: center;
          align-items: center;
          position: absolute;
          left: 0;
          top: 0;
          border-radius: 50%;
          //   transform: scale(0.3); //其他圆点
          cursor: pointer;
          color: white;
          font-size: 40px;
          overflow: hidden;
          &:hover .content {
            opacity: 1;
          }
        }
        .box-active {
          transition-delay: 0.5s;
          transform: scale(1) !important;
        }
        .curImgs {
          width: 308px;
          height: 328px;
        }
        .curImg {
          width: 240px;
          height: 252px;
        }
      }
    }
  }
}
</style>
  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值