Loading

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;
        }
      }
    }

需要把动画变量,以及后端请求的数据进行监听

posted @ 2022-10-14 16:48  limene  阅读(326)  评论(0编辑  收藏  举报