Vue实现带两个方向过渡效果的轮播图
Posted hans774882968
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue实现带两个方向过渡效果的轮播图相关的知识,希望对你有一定的参考价值。
网上有许多轮播图案例,但只有极少数做了两个方向的滑动过渡效果。而我就是其中一个!所以来关注hans774882968,看技术干货!
先看效果图
html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>轮播图图片切换</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<link rel="stylesheet" type="text/css" href = "./index.css" />
<style type="text/css"></style>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/vue/2.5.2/vue.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<body>
<main id="app" class="container">
<div class="img-wrap">
<div class="wrap" v-for="(item,idx) in imgs" :key="idx">
<transition :name="imgAnime">
<img v-show="curIdx === idx" :key="item.idx" :src="item.src" />
</transition>
</div>
<div class="left-btn" @click="imgChange(-1)"><</div>
<div class="right-btn" @click="imgChange(1)">></div>
</div>
</main>
<script src="./index.js"></script>
</body>
</html>
.img-wrap
是整个轮播图组件的根元素。.wrap
则是被绝对定位控制在我们期望的位置。
若干个图片,只有一个能显示,其他的应该display: none;
所以用v-show和curIdx
来控制。
CSS
body{
margin: 0;
background-color: wheat;
}
div{
box-sizing: border-box;
}
.container{
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.img-wrap{
width: 600px;
height: 225px;
position: relative;
overflow: hidden;/* 隐藏突出部分 */
}
.wrap{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
img{
width: 100%;
height: 100%;
}
/* right=左to右 */
.img-play-right-enter-active,.img-play-right-leave-active,
.img-play-left-enter-active,.img-play-left-leave-active{
transition: all .6s;
}
/* 左to右和右to左的类名呈现一个reverse的关系 */
.img-play-right-enter,.img-play-left-leave-to {
transform: translateX(100%);
}
.img-play-right-enter-to,.img-play-left-leave{
transform: translateX(0);
}
.img-play-right-leave,.img-play-left-enter-to{
transform: translateX(0);
}
.img-play-right-leave-to,.img-play-left-enter{
transform: translateX(-100%);
}
.left-btn,.right-btn{
position: absolute;
width: 32px;
height: 32px;
border-radius: 50%;
background-color: rgba(0,0,0,.2);
top: 50%;
margin-top: -12px;
font-size: 20px;
font-weight: bold;
color: white;
line-height: 29px;
text-align: center;
user-select: none;
cursor: pointer;
}
.left-btn{
left: 16px;
}
.right-btn{
right: 16px;
}
.wrap
被绝对定位控制在-100%、0%和100%(相对.img-wrap
的宽度)的位置,然后用translateX()
和vue提供的<transition>
来控制进入阶段(enter阶段)的起点、终点和离开阶段(leave阶段)的起点、终点。详细写法可以看代码的注释。
.img-wrap
用overflow: hidden;
来隐藏.wrap
的突出部分。
但还有一个问题没解决:怎么实现两个方向都有动画?参考https://www.cnblogs.com/gsgs/p/6698494.html,我们发现,直接动态修改<transition>
的name属性即可(注意,vue官方文档没有提到这个)。
.left-btn
和.right-btn
用绝对定位跑到期望的位置,然后进行一些样式上的处理,都是基本操作了。
JS
"use strict";
function main() {
let vm = new Vue({
el: '#app',
data() {
return {
imgs: [
{
idx: 0,
src: './imgs/1.jfif'
},
{
idx: 1,
src: './imgs/2.jfif'
},
{
idx: 2,
src: './imgs/3.jfif'
}
],
curIdx: 0,
timer: null,
imgAnime: 'img-play-right'
/* transition的name属性也可以动态变化~这一事实来自:
* https://www.cnblogs.com/gsgs/p/6698494.html */
}
},
mounted(){
this.newTimer()
},
methods: {
newTimer(){
this.timer = setInterval(() => {
this.imgChange(1)
},3000)
},
stopTimer(){
clearInterval(this.timer)
},
imgChange(v) {
this.imgAnime = v === -1 ? 'img-play-left' : 'img-play-right'
let l = this.imgs.length
this.curIdx = ((this.curIdx + v) % l + l) % l
this.stopTimer()
this.newTimer()
}
}
});
}
$(document).ready(main);
这里为了方便,对于没点击按钮时,自动放下一张图片的逻辑,也用this.imgChange(1)
实现了。这就导致每次setInterval调用1次就被清空。反正不影响效果,不想改代码了。
it is not bug, it is feature!
以上是关于Vue实现带两个方向过渡效果的轮播图的主要内容,如果未能解决你的问题,请参考以下文章