选项卡上下左右翻转动画效果
<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();
}