微信小程序叠式轮播图实现

方式一:叠式轮播图

代码实现 js

/**
 * 8月初写的了。。代码都没啥印象了,刚刚打开,发现位置是写死了的7个,不过可以动态去设置。。
 * 整体来说也不复杂,7个位置,相当于是7个状态,各个状态之间轮换,以下的列表都是从左往右的,最中间的也是界面当前正中间的。
 * 用currentIndex这个变量来控制当前翻页情况,也就是本来的7个位置处于什么状态。
 */
// 位置列表
const posOrgArray = [-360, -240, -120, 0, 120, 240, 360]
let posArray = [-360, -240, -120, 0, 120, 240, 360]
// 缩放列表
let scaArray = [.8, .8, .9, 1, .9, .8, .8]
// 透明度列表
let opaArray = [0, 1, 1, 1, 1, 1, 0]
// 高度列表
let indArray = [1, 2, 3, 4, 3, 2, 1]
// 当前位置列表
let curPosArray = [-360, -240, -120, 0, 120, 240, 360]
// 当前缩放列表
let curScaArray = []
// 当前透明度列表
let curOpaArray = []
// 当前高度列表
let curIndArray = []
let left = 0


// 是否可点击,控制点击频率
let canClick = true

// px和rpx转换比例,用于横向滑动的时候计算滑动距离(rpx)
let screenRate = 1

Page({

  data: {
    // 背景图列表
    imgArray: ["imgs/image1.png", "imgs/image2.png", "imgs/image3.png", "imgs/image4.png", "imgs/image5.png", "imgs/image6.png", "imgs/image7.png"],
    // 文字列表,和前面的图位置对应
    textArray: ["页面1", "页面2", "页面3", "页面4", "页面5", "页面6", "页面7"],
    animation: [],
    // 当前位置,这个。。和默认位置有关,不要随便改哦。
    currentIndex: 7,
    // index高度数组,中间的最高嘛~ 因为wxml里用style控制,所以写到了 data 里
    indexArray: [1, 2, 3, 4, 3, 2, 1],
    // 指示点数组(哈哈哈,写在了这里,没加上去)
    indicatorArray: []
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    wx.getSystemInfo({
      success: (res) => {
        // 750除以屏幕宽度,得到转换比。因为API用的和得到的大部分的单位都是px,所以还是要转一下
        screenRate = 750 / res.screenWidth
      }
    })
    // 初始化动画,注意这个数组和 this.data.animation不是同一个,而是一一对应的关系
    this.animation = []
    for (let i = 0; i < 7; i++) {
      let animation = wx.createAnimation({
        duration: 500,
        timingFunction: 'ease-out',
      })
      this.animation.push(animation)
    }
    console.log('this.animation')
    console.log(this.animation)
  },

  tapItemFn(e) {
    console.log(e.currentTarget.dataset.text)
  },
  touchstart(e) {

    left = e.touches[0].pageX
  },

  touchmove(e) {
    // console.log(e)
    // 频率控制,一次移动完成后,才能进行下一次
    if (this.isMove) {
      return
    }
    let moveLength = (e.touches[0].pageX - left) * screenRate
    moveLength = moveLength > 60 ? 60 : moveLength
    moveLength = moveLength < -60 ? -60 : moveLength
    let rate = moveLength / 60
    if (rate == 1) { //从右往左滑
      this.isMove = true
      this.tapRight()
    } else if (rate == -1) { //从左往右滑
      this.isMove = true
      this.tapLeft()
    }
  },

  touchend(e) {
    setTimeout(() => {
      this.isMove = false
    }, 500)
  },

  // 往左移
  tapLeft() {
    if (!canClick) {
      return
    }
    canClick = false
    setTimeout(() => {
      canClick = true
    }, 500)
    // 界面往左移,效果相当于数组向右移一位。比如,本来在位置2,向左移,就是2的位置去了1,也就是位置1的参数给到了位置2。。以此类推
    console.log('posArray')
    console.log(posArray)
    curPosArray = this.rollRight(posArray, 1)
    console.log(curPosArray)
    console.log('scaArray')
    console.log(scaArray)
    curScaArray = this.rollRight(scaArray, 1)
    console.log(scaArray)
    console.log('opaArray')
    console.log(opaArray)
    curOpaArray = this.rollRight(opaArray, 1)
    console.log(opaArray)
    console.log('indArray')
    console.log(indArray)
    curIndArray = this.rollRight(indArray, 1)
    console.log(indArray)
    let animation = this.data.animation
    console.log('this.data.animation')
    console.log(this.data.animation)
    for (let j = 0; j < 7; j++) {
      this.animation[j].scale(curScaArray[j], curScaArray[j]).left(curPosArray[j] + 'rpx').opacity(curOpaArray[j]).step()
      animation[j] = this.animation[j].export()
    }
    console.log(this.data.currentIndex)
    let currentIndex = ++this.data.currentIndex == 70 ? 0 : this.data.currentIndex
    console.log(currentIndex)
    this.setData({
      animation: animation,
      currentIndex: currentIndex,
      indexArray: curIndArray
    })
  },

  tapRight() {
    if (!canClick) {
      return
    }
    canClick = false
    setTimeout(() => {
      canClick = true
    }, 500)
    curPosArray = this.rollLeft(posArray, 1)
    curScaArray = this.rollLeft(scaArray, 1)
    curOpaArray = this.rollLeft(opaArray, 1)
    curIndArray = this.rollLeft(indArray, 1)
    let animation = this.data.animation
    for (let j = 0; j < 7; j++) {
      this.animation[j].scale(curScaArray[j], curScaArray[j]).left(curPosArray[j] + 'rpx').opacity(curOpaArray[j]).step()
      animation[j] = this.animation[j].export()
    }
    let currentIndex = --this.data.currentIndex == 0 ? 70 : this.data.currentIndex
    this.setData({
      animation: animation,
      currentIndex: currentIndex,
      indexArray: curIndArray
    })
  },

  /**
   * 把数组参数往左移,第一个参数是要改变的数组,第二个参数是移动的次数
   * 保存位置0的,然后将数组整体左移,再把之前保存的位置0的值,赋值给数组末尾,下面的rollRight刚好反过来
   */
  rollLeft: function(array, times) {
    for (let time = 0; time < times; time++) {
      let length = array.length - 1
      let temp = array[0]
      for (let i = 0; i < length; i++) {
        array[i] = array[i + 1]
      }
      array[length] = temp
    }
    return array.concat()
  },

  rollRight: function(array, times) {
    for (let time = 0; time < times; time++) {
      let length = array.length - 1
      let temp = array[length]
      for (let i = length; i > 0; i--) {
        array[i] = array[i - 1]
      }
      array[0] = temp
    }
    return array.concat()
  }
})

json

{
  "navigationBarTitleText": "轮播图测试",
  "disableScroll": true
}

wxml

<view class="swiper-page" bindtouchmove="touchmove" bindtouchstart="touchstart" bindtouchend="touchend">
  <view wx:for="{{7}}" wx:key="index" class="swiper-container">
    <view class="item-container" style="z-index:{{indexArray[index]}}">
      <view class="item{{index}} item-common" animation="{{animation[index]}}" bindtap="tapItemFn" data-text="{{textArray[index]}}">
        <image class="background" src="{{imgArray[index]}}" mode='aspectFit'></image>
        <text class="item-text">{{textArray[index]}}</text>
      </view>
    </view>
  </view>
  <button bindtap="tapLeft" style="position:absolute;top:0;left:20rpx">往左滑</button>
  <button bindtap="tapRight" style="position:absolute;top:0;right:20rpx">往右滑</button>
</view>

wxss

page {
  width: 100%;
  height: 100%;
}

.swiper-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  /* border: 1rpx solid #000; */
  box-sizing: border-box;
}

.swiper-container {
  position: absolute;
  left: 375rpx;
  /* border: 1rpx solid #000; */
  box-sizing: border-box;
}

.item-common {
  position: absolute;
}

.background {
  width: 210rpx;
  height: 270rpx;
  vertical-align: top;
  box-shadow: 0rpx 0rpx 15rpx rgba(0, 0, 0, 0.5);
}

.item-text {
  position: absolute;
  top: 180rpx;
  left: 0rpx;
  width: 100%;
  color: white;
  font-size: 30rpx;
  text-align: center;
  /* border: 1rpx solid #000; */
  box-sizing: border-box;
}

.item-container {
  left: -105rpx;
  position: absolute;
  /* border: 1rpx solid #000; */
  box-sizing: border-box;
}

.item0 {
  left: -360rpx;
  transform: scale(0.8, 0.8);
  opacity: 0;
  /* border: 1rpx solid blue;
  box-sizing: border-box; */
}

.item1 {
  left: -240rpx;
  transform: scale(0.8, 0.8);
  opacity: 1;
  /* border: 1rpx solid green;
  box-sizing: border-box; */
}

.item2 {
  left: -120rpx;
  transform: scale(0.9, 0.9);
  opacity: 1;
  /* border: 1rpx solid red;
  box-sizing: border-box; */
}

.item3 {
  left: 0rpx;
  transform: scale(1, 1);
  opacity: 1;
  /* border: 1rpx solid yellow;
  box-sizing: border-box; */
}

.item4 {
  left: 120rpx;
  transform: scale(0.9, 0.9);
  opacity: 1;
  /* border: 1rpx solid pink;
  box-sizing: border-box; */
}

.item5 {
  left: 240rpx;
  transform: scale(0.8, 0.8);
  opacity: 1;
  /* border: 1rpx solid sienna;
  box-sizing: border-box; */
}

.item6 {
  left: 360rpx;
  transform: scale(0.8, 0.8);
  opacity: 0;
  /* border: 1rpx solid slategrey;
  box-sizing: border-box; */
}

小程序论坛看到比较好的Demo学习完后记录

转载自:微信开放社区 卢霄霄

————————————————————————————————————————————————————————

方式二: 使用swiper属性previous-margin,next-margin

                

js

Page({
  data: {
    imgUrls: [
      '....../File_/5a9a9b40e9289.jpg',
      '....../File_/5a9a9b454463d.jpg',
      '....../File_/5a9a9b47142c6.jpg'
    ],
    swiperIndex: 0
  },
  swiperChange(e) {
    this.setData({
      swiperIndex: e.detail.current
    })
  }
})

wxml

<view class='list'>
  <swiper indicator-dots="{{true}}" autoplay="{{false}}" previous-margin="{{'140rpx'}}" next-margin="{{'140rpx'}}" bindchange="swiperChange">
    <block wx:for="{{imgUrls}}" wx:key="{{index}}">
      <swiper-item>
        <image src="{{item}}" class="slide-image {{swiperIndex == index ? 'active' : ''}}" />
      </swiper-item>
    </block>
  </swiper>
</view>

wxss

swiper {
  width: 750rpx;
  height: 900rpx;
  /* border: 1rpx solid #000; */
}

swiper-item {
  padding-top: 100rpx;
  /* border: 1rpx solid #000; */
}

image {
  width: 375rpx;
  height: 667rpx;
  position: absolute;
  left: 50%;
  margin-left: -188rpx;
  /* border: 1rpx solid #e60012; */
}

image.active {
  transform: scale(1.14);
  transition: all 0.2s ease-in 0s;
  /* border: 1rpx solid blue; */
}

 

  • 2
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值