想要实现的效果如下图。查了一些组件都没有类似的效果,于是使用原生的swiper组件写了一个。但是只有列表长度大于3才能保持当前项始终在中间显示的效果。
主要逻辑就是根据current(swiper 当前索引)计算三屏视图中的居中项下标 centerIndex,居中项为 (current + 1) % 列表长度。

wxml:
<view class="template-section-carousel">
<swiper class="swiper-section" circular="true" current="{{current}}" display-multiple-items="3" duration="300" bindchange="onSwiperChange">
<swiper-item wx:for="{{swiperList}}" wx:key="id">
<image class="card {{index === centerIndex ? 'active' : ''}}" src="{{item.imgUrl}}" mode="widthFix" data-current-swiper-id="{{item.id}}" />
</swiper-item>
</swiper>
<!-- 左右切换按钮 -->
<block>
<image src="/arrow-left.png" mode="widthFix" class="arrow left" bind:tap="handleArrowLeft" />
<image src="/arrow-right.png" mode="widthFix" class="arrow right" bind:tap="handleArrowright" />
</block>
</view>
css:
.template-section-carousel {
position: absolute;
z-index: 2;
width: 100%;
height: auto;
top: 910rpx;
left: 0;
.swiper-section {
width: 578rpx;
height: 282.67rpx;
margin: 0 auto;
swiper-item {
display: flex;
align-items: center;
justify-content: center;
}
.card {
width: 145.33rpx;
height: 208rpx;
overflow: hidden;
transform: scale(0.85);
transition: transform 300ms ease, opacity 300ms ease, box-shadow 300ms ease;
}
.card.active {
width: 197.33rpx;
height: 282.67rpx;
transform: scale(1);
}
}
.arrow {
position: absolute;
z-index: 3;
width: 26.67rpx;
height: auto;
top: 120rpx;
}
.left {
left: 35rpx;
}
.right {
right: 35rpx;
}
}
js:
Page({
data: {
current: 0,
centerIndex: 1,
swiperList: [
{ id: 1, imgUrl: '/template-1.png' },
{ id: 2, imgUrl: '/template-2.png' },
{ id: 3, imgUrl: '/template-1.png' },
{ id: 4, imgUrl: '/template-2.png' }
]
},
onShow() {
this.init()
},
/**
* 初始化
*/
init() {
this.updateNeighbors(this.data.current)
},
/**
* 轮播图切换,传入 current 计算中间可视项的 centerIndex
*/
onSwiperChange(e) {
const current = e.detail.current
this.updateNeighbors(current)
},
/**
* 最关键的部分,在这里计算居中项并加放大样式;
* 根据传入的 current(swiper 当前索引),计算三屏视图中的居中项下标 centerIndex,
* 并同步到数据;用于让中间项应用放大样式,保持“当前项始终居中放大”。
* 注意:此处采用 display-multiple-items=3 且 circular=true,居中项为 (current + 1) % 列表长度。
*/
updateNeighbors(current) {
const len = this.data.swiperList.length
const centerIndex = (current + 1) % len
this.setData({ current, centerIndex })
},
/**
* 切换上一张、下一张
*/
handleArrowLeft() {
const { current, swiperList } = this.data
const newCurrent = (current - 1 + swiperList.length) % swiperList.length
this.setData({ current: newCurrent })
this.updateNeighbors(newCurrent)
},
handleArrowright() {
const { current, swiperList } = this.data
const newCurrent = (current + 1) % swiperList.length
this.setData({ current: newCurrent })
this.updateNeighbors(newCurrent)
},
})
4462

被折叠的 条评论
为什么被折叠?



