小程序的swiper可以应付大部分的轮播需求。但有的时候为了迎合界面布局,需要特别一点的轮播,例如:层叠轮播(其实我太清楚它是层叠轮播还是旋转木马轮播哈,见谅,见谅);我先上效果图:
我自己在网上找了一些案例,然后我也跟着做了一个。说一下思路吧!初始需要给item们放置好位置以及各种层级,然后在切换滑动的过程中对设置的位置、层级、透明度进行替换,加上小程序的wx.createAnimation()动画效果
个人认为缺点(仅个人观点,望各位大佬指教)
主要定位分层,这些大家应该都知道,所以到这里的时候大家可能就会发现一个弊端,因为要定位分层,所以这个轮播的长度需要固定,不能随心配置(当然也可能是我技术不到家啊,如果有大佬有其他好的方法或者组件,欢迎回复或更正)。
我还是先上代码吧:(.wxml文件)
<view class="swiper-page" bindtouchmove="touchmove" bindtouchstart="touchstart" bindtouchend="touchend">
<view wx:for="{{imgArray}}" wx:key="index" class="swiper-container">
<view class="item-container" style="z-index:{{indexArray[index]}}">
<view class="item{{index}} item-common" animation="{{animation[index]}}" data-text="{{textArray[index]}}">
<image class="background" src="{{item.image}}" mode='aspectFit'></image>
<text class="item-text">{{item.text}}</text>
</view>
</view>
</view>
<view bindtap="tapLeft" style="position:absolute;top:0;left:20rpx">往左滑</view>
<view bindtap="tapRight" style="position:absolute;top:0;right:20rpx">往右滑</view>
</view>
(.wxss文件)
page {
width:100%;
height:100%;
}
.swiper-page {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
position:relative;
}
.swiper-container {
position: absolute;
width: 210rpx;
height: 270rpx;
left: 0rpx;
}
.item-common {
position: absolute;
}
.background {
width: 210rpx;
height: 270rpx;
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;
}
.item-container {
width: 210rpx;
height: 270rpx;
left: 0rpx;
position: absolute;
}
.item1 {
left: 120rpx;
transform: scale(.8, .8);
opacity: 1;
}
.item0 {
left: 280rpx;
transform: scale(1, 1);
opacity: 1;
}
.item2 {
left: 420rpx;
transform: scale(.8, .8);
opacity: 1;
}
(.js文件)
// 位置列表
let posArray = [ 280,120,420]
// 缩放列表
let scaArray = [1, .8, .8 ]
// 透明度列表
let opaArray = [1,.8, .8]
// 高度列表
let indArray = [ 1, 0.8, 0.8]
// 当前位置列表
let curPosArray = [ 280,120,420]
// 当前缩放列表
let curScaArray = []
// 当前透明度列表
let curOpaArray = []
// 当前高度列表
let curIndArray = []
let left = 0
// 是否可点击,控制点击频率
let canClick = true
// px和rpx转换比例,用于横向滑动的时候计算滑动距离(rpx)
let screenRate = 1
Page({
data: {
imgArray: [{
image:'imgs/image1.png',
text:'页面1'
},{
image:'imgs/image2.png',
text:'页面2'
},{
image:'imgs/image3.png',
text:'页面3'
}],
animation: [],
indexArray: [2,1,1]
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
wx.getSystemInfo({
success: (res) => {
screenRate = 750 / res.screenWidth
}
})
this.animation = []
for (let i = 0; i < 3; i++) {
let animation = wx.createAnimation({
duration: 500,
timingFunction: 'ease-out',
})
this.animation.push(animation)
}
},
touchstart(e) {
left = e.touches[0].pageX
},
touchmove(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.tapLeft()
} else if (rate == -1) { //从左往右滑
this.isMove = true
this.tapRight()
}
},
touchend(e) {
setTimeout(()=>{
this.isMove = false
},500)
},
// 往左移
tapLeft() {
if (!canClick) {
return
}
canClick = false
setTimeout(() => {
canClick = true
}, 500)
curPosArray = this.rollRight(posArray, 1)
curScaArray = this.rollRight(scaArray, 1)
curOpaArray = this.rollRight(opaArray, 1)
curIndArray = this.rollRight(indArray, 1)
let animation = this.data.animation
for (let j = 0; j < 3; j++) {
this.animation[j].scale(curScaArray[j], curScaArray[j]).left(curPosArray[j] + 'rpx').opacity(curOpaArray[j]).step()
animation[j] = this.animation[j].export()
}
this.setData({
animation: animation,
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 < 3; j++) {
this.animation[j].scale(curScaArray[j], curScaArray[j]).left(curPosArray[j] + 'rpx').opacity(curOpaArray[j]).step()
animation[j] = this.animation[j].export()
}
this.setData({
animation: animation,
indexArray: curIndArray
})
},
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()
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function() {
}
})