uni-app + vue3实现左滑不喜欢,右滑喜欢(触摸左右滑动)效果
<view class="swiper_wrap">
<view
class="swiper_item"
:style="{zIndex:(20-index)}"
v-for="(user, index) in swiper_data"
:key="index"
:data-id="index"
:animation="user.anim"
@touchstart="touchStart"
@touchmove="touchMove"
@touchend="touchEnd"
>
<view class="item_iflike">
<!-- 不喜欢按钮 -->
<view class="item_dislike" :style="{display: user.likestate == -1? 'block' : 'none'}">
<img src=""/>
</view>
<!-- 喜欢按钮 -->
<view class="item_like" :style="{display: user.likestate == 1? 'block' : 'none'}">
<img src="" />
</view>
</view>
<!-- 内容 -->
<view class="item_info">名字:{{user.name}}</view>
</view>
</view>
<script setup lang="ts">
import { ref } from "vue";
let startX = 0; // 滑动开始x轴的位置
let startY = 0; // 滑动开始y轴的位置
let moveX = 0; // 滑动X轴的位置
let moveY = 0; // 滑动Y轴的位置
let like_state = 0; // 左滑:-1; 没滑动: 0; 右滑动: 1
let currentIndex = -1; // 当前滑动的卡片index
let skewDeg = 0; // 当前滑动卡片的倾斜度
// TODO 请求后端获取卡片列表
let swiper_data = ref([
{
name: "1",
likestate: 0,
anim: null
},
{
name: "2",
likestate: 0,
anim: null
},
{
name: "3",
likestate: 0,
anim: null
},
]);
// 开始触摸:记录位置
const touchStart = (event: any) => {
// console.log(event);
startX = event.touches[0].pageX;
startY = event.touches[0].pageY;
};
// 触摸开始滑动
const touchMove = (event: any) => {
let currentX = event.touches[0].pageX;
let currentY = event.touches[0].pageY;
let movex = currentX - startX;
let movey = currentY - startY;
let text = "";
let currentindex = event.currentTarget.dataset.id;
let state = 0; // 左滑:-1; 没滑动: 0; 右滑动: 1
if (Math.abs(movex) > Math.abs(movey)) {
// 左右滑动
if (movex < -50) {
text = "左滑";
state = -1;
// todo 不喜欢的处理
} else if (movex > 50) {
text = "右滑";
state = 1;
// todo 喜欢的处理
}
skew(currentindex, movex, movey);
} else {
// 上下方向滑动
if (movey < 0) text = "上滑";
else if (movey > 0) text = "下滑";
}
// 改变swiper_data属性
// swiper_data[currentindex]["text"] = text;
swiper_data.value[currentindex]["likestate"] = state;
like_state = state;
currentIndex = currentindex;
moveX = movex;
moveY = movey;
};
// 触摸结束
const touchEnd = (event: any) => {
if (Math.abs(moveX) > 120) {
// 隐藏
hidden()
} else {
let anim = uni.createAnimation({
duration: 300,
timingFunction: "ease-in-out",
});
anim.rotate(0).step();
swiper_data.value[currentIndex]["anim"] = anim.export();
swiper_data.value[currentIndex]["likestate"] = 0;
}
};
// 触摸卡片倾斜
const skew = (index: number, x: number, y: number) => {
let anim = uni.createAnimation({
duration: 500,
timingFunction: "linear",
});
// swiper_data.value[index]['anim'] = anim
if (Math.abs(x) < 180) {
skewDeg = x / 4;
anim.rotate(skewDeg).step();
swiper_data.value[index]["anim"] = anim.export();
}
};
// 触摸结束, 卡片消失
const hidden = () => {
let anim = uni.createAnimation({
duration: 400,
timingFunction: "ease-in-out",
});
if (like_state == -1) {
anim.translate(-400, -400);
} else if (like_state == 1) {
anim.translate(400, -400);
}
anim.rotate(skewDeg).opacity(0).step();
swiper_data.value[currentIndex]["anim"] = anim.export();
};
</script>
.swiper_wrap {
width: 100%;
height: 100%;
position: relative;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
.swiper_item {
width: 90vw;
height: 100%;
position: absolute;
background-color: rgb(61, 218, 139);
border-radius: 10px;
.item_iflike {
position: relative;
margin: 0 auto;
width: 18rem;
height: 2rem;
padding-top: 1rem;
.item_dislike image {
position: absolute;
width: 3rem;
height: 3rem;
background: url(../../static/img/like.png);
// background-color: red;
background-position: -22.15rem;
background-size: 16rem;
border-radius: 5rem;
}
.item_like image {
position: absolute;
right: 0;
width: 3rem;
height: 3rem;
background: url(../../static/img/like.png);
// background-color: red;
background-position: -44.05rem;
background-size: 16rem;
border-radius: 5rem;
}
}
.item_info {
position: absolute;
bottom: 0;
width: 90vw;
height: 60vh;
// background-color: green;
}
}
}
需要把动画变量,以及后端请求的数据进行监听