css+js 选项卡动画效果

发布时间:2023年12月18日

选项卡上下左右翻转动画效果

<template>
  <div class="web-box">
    <div class="topTitle">
      <div class="topTitle1">标题标题</div>
    </div>
    <div class="info-wrap">
      <div style="width: 100%;height: 100%;">
        <div class="system-list" v-if="navList.length>0">
          <el-carousel :loop="false" indicator-position="none" arrow="always" :autoplay="false"
                       style="width: 100%;height: 100%;">
            <el-carousel-item class="nav-list-1" v-for="(item,index) in navList" :key="index">
              <div class="nav-item" :title="b.sysName" v-for="(b,i) in item" :key="i">
                <div class="change-box" v-if="b.hasAuth">
                  <div class="picBox">
                    <div class="show nav-item-content">
                      <div class="nav-item-left">
                        <img class="sysIcon" :src="imgBaseUrl+b.sysIcon"/>
                      </div>
                      <div class="nav-item-right">
                        <div class="nav-item-name">{{b.sysName}}</div>
                      </div>
                    </div>
                    <div class="hide">
                      <div class="hide-name">{{b.sysName}}</div>
                      <div class="hide-text" @click="clickNav(b)">立即进入 ></div>
                    </div>
                  </div>
                </div>
                <div class="picBox" v-else>
                  <div class="show nav-item-content gray">
                    <div class="nav-item-left">
                      <img class="sysIcon" :src="imgBaseUrl+b.sysIcon"/>
                    </div>
                    <div class="nav-item-right">
                      <div class="nav-item-name">{{b.sysName}}</div>
                    </div>
                  </div>
                </div>
              </div>
            </el-carousel-item>
          </el-carousel>
        </div>
        <div class="system-list" v-else>
          <el-empty :image-size="50" description="暂无数据"></el-empty>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import Swiper from 'swiper'; // 注意引入的是Swiper
  import 'swiper/css/swiper.min.css' // 注意这里的引入
  import $ from 'jquery';
  import { Index } from '@/components/Active/active'
  export default {
    name: "Index",
    data() {
      return {
        
        title: '',
        content: '',
        navList: [],
        navIndex: 0,
        nowList: [
            {hasAuth:true,sysIcon:'xxx.png',sysName:'xxx'},
            {hasAuth:true,sysIcon:'xxx.png',sysName:'xxx'},
            {hasAuth:true,sysIcon:'xxx.png',sysName:'xxx'},
            {hasAuth:true,sysIcon:'xxx.png',sysName:'xxx'},
            {hasAuth:true,sysIcon:'xxx.png',sysName:'xxx'},
            {hasAuth:true,sysIcon:'xxx.png',sysName:'xxx'},
        ]
      };
    },
    // 监听属性 类似于data概念
    computed: {

    },
    created() {
      this.getConfigData();
    },
    methods: {
      //系统应用
      getConfigData() {
          let dataList = this.nowList;
          let nowList = [];
          let arr = [];
          //每18个一页,多余的进入下一个
          for (let i = 0; i < dataList.length; i++) {
              arr.push(dataList[i]);
              if (i % 18 === 17 || i === dataList.length - 1) {
                  nowList.push(arr);
                  arr = [];
              }
          }
          this.navList = nowList;
          setTimeout(() => {
              new Index($(".system-list .change-box"))
              this.mySystemSwiper()
          })
      },
      mySystemSwiper() {
        let mySystemSwiper = new Swiper('.system-list', {
          slidesPerView: 5,
          navigation: {
            nextEl: '.swiper-button-next', // 右按钮
            prevEl: '.swiper-button-prev', // 左按钮
          },
        })
      },
    },
  };
</script>

<style scoped lang="scss">
  @import '~@/components/Active/active.css';
  .web-box {
    width: 100%;
    height: calc(100vh - 50px);
    background: #f4f9ff;
    box-sizing: border-box;
    overflow: hidden;
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    .topTitle{
      width: 100%;
      height: 33vh;
      background-image: url("../assets/images/index/topbg.png");
      background-size: 100% 100%;
      display: flex;
      align-items: flex-end;
      justify-content: center;
      .topTitle1{
        width: 12.4vw;
        height: 4.23vh;
        text-align: center;
        line-height: 4.23vh;
        background-image: url("../assets/images/index/titleBg.png");
        background-size: 100% 100%;
        font-size: 1.66vh;
        letter-spacing: 0.09vw;
        color: #3c4b70;
        font-weight: bolder;
      }
    }
      .info-wrap {
        width: 83.07vw;
        height: 57vh;
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        background-color: #ffffff;
        border-radius: 1vh;
        box-shadow: -5px 5px 10px 0px rgba(86, 113, 207, 0.25);

        .system-list {
          margin-top: 2vh;
          width: 100%;
          height: calc(100% - 4.54vh);
          box-sizing: border-box;
          overflow: hidden;

          .el-carousel {
            padding: 0 3.5vw;
          }

          .nav-list-1 {
            width: 100%;
            height: 100%;
            display: flex;
            flex-wrap: wrap;
            align-content: start;
            padding-top: 3vh;

            .nav-item {
              width: 11.67vw;
              height: 11.04vh;
              margin:2vh 0.5vw;
              cursor: pointer;
              position: relative;
              .change-box, .picBox{
                width: 100%;
                height: 100%;
              }
              .nav-item-content{
                width: 100%;
                height: 100%;
                display: flex;
                align-items: center;
                padding: 0 0.5vw;
                background-size: 100% 100%;
              }
              .nav-item-left {
                width: 4vw;
                height: 4vw;
                display: flex;
                align-items: center;
                justify-content: center;

                .sysIcon {
                  width: 3vw;
                  height: 3vw;
                }

              }

              .gray{
                background-image: url("../assets/images/index/bg2.png") !important;
                .nav-item-left{
                  filter: grayscale(95%);
                }
                .nav-item-right{
                  color: #aeadad;
                }

              }

              .nav-item-right {
                width: 7vw;
                height: 100%;
                display: flex;
                flex-wrap: wrap;
                align-items: center;
                padding: 1vh 0.5vw 1vh 1vw;

                .nav-item-name {
                  width: 5.5vw;
                  font-size: 1.5vh;
                  font-weight: bolder;
                }

                .nav-item-text {
                  width: 4vw;
                  height: 2vh;
                  line-height: 2vh;
                  text-align: center;
                  cursor: pointer;
                  background-color: rgba(255, 255, 255, 0.34);
                  border-radius: 0.8vh;
                  font-size: 1.2vh;
                }
              }

              &:nth-child(2n+1) .nav-item-content{
                color: #645b97;
                background-image: url("../assets/images/index/1.png");
              }

              &:nth-child(2n+2) .nav-item-content{
                color: #965c41;
                background-image: url("../assets/images/index/2.png");
              }

              &:nth-child(2n+3) .nav-item-content{
                color: #405f9a;
                background-image: url("../assets/images/index/3.png");
              }

              &:nth-child(2n+4) .nav-item-content{
                color: #a27a2d;
                background-image: url("../assets/images/index/4.png");
              }

              &:nth-child(2n+5) .nav-item-content{
                color: #257856;
                background-image: url("../assets/images/index/5.png");
              }

              &:nth-child(2n+6) .nav-item-content{
                color: #a27a2d;
                background-image: url("../assets/images/index/4.png");
              }

              &:nth-child(2n+7) .nav-item-content{
                color: #965c41;
                background-image: url("../assets/images/index/2.png");
              }

              &:nth-child(2n+8) .nav-item-content{
                color: #257856;
                background-image: url("../assets/images/index/5.png");
              }

              &:nth-child(2n+9) .nav-item-content{
                color: #645b97;
                background-image: url("../assets/images/index/1.png");
              }

              &:nth-child(2n+10) .nav-item-content{
                color: #405f9a;
                background-image: url("../assets/images/index/3.png");
              }
              &:nth-child(2n+11) .nav-item-content{
                color: #a27a2d;
                background-image: url("../assets/images/index/4.png");
              }

              &:nth-child(2n+12) .nav-item-content{
                color: #965c41;
                background-image: url("../assets/images/index/2.png");
              }

              &:nth-child(2n+13) .nav-item-content{
                color: #257856;
                background-image: url("../assets/images/index/5.png");
              }

              &:nth-child(2n+14) .nav-item-content{
                color: #645b97;
                background-image: url("../assets/images/index/1.png");
              }

              &:nth-child(2n+15) .nav-item-content{
                color: #405f9a;
                background-image: url("../assets/images/index/3.png");
              }
              &:nth-child(2n+16) .nav-item-content{
                color: #965c41;
                background-image: url("../assets/images/index/2.png");
              }

              &:nth-child(2n+17) .nav-item-content{
                color: #257856;
                background-image: url("../assets/images/index/5.png");
              }

              &:nth-child(2n+18) .nav-item-content{
                color: #645b97;
                background-image: url("../assets/images/index/1.png");
              }
            }
          }
        }
      }

      .swiper-button-prev {
        width: 2.86vw;
        height: 100%;
        background: #fff;
        left: 0;
        top: 0;
        margin: 0;
        color: #5e97ff;
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
        pointer-events: all !important;
        opacity: 1 !important;

        &:before {
          position: absolute;
          width: 0.94vw;
          height: 5.19vh;
          box-shadow: 0vh 0vh 0.37vh 0vh rgba(81, 103, 91, 0.4);
          border-radius: 0.37vh;
          font-size: 1.5vh;
          display: flex;
          flex-wrap: wrap;
          align-items: center;
          justify-content: center;
        }

        &.swiper-button-disabled:before {
          pointer-events: none !important;
          opacity: 0.4 !important;
        }

        &:after {
          content: "";
        }
      }

      .swiper-button-next {
        width: 2.86vw;
        height: 100%;
        background: #fff;
        right: 0;
        top: 0;
        margin: 0;
        color: #5e97ff;
        pointer-events: all !important;
        opacity: 1 !important;
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;

        &.swiper-button-disabled:before {
          pointer-events: none !important;
          opacity: 0.4 !important;
        }

        &:before {
          position: absolute;
          width: 0.94vw;
          height: 5.19vh;
          box-shadow: 0vh 0vh 0.37vh 0vh rgba(81, 103, 91, 0.4);
          border-radius: 0.37vh;
          font-size: 1.5vh;
          display: flex;
          flex-wrap: wrap;
          align-items: center;
          justify-content: center;
        }

        &:after {
          content: "";
        }
      }




    .el-carousel::v-deep {

      .el-carousel__container {
        height: 100%;
      }

      .el-carousel__arrow {
        width: 28px;
        height: 72px;
        border-radius: 3px;
        background: #f0f2f5;
        color: rgba(94, 151, 255, 0.86);
        font-size: 24px;
        box-shadow: #DDD 0 2px 4px 1px;
        border: 1px solid #e5e8e7;

        &.el-carousel__arrow--left {
          left: -51px;

          i.el-icon-arrow-left:before {
            content: "\e792";
          }
        }

        &.el-carousel__arrow--right {
          right: -51px;

          i.el-icon-arrow-right:before {
            content: "\e791";
          }
        }
      }
    }

  }
</style>


components-Active文件夹:

1.active.css

.picBox{
  position: relative;
  transform-style: preserve-3d;
  transform-origin: 50% 50% -6vh;
  animation: 500ms ease-out 0ms 1 normal forwards;
}
.-left .picBox{
  position: relative;
  transform-style: preserve-3d;
  transform-origin: 50% 50% -6vw;
  animation: 500ms ease-out 0ms 1 normal forwards;
}
.-bottom .picBox{
  position: relative;
  transform-style: preserve-3d;
  transform-origin: 50% 50% -6vh;
  animation: 500ms ease-out 0ms 1 normal forwards;
}
.-right .picBox{
  position: relative;
  transform-style: preserve-3d;
  transform-origin: 50% 50% -6vw;
  animation: 500ms ease-out 0ms 1 normal forwards;
}

.show,
.hide{
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
.hide{
  color:#fff;
  /*background-color:#3c4b70;*/
  text-align:center;
  transform: translate3d(0,0,-1px);
  background-image: url("../../assets/images/index/bg1.png");
  background-repeat: no-repeat;
  background-size: 100% 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  font-size: 1.6vh;
  font-weight: bolder;
  border-radius: 0.8vh;
  /* 3D空间内移动一个元素的位置 */
}
.hide .hide-name{


}
.hide .hide-text{
  margin: 1vh auto 0;
  width: 4vw;
  height: 2vh;
  line-height: 2vh;
  text-align: center;
  cursor: pointer;
  background-color: rgba(255, 255, 255, 0.25);
  border-radius: 0.8vh;
  font-size: 1.2vh;
}

.in-top .hide,
.out-top .hide
{
  transform-origin: 0% 100% !important;
  transform: translate3d(0, -100%, 0) rotate3d(1,0,0,90deg);
}
.in-top .picBox{
  animation-name: in-top;
  animation-play-state: running;
}
.out-top .picBox{
  animation-name: out-top;
  animation-play-state: running;
}
@keyframes in-top {
  from  {transform: rotate3d(0,0,0,0deg)}
  to    {transform: rotate3d(-1,0,0,90deg)}
}

@keyframes out-top {
  from {transform: rotate3d(-1,0,0,90deg)}
  to   {transform: rotate3d(0,0,0,0deg)}
}
.in-right .hide,
.out-right .hide {
  transform-origin: 0% 0%;
  transform: translate3d(100%, 0, 0) rotate3d(0,1,0,90deg);
}
.in-right .picBox{
  animation-name: in-right;
  animation-play-state: running;
}
.out-right .picBox{
  animation-name: out-right;
  animation-play-state: running;
}
@keyframes in-right {
  from  {transform: rotate3d(0,0,0,0deg)}
  to    {transform: rotate3d(0,-1,0,90deg)}
}

@keyframes out-right {
  from  {transform: rotate3d(0,-1,0,90deg)}
  to    {transform: rotate3d(0,0,0,0deg)}
}

.in-bottom .hide,
.out-bottom .hide {
  transform-origin: 0% 0%;
  transform: translate3d(0, 100%, 0) rotate3d(-1,0,0,90deg);
}
.in-bottom .picBox{
  animation-name: in-bottom;
  animation-play-state: running;
}
.out-bottom .picBox{
  animation-name: out-bottom;
  animation-play-state: running;
}
@keyframes in-bottom {
  from  {transform: rotate3d(0,0,0,0deg)}
  to    {transform: rotate3d(1,0,0,90deg)}
}
@keyframes out-bottom {
  from  {transform: rotate3d(1,0,0,90deg)}
  to    {transform: rotate3d(0,0,0,0deg)}
}
.in-left .hide,
.out-left .hide {
  transform-origin: 100% 0;
  transform: translate3d(-100%,0,0) rotate3d(0,-1,0,90deg);
}
@keyframes in-left {
  from  {transform: rotate3d(0,0,0,0deg)}
  to    {transform: rotate3d(0,1,0,90deg)}
}
@keyframes out-left {
  from  {transform: rotate3d(0,1,0,90deg)}
  to    {transform: rotate3d(0,0,0,0deg)}
}
.in-left .picBox{
  animation-name: in-left;
  animation-play-state: running;
}
.out-left .picBox{
  animation-name: out-left;
  animation-play-state: running;
}

2.active.js

Index.prototype.init = function () {
    var self = this;
    this.nodes = [];
    Array.prototype.slice.call(self.node, 0).forEach(function (item, index) {
        self.nodes.push(self.update(item));
        self.bindEvents(item, index);
    });
};
Index.prototype.update = function (item) {
    return {
        w: item.offsetWidth,
        h: item.offsetHeight,
        l: item.offsetLeft,
        t: item.offsetTop
    }
};
Index.prototype.bindEvents = function (item, index) {
    var self = this;
    item.onmouseenter = function (e) {
      e.stopPropagation()
      self.addClass(e, item, 'in', index);
      return false;
    }
    item.onmouseleave = function (e) {
      self.addClass(e, item, 'out', index);
      return false;
    }
};
Index.prototype.addClass = function (e, item, state, index) {
    var direction = this.getDirection(e, index);
    var class_suffix = '';
    var class_durr = '';
    switch (direction) {
        case 0:
            class_suffix = '-top';
            break;
        case 1:
            class_suffix = '-right';
            break;
        case 2:
            class_suffix = '-bottom';
            break;
        case 3:
            class_suffix = '-left';
            break;
    }
    item.className = 'change-box';
    item.classList.add(class_suffix);
    item.classList.add(state + class_suffix);
};
Index.prototype.getDirection = function (e, index) {
    var w = this.nodes[index].w,
        h = this.nodes[index].h,
        x = Math.abs(e.offsetX) - w / 2 ,
        y = Math.abs(e.offsetY) - h / 2 ,
        w1 = Math.abs(e.offsetX),
        h1 = Math.abs(e.offsetY),
        w2 = w - Math.abs(e.offsetX),
        h2 = h - Math.abs(e.offsetY);
        // 取到x,y两点坐标
  let d = 0;
  if (x <= 0 && y <= 0 && w1 - h1 < 0){
    d = 3
  }else if (x <= 0 && y > 0){
    if (w1 - h2 <= 0){
      d = 3
    }else{
      d = 2
    }
  }else if (x > 0 && y <= 0){
    if (w2 - h1 >= 0){
      d = 0
    }else{
      d = 1
    }
  }else if (x > 0 && y > 0){
    if (w2 - h2 >= 0){
      d = 2
    }else{
      d = 1
    }
  }
    return d;//d的数值用于判断方向上下左右。
};
export function Index(node) {
  this.node = node;
  this.init();
}

文章来源:https://blog.csdn.net/henghahouhei/article/details/134987586
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。