小程序滑动切换图片卡片特效

107 阅读2分钟

94951b13e0a7918964e30bc0792428c.png

需要实现这样的图片滑动效果,自己搜索的话没有看到一个类似的,哈哈应该是我检索问题。他们都推荐直接使用人家写好的组件,这里我们项目好像就这一块使用,就自己写一个好了。主要代码不到200行 轻量实现图片滑动特效

<template>
  <div class="s-container">
    <div class="s-title">
      <text>和好友一起推广,一起赚奖励</text>
    </div>
    <div class="s-main">
      <div class="s-item" 
      :class="{ 'active': currentIndex === index }" 
      v-for="(item, index) in shareInfo" :key="index"
      :style="{ right: item.right + '%', transform: 'translateX(' + deltaX + 'rpx)',
      transition: deltaX === 0 ? 'all .3s' : 'none'}"
      @touchstart="touchstart" 
      @touchmove="touchmove"
      @touchend="touchend">
        <image :src="item.posterImg"></image>
      </div>
    </div>
    <div class="s-footer">
      <div class="s-generate">
        <image src="../../static/images/icon/picture.png" />
        <text>生成海报</text>
      </div>
    </div>
  </div>
</template>
<script>
var http = require("../../../utils/http.js");
export default {
  onLoad() {
    uni.setNavigationBarTitle({
      title: "分享中心",
    });

    const systemInfo = uni.getSystemInfoSync();
    this.screenWidth = systemInfo.screenWidth;
  },
  async onShow() {
    // this.shareInfo = await this.initShareInfo();
  },
  data() {
    return {
      currentIndex: 0,
      screenWidth: 0,
      shareInfo: [
        {
          right: 0,
          posterImg: "../../static/images/icon/silder.png",
        },
        {
          right: 0,
          posterImg: "../../static/images/icon/silder.png",
        },
        {
          right: 0,
          posterImg: "../../static/images/icon/silder.png",
        },
        {
          right: 0,
          posterImg: "../../static/images/icon/silder.png",
        },
        {
          right: 0,
          posterImg: "../../static/images/icon/silder.png",
        },
        {
          right: 0,
          posterImg: "../../static/images/icon/silder.png",
        },
      ],
      startX: 0, // 触摸开始时的 X 坐标
      currentX: 0, // 触摸移动时的 X 坐标
      deltaX: 0, // 滑动的距离
    };
  },
  methods: {
    initShareInfo() {
      return new Promise((resolve) => {
        http.request({
          url: "/poster/list",
          method: "GET",
          data: {},
          callBack: (res) => {
            resolve(res);
          },
        });
      });
    },
    touchstart(event) {
      // 获取触摸开始时的 X 坐标
      this.startX = event.touches[0].clientX;
    },
    touchmove(event) {
      // 获取触摸移动时的 X 坐标
      this.currentX = event.touches[0].clientX;

      // 计算滑动的距离
      this.deltaX = this.currentX - this.startX;
    },
    touchend() {
      if (Math.abs(this.deltaX) > 70) {
        // 向右滑动
        if (this.deltaX > 0 && this.currentIndex > 0) {
          setTimeout(() => {
            this.currentIndex--;
          })
        }
        // 向左滑动
        if (this.deltaX < 0 && this.currentIndex < this.shareInfo.length - 1) {
          setTimeout(() => {
            this.currentIndex++;
          })
        }
      }
      this.deltaX = 0;
    },
  },
  watch: {
    currentIndex(newValue, oldValue) {
      if (oldValue > newValue) {
        this.shareInfo.forEach(v => v.right -= 100)
      }
      if (oldValue < newValue) {
        this.shareInfo.forEach(v => v.right += 100)
      }
    }
  },
};
</script>
<style>
page {
  background: linear-gradient(to bottom, #FFF4FA, #F4F4F4);
  overflow: hidden;
}
</style>

<style scoped>
.s-container {
  width: 100%;
  overflow: hidden;
}

.s-title {
  text-align: center;
  margin: 32rpx;
  background: linear-gradient(to right, #f02850, #ff280f);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.s-main {
  display: flex;
  width: 100%;
  box-sizing: border-box;
  padding: 0 116rpx;
  overflow: hidden;
}

.s-item {
  flex-shrink: 0;
  width: 520rpx;
  height: 800rpx;
  position: relative;
}

.s-item > image::after {
  content: '';
  display: block;
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  background-color: rgba(0, 0, 0, .4);
}

.s-item:last-child {
  margin: 0;
}

.s-item > image {
  width: 100%;
  height: 100%;
  transform: scale(.9);
  transition: all .3s;
}

.active > image {
  transform: scale(1);
}

.active > image::after {
  content: none;
}

.s-footer {
  position: fixed;
  bottom: 0;
  width: 100%;
  background-color: #fff;
  height: 160rpx;
  display: flex;
  justify-content: center;
  align-items: center;
}

.s-footer > .s-generate {
  width: 92%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  padding: 20rpx 0;
  border-radius: 62rpx;
  background: linear-gradient(to right, #F02850, #FF280F);
}

.s-footer > .s-generate > image {
  width: 52rpx;
  height: 52rpx;
}
</style>