uniapp上划喜欢下划不喜欢效果 By ChatGPT 3.5

作者: gavin 分类: uniapp 发布时间: 2023-09-08 13:46
<template>
  <view class="card-container" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">
    <view
      v-for="(card, index) in cards"
      :key="index"
      class="card"
      :style="{ height: cardHeight, backgroundColor: card.backgroundColor, transform: `translateY(${cardTranslateY(index)}px)`, opacity: cardOpacity(index), zIndex: cardZIndex(index) }"
    >
      {{ card.content }}
      <view
        class="overlay"
        :class="{ 'like-overlay': isLiking && index === currentCardIndex, 'dislike-overlay': isDisliking && index === currentCardIndex }"
      >
        {{ overlayText }}
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      cards: [
        { content: '卡片1', backgroundColor: '#FF5733' },
        { content: '卡片2', backgroundColor: '#33FF57' },
        { content: '卡片3', backgroundColor: '#5733FF' },
        // 添加更多卡片
      ],
      startY: 0,
      endY: 0,
      cardHeight: '200px', // 设置卡片高度
      currentCardIndex: 0,
      cardTranslateYOffset: 0, // 卡片的垂直位移
      isLiking: false,
      isDisliking: false,
    };
  },
  computed: {
    currentCard() {
      return this.cards[this.currentCardIndex];
    },
    overlayText() {
      if (this.isLiking) {
        return '喜欢';
      } else if (this.isDisliking) {
        return '不喜欢';
      } else {
        return '';
      }
    },
  },
  methods: {
    touchStart(event) {
      this.startY = event.changedTouches[0].clientY;
    },
    touchMove(event) {
      this.endY = event.changedTouches[0].clientY;
      this.cardTranslateYOffset = this.endY - this.startY;

      // 根据滑动方向切换文字提示
      this.isLiking = this.cardTranslateYOffset < -50; // 向上滑动
      this.isDisliking = this.cardTranslateYOffset > 50; // 向下滑动
    },
    touchEnd() {
      this.handleSwipe();
      this.resetOverlay();
    },
    handleSwipe() {
      const deltaY = this.endY - this.startY;
      if (deltaY > 100) {
        // 用户向下滑动足够远,执行不喜欢操作
        this.dislike();
      } else if (deltaY < -100) {
        // 用户向上滑动足够远,执行喜欢操作
        this.like();
      } else {
        // 滑动距离不够,卡片恢复原位
        this.cardTranslateYOffset = 0;
      }
    },
    like() {
      // 执行喜欢操作,例如显示下一个卡片
      // 可以在这里添加动画效果
      this.nextCard();
    },
    dislike() {
      // 执行不喜欢操作,例如显示下一个卡片
      // 可以在这里添加动画效果
      this.nextCard();
    },
    cardTranslateY(index) {
      // 计算卡片的垂直位移,只有当前卡片移动,其他卡片保持不变
      if (index === this.currentCardIndex) {
        return this.cardTranslateYOffset;
      } else {
        return 0;
      }
    },
    cardOpacity(index) {
      // 根据卡片的索引来计算透明度
      if (index === this.currentCardIndex) {
        return 1; // 当前卡片完全不透明
      } else {
        return 1; // 其他卡片完全透明
      }
    },
    cardZIndex(index) {
      // 根据卡片的索引来计算 z-index
      if (index === this.currentCardIndex) {
        return 2; // 当前卡片的 z-index 为 2
      } else if (index === this.currentCardIndex + 1) {
        return 1; // 下一张卡片的 z-index 为 1
      } else {
        return 0; // 其他卡片的 z-index 为 0
      }
    },
    nextCard() {
      // 显示下一个卡片
      if (this.currentCardIndex < this.cards.length - 1) {
        this.currentCardIndex++;
      } else {
        // 已经到最后一张卡片,回到第一张卡片
        this.currentCardIndex = 0;
      }
      this.cardTranslateYOffset = 0; // 重置垂直位移
    },
    resetOverlay() {
      // 重置文字提示状态
      this.isLiking = false;
      this.isDisliking = false;
    },
  },
};
</script>

<style>
.card-container {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 400px; /* 卡片容器的高度 */
  overflow: hidden; /* 隐藏溢出的卡片部分 */
}

.card {
  width: 80%; /* 卡片的宽度为容器的80% */
  box-sizing: border-box;
  padding: 20px;
  color: white;
  font-size: 24px;
  position: absolute;
  transition: transform 0.3s ease, opacity 0.3s ease; /* 添加过渡效果 */
  border-radius: 10px; /* 添加圆角效果 */
  left: 50%; /* 将卡片居中对齐 */
  margin-left:-40%;
  transform: translateX(-50%);
  opacity: 0.8; /* 初始透明度 */
}

.overlay {
  position: absolute;

  left: 50%;
  transform: translateX(-50%);
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  padding: 5px 10px;
  border-radius: 5px;
  font-size: 16px;
  display: none;
}

.like-overlay {
  display: block;
  top: -40px;
  animation: fadeIn 0.3s ease;
}

.dislike-overlay {
  display: block;
  bottom: -40px;
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
</style>