vue 摩天轮菜单栏-自动旋转

这是一个使用Vue.js编写的圆形菜单组件,包含转动动画效果。用户在鼠标悬停时会暂停转动,离开时恢复。菜单项根据预设角度分布,并在点击时更新详细信息。组件接受起始角度、默认高亮项等属性进行自定义。

<template>

  <div class="cirularMenu" @mouseenter="loopClose()" @mouseleave="loopStart()">

    <div class="cirula">

      <slot name="title"></slot>

      <!-- 圆形转盘 -->

      <div class="cirula_box" ref="cirula">

        <div

          ref="cirula_origin"

          class="cirula_origin"

          :style="`transform: rotate(${initialAngle}deg);`"

        >

          <div

            :key="index"

            class="cirula_item"

            :ref="`cirulaItem${index}`"

            @click="handleUpdate(index)"

            v-for="(item, index) in menus"

            :style="`transform: rotate(${-initialAngle}deg);`"

          >

            <img

              :src="

                activeIndex == index

                  ? require(`@/assets/image/screen/circularMenu_${

                      index + 1

                    }_active.png`)

                  : require(`@/assets/image/screen/circularMenu_${

                      index + 1

                    }_default.png`)

              "

              alt=""

            />

            <p>{{ item.title }}</p>

          </div>

        </div>

        <!-- 转盘 -->

        <div class="cirula_service">

          <div class="cirula_service_border"></div>

          <div class="cirula_service_main">

            <img

              src="~@/assets/image/screen/cirulaMenu_serviceCloud.png"

              alt=""

            />

            <h4>数智化综合服务</h4>

            <p>Digital intelligence<br />integrated service</p>

          </div>

        </div>

      </div>

    </div>

    <!-- 联动详情 -->

    <div class="description">

      <div class="desc_title">

        <h3>{{ descTitle }}</h3>

        <span>{{ descSubtitle }}</span>

      </div>

      <div class="desc_content">{{ descContent }}</div>

    </div>

  </div>

</template>

<script>

export default {

  props: {

    // 起始角度

    startAngle: {

      type: Number,

      default: () => {

        return 0;

      },

    },

    // 默认高亮下标

    circularActive: {

      type: Number,

      default: () => {

        return 0;

      },

    },

  },

  data() {

    return {

      PI: 360, // 分布角度

      timer: null, // 定时器

      descTitle: "", // 详情标题

      descContent: "", // 详情内容

      descSubtitle: "", // 详情副标题

      initialAngle: this.startAngle, // 起始角度

      activeIndex: this.circularActive, //默认下标

      menus: [

        {

          title: "智慧工厂",

          subtitle: "SMART FACTORY BUSINESS INTRODUCTION",

          desc: "智慧工厂业务介绍智慧工厂业务介绍智慧工厂业务介绍智慧工厂业务介绍智慧工厂业务介绍",

        },

        {

          title: "智慧园区",

          subtitle: "SMART PARK BUSINESS INTRODUCTION",

          desc: "智慧园区业务介绍智慧园区业务介绍智慧园区业务介绍智慧园区业务介绍智慧园区业务介绍",

        },

        {

          title: "智慧家庭",

          subtitle: "SMART FAMILY BUSINESS INTRODUCTION",

          desc: "智慧家庭业务介绍智慧家庭业务介绍智慧家庭业务介绍智慧家庭业务介绍智慧家庭业务介绍",

        },

        {

          title: "智慧电力",

          subtitle: "SMART POWER BUSINESS INTRODUCTION",

          desc: "智慧电力业务介绍智慧电力业务介绍智慧电力业务介绍智慧电力业务介绍智慧电力业务介绍",

        },

        {

          title: "数字能源",

          subtitle: "DIGITAL ENERGY BUSINESS INTRODUCTION",

          desc: "数字能源业务介绍数字能源业务介绍数字能源业务介绍数字能源业务介绍数字能源业务介绍",

        },

        {

          title: "智慧教育",

          subtitle: "SMART EDUCATION BUSINESS INTRODUCTION",

          desc: "智慧教育业务介绍智慧教育业务介绍智慧教育业务介绍智慧教育业务介绍智慧教育业务介绍",

        },

        {

          title: "智慧交通",

          subtitle: "SMART TRAFFIC BUSINESS INTRODUCTION",

          desc: "智慧交通智慧交通智慧交通智慧交通智慧交通智慧交通智慧交通智慧交通智慧交通智慧交通",

        },

        {

          title: "智慧水务",

          subtitle: "SMART WATER BUSINESS INTRODUCTION",

          desc: "智慧水务业务介绍智慧水务业务介绍智慧水务业务介绍智慧水务业务介绍智慧水务业务介绍",

        },

        {

          title: "智慧灯杆",

          subtitle: "SMART POLE BUSINESS INTRODUCTION",

          desc: "智慧灯杆业务介绍智慧灯杆业务介绍智慧灯杆业务介绍智慧灯杆业务介绍智慧灯杆业务介绍",

        },

        {

          title: "智慧城市",

          subtitle: "SMART CITY BUSINESS INTRODUCTION",

          desc: "智慧城市业务介绍智慧城市业务介绍智慧城市业务介绍智慧城市业务介绍智慧城市业务介绍",

        },

      ],

    };

  },
  created() {

    // window.clearInterval(this.timer);

  },
  mounted() {
    this.initCirula();

    this.handleUpdate(this.activeIndex);

    // setTimeout(() => {

    //   var cirulaDom = document.getElementsByClassName("cirula");

    //   cirulaDom[0].style.height = cirulaDom[0].clientWidth;

    //   console.log(cirulaDom[0].style.height, "height");

    // }, 300);

    window.addEventListener("resize", () => {
      this.initCirula();
    });

    // 每5秒更新选中项

    this.timer = window.setInterval(() => {

      this.setTimer();

    }, 5 * 1000);

  },

  methods: {

    // 初始化圆盘,根据计算使其子模块分布到对应位置 - initCirula该方法为百度CV得来

    initCirula() {

      let cirulaItem = document.querySelectorAll(".cirula_item");

      let avd = this.PI / cirulaItem.length; // cirula_item 对应的角度

      let ahd = (avd * Math.PI) / 180; // cirula_item 对应的弧度

      let radius = (this.$refs.cirula.clientWidth - 60) / 2; //圆的半径

      for (let i = 0; i < cirulaItem.length; i++) {

        cirulaItem[i].style.top = Math.cos(ahd * i) * radius + "px";

        cirulaItem[i].style.left = Math.sin(ahd * i) * radius + "px";

      }

    },

    // 联动详情

    handleUpdate(index) {

      this.activeIndex = index;

      this.descTitle = this.menus[index].title;

      this.descContent = this.menus[index].desc;

      this.descSubtitle = this.menus[index].subtitle;

    },

    // 选中项切换

    setTimer() {

      if (this.activeIndex == this.menus.length - 1) {

        this.activeIndex = 0;

      } else {

        this.activeIndex = this.activeIndex + 1;

      }

      this.handleUpdate(this.activeIndex);

    },

    // 鼠标移入

    loopClose() {

      window.clearInterval(this.timer);

      this.timer = null;

      // 圆盘停止旋转

      this.handleAnimation("paused");

    },

    // 鼠标移出

    loopStart() {

      if (this.timer == null) {

        this.timer = window.setInterval(() => {

          this.setTimer();

        }, 5 * 1000);

      }

      // 圆盘恢复旋转

      this.handleAnimation("running");

    },

    // 动画暂停 / 启动

    handleAnimation(params) {

      this.$refs.cirula_origin.style.animationPlayState = params;

      let cirulaItem = document.querySelectorAll(".cirula_item");

      for (let i = 0; i < cirulaItem.length; i++) {

        cirulaItem[i].style.animationPlayState = params;

      }

    },

  },

  // 销毁定时器

  beforeDestroy() {

    window.clearInterval(this.timer);

  },

};

</script>

<style lang="less" scoped>

.cirularMenu {

  width: 100%;

  height: 100%;

  .cirula {

    width: 100%;

    height: 50%;

    position: relative;

    //  圆形转盘

    .cirula_box {

      width: 80%;

      height: 0;

      margin: 0 auto;

      margin-top: 68px;

      padding-top: 80%;

      position: absolute;

      left: 50%;

      top: 50%;

      transition: 0.3s;

      transform: translate(-50%, -50%);

      .cirula_origin {

        width: 100%;

        height: 0;

        padding-top: 100%;

        cursor: pointer;

        border-radius: 50%;

        position: absolute;

        top: 0;

        left: 0;

        animation: rolateCirula 20s infinite alternate linear;

        .cirula_item {

          cursor: pointer;

          margin-top: 40%;

          margin-left: 45%;

          position: absolute;

          animation: rolateItem 20s infinite alternate linear;

          img {

            width: 120px;

            height: 120px;

            margin-bottom: 10px;

            object-fit: contain;

          }

          p {

            margin: 0px;

            color: #fff;

            font-size: 28px;

          }

        }

      }

      // 转盘

      .cirula_service {

        width: 85%;

        height: 85%;

        position: absolute;

        top: 50%;

        left: 50%;

        margin-left: -1%;

        border-radius: 50%;

        border: 2px dashed #00c2ff;

        transform: translate(-50%, -50%);

        .cirula_service_border {

          width: 75%;

          height: 75%;

          position: absolute;

          top: 50%;

          left: 50%;

          border-radius: 50%;

          border: 2px solid #00c2ff;

          transform: translate(-50%, -50%);

        }

        .cirula_service_main {

          width: 60%;

          height: 60%;

          display: flex;

          position: absolute;

          align-items: center;

          top: 50%;

          left: 50%;

          border-radius: 50%;

          text-align: center;

          flex-direction: column;

          justify-content: center;

          border: 2px solid #00c2ff;

          transform: translate(-50%, -50%);

          background: rgba(0, 66, 87, 0.5);

          box-shadow: inset 0px 0px 60px 0px #00f2fb;

          img {

            width: 105px;

            height: 105px;

            object-fit: contain;

          }

          h4 {

            padding: 0;

            color: #fff;

            line-height: 1;

            font-size: 36px;

            font-weight: 500;

            margin: 12px auto;

          }

          p {

            color: #fff;

            font-size: 20px;

            line-height: 1.5;

          }

        }

      }

    }

  }

  //  联动详情

  .description {

    width: 100%;

    height: 45%;

    margin-top: 5%;

    overflow: hidden;

    .desc_title {

      width: 90%;

      height: 68px;

      display: flex;

      align-items: flex-end;

      justify-content: flex-start;

      background: url("~@/assets/image/screen/module_title-bg.png") no-repeat;

      background-size: 100% 100%;

      h3 {

        margin: 0;

        line-height: 1;

        font-size: 32px;

        color: #d9ffff;

        text-indent: 60px;

        margin-bottom: 25px;

      }

      span {

        line-height: 1;

        font-size: 20px;

        color: #d9ffff;

        margin-left: 25px;

        margin-bottom: 25px;

        color: rgba(217, 255, 255, 0.5);

      }

    }

    .desc_content {

      color: #fff;

      font-size: 18px;

      line-height: 1.5;

      margin-top: 40px;

      overflow-y: auto;

      height: calc(100% - 68px);

    }

  }

}

// 旋转动画

@keyframes rolateCirula {

  to {

    transform: rotate(360deg);

  }

}

@keyframes rolateItem {

  to {

    transform: rotate(-360deg);

  }

}

</style>

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值