遇到一個需求,需要在小程式內實現自動輪播的畫廊效果,如果是網頁版的話有大量現成的庫可以用,但小程式找了一圈沒找到有類似的庫,只好自己想辦法了。
在踩了多個坑之後找到最簡單的方法,就是用CSS animation來實現,但缺點就是不能手動拖動。
先貼一下效果圖
第一步 html
因為要無限滾動,所以放完在最後一個圖之後需要切換回第一個圖。為了讓使用者感知不到這個切換過程,需要將最開始圖片複製後末尾,小程式裡把wx:for
複製一遍就行了,注意要修改wx:key
的值,避免重複。
為啥是複製全部圖片呢,主要是因為keyframes
的值不能動態設定,複製全部後只需要將end
進度值設定為-50%即可。
<view class="series">
<view
style="animation: {{duration}}ms scroll-animation linear infinite;width: {{seriesWidth*2}}rpx"
class="images">
<view class="row" wx:for="{{productSeries}}" wx:key="{{index}}">
<image
wx:for="{{item}}"
wx:for-item="img"
wx:for-index="imgIndex"
wx:key="{{img + imgIndex}}"
src="{{img}}"
></image>
<image
wx:for="{{item}}"
wx:for-item="img"
wx:for-index="imgIndex"
wx:key="{{img + imgIndex}}-extra"
src="{{img}}"
></image>
</view>
</view>
</view>
複製程式碼
第二步 css
CSS動畫很簡單,讓gallery轉動到-50%的時候跳回0%,並設定infinite
。使用style
而非class
的原因是畫廊總長不確定,動畫的時長根據圖片數量來設定。width
也是需要動態設定,自動計算的width
會有問題。
.series {
overflow: hidden;
.images {
min-width: 100%;
.row {
white-space: nowrap;
line-height: 1;
&:last-child {
transform: translateX(-100rpx);
}
}
image {
width: 180rpx;
height: 180rpx;
margin: 0 10rpx 8rpx 0;
}
}
}
@keyframes scroll-animation {
from {
transform: translateX(0);
}
to {
transform: translateX(-50%);
}
}
複製程式碼
第三步 js
我們還需要通過js計算動畫時長和view的長度,數字190
是image width
+ margin-right
的值。最後要再減一次margin-right
的原因我也不確定,但不減這個值的話動畫最後會有一點卡頓的感覺,顯得不太流暢,希望有大佬解答一下原理。
data = {
productSeries: [
[
'/images/house1.png',
'/images/house2.png',
'/images/house3.png',
'/images/house2.png',
'/images/house3.png',
'/images/house4.png'
],
[
'/images/house1.png',
'/images/house2.png',
'/images/house3.png',
'/images/house2.png',
'/images/house3.png',
'/images/house4.png'
]
],
speed: 40,
seriesWidth: 400,
duration: 60000
}
onShow() {
if (this.productSeries[0].length > 4) {
this.seriesWidth = 190 * this.productSeries[0].length - 10
this.duration = Math.floor(this.seriesWidth / this.speed * 1000)
} else { // 當一行圖片太少時就沒必要加動畫了
this.seriesWidth = null
this.duration = 0
}
}
複製程式碼