记 VUE项目中transform实现的一个仿3D效果旋转菜单

2,043 阅读1分钟

大屏项目仿3D效果旋转菜单

导航菜单v-for遍历渲染、通过绝对定位、transform过渡、根据菜单数量js动态计算旋转角度

GIF 2021-12-30 16-11-52.gif

配置初始数据

activeIndex: 0,//当前激活的菜单
times: 3,//默认激活菜单所在位置的旋转初始值

//菜单初始位置 (项目用的vw单位)
navTransData: [
  'translate3d(40vw, 5vw, 11vw) ',//第1个
  'translate3d(33vw, 12vw, 5vw) ',//第2个
  'translate3d(28vw, 14vw, 5vw) ',//第3个
  'translate3d(27vw, 22vw, 8vw) ',//第4个
  'translate3d(32vw, 3vw, 7vw) ',//第5个
  'translate3d(30vw, 10vw, 10vw) ',//第6个
  'translate3d(30vw, 18vw, 10vw) ',//第7个
],
//透明度
navOpacity: [1, 1, 1, 1, 0.7, 0.5, 0.5],

在生命周期函数中调用初始化一次,菜单通过v-for遍历绑定此方法

//旋转菜单
rotate(activeIndex) {
  let intervalTime = activeIndex - this.activeIndex //当前点击菜单 与上一个菜单的
  let transTime = Math.abs(intervalTime) === 4 ? 0.7 : 0.4
  //设置 旋转方向
  if (intervalTime > 0) {
    if (intervalTime === 6) {
      this.times = this.times - 1
    } else if (intervalTime === 5) {
      this.times = this.times - 2
    } else {
      this.times = this.times + intervalTime
    }
  } else {
    if (intervalTime === -6) {
      this.times = this.times + 1
    } else if (intervalTime === -5) {
      this.times = this.times + 2
    } else {
      this.times = this.times - Math.abs(intervalTime)
    }
  }

  this.activeIndex = activeIndex;
  let menuItem = document.querySelectorAll('.menu-item');
  let rotateDeg = 360 / this.menuItems.length;
  console.log(intervalTime,this.times,rotateDeg)
  
  menuItem.forEach((item, index) => {
    item.style.opacity = this.setStyle(activeIndex, this.navOpacity)[index]
    item.style.transition = `transform ${transTime}s linear`
    item.style.transform = `rotate(${-rotateDeg * index + this.times * rotateDeg}deg) ${this.setStyle(activeIndex, this.navTransData)[index]} rotate(${rotateDeg * index - this.times * rotateDeg}deg) rotateX(-65deg)`
  })
},
// 设置菜单transform对应位置
setStyle(index, initData) {
  let start = initData.slice(-index);
  let end = initData.slice(0, initData.length - index)
  return start.concat(end);
},