开发中,实现滑动切换轮播图是一个常见的需求。本文将介绍如何使用Touch手势来实现这一功能,为应用添加更加灵活和直观的界面交互效果。
效果
代码
<template>
<view class="sliding-swiper">
<view
class="item"
v-for="item in listNew"
:key="item.key"
:style="[itemStyle(item.sort)]"
:class="[
{
'prev-active': animateType == 'prev',
'next-active': animateType == 'next',
},
]"
@touchstart="touchstart($event)"
@touchmove="touchmove($event)"
@touchend="touchend($event)">
<view class="image-wrap">
<image
:src="item.image"
mode="aspectFill"
class="image"></image>
</view>
<view class="line-1 title"> {{ item.key }}-{{ item.title }} </view>
</view>
</view>
</template>
<script>
export default {
props: {
list: {
type: Array,
default: [],
},
},
data() {
return {
listNew: [],
animateType: "",
startX: 0,
moveX: 0,
curIndex: 0,
};
},
computed: {
itemStyle() {
return (index) => {
let translateX = `translateX(${index > 2 ? 0 : index * 20}%)`;
let scale = `scale(${1 - index / 10})`;
return {
transform: `${translateX} ${scale}`,
zIndex: `${this.listNew.length - index}`,
};
};
},
},
mounted() {
this.listNew = this.list.map((item, index) => {
item.sort = index;
item.key = `index_${index}`;
return item;
});
},
methods: {
change(type = "next") {
this.animateType = type;
let last = this.listNew.length - 1;
if (type == "next") {
this.curIndex = this.curIndex == last ? 0 : this.curIndex + 1;
this.listNew = this.listNew.map((item, index) => {
item.sort = index == this.curIndex ? 0 : item.sort == 0 ? last : item.sort - 1;
return item;
});
}
if (type == "prev") {
this.curIndex = this.curIndex == 0 ? last : this.curIndex - 1;
this.listNew = this.listNew.map((item, index) => {
item.sort = index == this.curIndex ? 0 : item.sort == last ? 0 : item.sort + 1;
return item;
});
}
this.$nextTick(() => {
this.animateType = "";
});
},
touchstart(e) {
this.startX = e.touches[0].clientX;
},
touchmove(e) {
this.moveX = e.touches[0].clientX;
},
touchend(e) {
let distance = this.moveX - this.startX;
this.change(distance < 100 ? "next" : "prev");
},
},
};
</script>
<style scoped lang="scss">
.sliding-swiper {
width: 100%;
display: grid;
.item {
// 使item重叠
grid-area: 1 / 1;
position: relative;
width: 80%;
transition: 0.3s;
border-radius: 10rpx;
overflow: hidden;
box-shadow: 0 4rpx 10rpx 0 rgba(0, 0, 0, 0.1);
&.prev-active {
animation: prev 0.5s ease-out;
}
@keyframes prev {
20% {
transform: translateX(-10%);
}
60% {
transform: translateX(-60%);
}
100% {
transform: translateX(-100%) scale(0.5);
}
}
&.next-active {
animation: next 0.5s ease-out;
}
@keyframes next {
20% {
transform: translateX(-80%);
}
60% {
transform: translateX(-20%) scale(1);
}
100% {
transform: translateX(0) scale(1);
}
}
.image-wrap {
width: 100%;
height: 240rpx;
box-sizing: border-box;
.image {
width: 100%;
height: 100%;
}
}
.title {
padding: 20rpx 10rpx;
width: 100%;
background-color: #fff;
box-sizing: border-box;
}
}
}
</style>
startX和moveX:记录触摸开始和移动中的X坐标。touchStart、touchMove和touchEnd:处理触摸事件,计算滑动距离,并根据滑动方向切换轮播图。
使用
<template>
<view class="content">
<navbar
backIconColor="#fff"
titleColor="#fff"
title="首页"
:isBack="true"
:background="{
background: 'linear-gradient(144deg,#af40ff,#4f46e5)',
}"></navbar>
<view style="display:flex;justify-content: space-between;box-sizing:border-box;background-color: #fff; margin: 20rpx;padding: 20rpx;border-radius: 10rpx;overflow: hidden;">
<view style="margin-right: 20rpx">
<image style="width: 160rpx; height: 160rpx" src="https://img0.baidu.com/it/u=360986675,4290492095&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500" mode="aspectFill" :lazy-load="true">
</image>
</view>
<view style="flex: 1">
<view style="margin-bottom: 20rpx;font-size: 30rpx;font-weight: bold;">
塞上风沙随马蹄,草原如画逐风吹。天高云淡思无限,万里胡天魂梦追。
</view>
<view style="width: 100%;padding-right: 20rpx;box-sizing: border-box;">
<slidingSwiper :list="slidingSwiperList"></slidingSwiper>
</view>
</view>
</view>
</view>
</template>
<script>
import navbar from "@/components/navbar/navbar.vue";
import slidingSwiper from "@/components/slidingSwiper/slidingSwiper.vue";
export default {
component: {
navbar,
slidingSwiper
},
data() {
return {
slidingSwiperList: [
{
image: "https://cdn.uviewui.com/uview/swiper/swiper2.png",
title: "昨夜星辰昨夜风,画楼西畔桂堂东",
},
{
image: "https://cdn.uviewui.com/uview/swiper/swiper1.png",
title: "身无彩凤双飞翼,心有灵犀一点通",
},
{
image: "https://cdn.uviewui.com/uview/swiper/swiper3.png",
title: "谁念西风独自凉,萧萧黄叶闭疏窗,沉思往事立残阳",
},
{
image: "https://img1.baidu.com/it/u=3915920165,3171018890&fm=253&fmt=auto&app=120&f=JPEG",
title: "星斗闪烁银河挂,人间天地一片霞",
},
{
image: "https://img1.baidu.com/it/u=922847932,2985620342&fm=253&fmt=auto&app=120&f=JPEG?w=1422&h=800",
title: "万里草原秋色多,风吹草低见牛羊",
},
{
image: "https://img2.huashi6.com/images/resource/2021/07/02/9094588h7p0.jpg?imageMogr2/quality/100/interlace/1/thumbnail/2000x%3E",
title: "海内存知己,天涯若比邻",
},
],
};
},
onLoad() {},
methods: {},
};
</script>