一、实现效果
二、实现原理
1.css的var()函数
var() 函数用于插入自定义属性的值,而不是另一个属性的值的任何部分。
语法:
var(custom-property-name, value)
2.利用行内样式,区分不同样式
获取每一项的值
style="--index:{{item.zIndex}};--left:{{item.mLeft}}"
设置不同的缩放大小,层级高低,相对居中的位置
transform: scale(calc(0.5 + var(--index) / 10));
margin-left: calc(var(--left) * 100rpx - 150rpx);
z-index: var(--index);
3.初始化数据,为数据设置相应的z-index和mleft
4.结合事件:bindtouchmove,bindtouchstart,bindtouchend
bindtouchmove 手指触摸开始移动 bindtouchstart 手指触摸开始触动 bindtouchend 手指触摸动作结束
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset,touches。 事件的使用方式
事件分为冒泡事件和非冒泡事件:
冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
3.实现代码
<!-- 堆叠式轮播 -->
<view class="swiper-box" bindtouchmove="tauchMove" bindtouchstart="tauchStart" bindtouchend="tauchEnd">
<view class="item-box {{item.zIndex==1?'none':''}}" wx:for="{{swiperList}}" wx:key="index" style="--index:{{item.zIndex}};--left:{{item.mLeft}}">
<view class="swiper-item">
<image src="{{item.url}}" mode="aspectFill" wx:if="{{item.type=='image'}}"></image>
</view>
</view>
</view>
//js代码
data: {
swiperList: [{
type: 'image',
url: 'https://gips3.baidu.com/it/u=3806027521,964485011&fm=3039&app=3039&f=JPEG?w=1024&h=1024'
}, {
type: 'image',
url: 'https://img2.baidu.com/it/u=2016376351,2047203948&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'
}, {
type: 'image',
url: 'https://img0.baidu.com/it/u=1462294052,803648181&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400'
}, {
type: 'image',
url: 'https://img2.baidu.com/it/u=2846291940,466884003&fm=253&fmt=auto?w=500&h=500'
}, {
type: 'image',
url: 'https://img0.baidu.com/it/u=3173832266,884877117&fm=253&fmt=auto?w=500&h=500'
}, {
type: 'image',
url: 'https://gips1.baidu.com/it/u=359283887,3433215152&fm=3039&app=3039&f=JPEG?w=1024&h=1024'
},
{
type: 'image',
url: '../images/bg.jpg'
},
],
// 滑动事件
onLoad: function (options) {
this.tauchSwiper('swiperList');
},
onShow: function () {
},
// 初始化tauchSwiper
tauchSwiper(name) {
let list = this.data[name];
for (let i = 0; i < list.length; i++) {
// Math.abs(x) 函数返回指定数字 “x“ 的绝对值
list[i].zIndex = parseInt(list.length / 2) + 1 - Math.abs(i - parseInt(list.length / 2))
list[i].mLeft = i - parseInt(list.length / 2)
}
this.setData({
swiperList: list
})
},
// tauchSwiper触摸开始
tauchStart(e) {
this.setData({
tauchStart: e.touches[0].pageX
})
},
// tauchSwiper计算方向
tauchMove(e) {
this.setData({
direction: e.touches[0].pageX - this.data.tauchStart > 0 ? 'right' : 'left'
})
},
// tauchSwiper计算滚动
tauchEnd(e) {
let direction = this.data.direction;
let list = this.data.swiperList;
if (direction == 'right') {
let mLeft = list[0].mLeft;
let zIndex = list[0].zIndex;
for (let i = 1; i < list.length; i++) {
list[i - 1].mLeft = list[i].mLeft
list[i - 1].zIndex = list[i].zIndex
}
list[list.length - 1].mLeft = mLeft;
list[list.length - 1].zIndex = zIndex;
this.setData({
swiperList: list
})
} else {
let mLeft = list[list.length - 1].mLeft;
let zIndex = list[list.length - 1].zIndex;
for (let i = list.length - 1; i > 0; i--) {
list[i].mLeft = list[i - 1].mLeft
list[i].zIndex = list[i - 1].zIndex
}
list[0].mLeft = mLeft;
list[0].zIndex = zIndex;
this.setData({
swiperList: list
})
}
},
wxss
* 轮播图 */
.swiper-item image,
.swiper-item video {
width: 100%;
display: block;
height: 100%;
margin: 0;
pointer-events: none;
}
image {
max-width: 100%;
display: inline-block;
position: relative;
z-index: 0;
}
.swiper-box {
height: 20vh;
position: relative;
max-width: 750rpx;
overflow: hidden;
box-sizing: border-box;
/* margin-top: 90rpx; */
}
.swiper-box .item-box {
position: absolute;
width: 300rpx;
height: 200rpx;
top: 0;
bottom: 0;
left: 50%;
margin: auto;
transition: all 0.2s ease-in 0s;
opacity: 1;
box-shadow: 0px 13rpx 12rpx rgba(0, 0, 0, .5);
border-radius: 15rpx;
overflow: hidden;
}
.swiper-box .item-box.none {
opacity: 0;
}
.swiper-box .item-box .swiper-item {
width: 100%;
height: 100%;
border-radius: 6rpx;
overflow: hidden;
}
.swiper-box .item-box {
transform: scale(calc(0.5 + var(--index) / 10));
margin-left: calc(var(--left) * 100rpx - 150rpx);
z-index: var(--index);
}