<template>
<div class="banner" >
<div class="bg" ref="bg">
<transition name="fade">
<div class="imgs" v-for="(item, i) in banner" v-if="i===mark" :class="isSwitch ? 'animation':''" :style="i == mark ? 'opacity: 1;':'opacity: 0;z-index:3'" :key="i" @mouseover="stopTimer" @mouseout="startTimer">
<img :src="item.picUrl" class="img1" alt="" >
</div>
</transition>
</div>
<div class="page" v-if="banner.length >1">
<ul class="dots">
<li class="dot-active" v-for="(item, i) in banner" :class="{ 'dot':i!=mark }" :key="i" @click="change(i)"></li>
</ul>
</div>
</div>
</template>
<script>
export default {
data () {
return {
// 模拟banner数据
isSwitch: false,
banner: [
{
type: 0,
productId: 150642571432835,
fullUrl: '',
picUrl: require('@/assets/banner.jpg'),
},{
type: 0,
productId: 150642571432835,
fullUrl: '',
picUrl: require('@/assets/logo.png'),
}
],
mark: 0,
time:'',
timer:''
}
},
methods: {
autoPlay () {
this.$set(this,'isSwitch',true)
this.mark++
if (this.mark > this.banner.length - 1) {
// 当遍历到最后一张图片置零
this.mark = 0
}
this.time = setTimeout(this.animation, 2000)
},
animation(){
this.$set(this,'isSwitch',false)
clearTimeout(this.time)
},
play () {
// 每2.5s自动切换
this.timer = setInterval(this.autoPlay, 6000)
},
change (i) {
// this.$set(this,'isSwitch',false)
let that = this
clearInterval(this.timer)
if(that.mark !==i){
if(that.isSwitch){
that.$set(that,'isSwitch',false)
setTimeout(() => {
that.$set(that,'isSwitch',true)
that.mark = i
that.time = setTimeout(that.animation, 2000)
that.play()
}, 100);
} else{
that.$set(that,'isSwitch',true)
that.mark = i
that.time = setTimeout(that.animation, 2000)
that.play()
}
}
},
startTimer () {
this.timer = setInterval(this.autoPlay, 6000)
},
stopTimer () {
clearInterval(this.timer)
},
},
created () {
this.play()
}
}
</script>
<!-- Add 'scoped' attribute to limit CSS to this component only -->
<style lang="less" scoped>
ul li {
list-style: none;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.banner,
.banner span,
.banner div {
font-family: "Microsoft YaHei";
transition: all 0.3s;
transition-timing-function: linear;
}
.banner {
cursor: pointer;
perspective: 3000px;
position: relative;
z-index: 19;
margin: 0 auto;
width: 100%;
}
.bg {
position: relative;
width: 100%;
height: 509px;
border-radius: 10px;
visibility: visible;
animation: fadeInOut .7s ease;
-webkit-animation-name: fadeInOut;
-webkit-animation-timing-function: ease;
-webkit-animation-iteration-count: infinite;
-webkit-animation-duration: 0s;
-webkit-animation-direction: alternate;
& div {
height: 100%;
width: 100%;
}
}
.animation{
-webkit-animation-duration: 2s;
}
.imgs {
position:absolute;
}
.img1 {
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 0;
// border-radius: 10px;
}
.img2 {
display: block;
position: absolute;
width: 100%;
height: 100%;
bottom: 5px;
left: 0;
background-size: 95% 100%;
border-radius: 10px;
}
.img3 {
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 0;
border-radius: 10px;
}
.a {
z-index: 20;
transform: translateZ(40px);
}
.b {
z-index: 20;
transform: translateZ(30px);
}
.page {
position: absolute;
width: 1200px;
margin: 0 auto;
top: 409px;
left: 0;
right: 0;
bottom: 0;
z-index: 30;
.dots {
display: flex;
flex-direction: row;
align-items: center;
justify-content: left;
.dot-active {
box-sizing: content-box;
text-align: center;
float: left;
width: 48px;
height: 3px;
margin: 0 2px;
cursor: pointer;
background-color: #00C876;
padding: 30px 0;
background-clip: content-box;
position: relative;
transition: width .3s ease-out;
}
.dot {
background-color: #FFFFFF;
background-clip: content-box;
width: 36px;
}
}
}
@-webkit-keyframes fadeInOut {
0% {
opacity:0;
}
25% {
opacity:0.25;
}
100%{
opacity:1;
}
}
</style>
vue +less动画轮播banner
最新推荐文章于 2023-02-01 09:31:59 发布