微信小程序(原生)使用Swiper实现(商品详情)视频和图片轮播(仿京东/淘宝商品详情头部视频+图片轮播)
一、需求
1、如果第一是视频,不进行自动轮播
2、可以手动滑动切换
3、点击播放视频,也可以手动滑动切换
4、视频播放完后,自动轮播
5、视频可以点击暂停和全屏播放
二、最终效果
三、源码
播放icon使用了TDesign组件库
1、wxml
<swiper class="detail-banner" wx:if="{{details.images.length > 0}}" indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}" circular="{{circular}}" indicator-color="{{indicatorColor}}" indicator-active-color="{{indicatorActiveColor}}" style="background: #fff;"><swiper-item wx:for="{{bannerMsg}}" wx:for-item="item" wx:key="index"><view class='videocover' data-id="{{index}}" wx:if="{{item.type==2}}"><view class='videocoverbg'></view><t-icon name="play-circle" size="100rpx" class="playIcon" bindtap="videoPlay" wx:if="{{!controls}}" /></view><view wx:if="{{item.type==2}}"><video class='box-w block' id="video" src="{{item.url}}" show-center-play-btn="{{false}}" objectFit="cover" bindended="endPlay" controls="{{controls}}"></video></view><image class="detail-banner-img" src="{{item.url}}" data-src="{{item.url}}" wx:if="{{item.type==1}}"></image></swiper-item></swiper>
2、wxss
.detail-banner {width: 100%;height: 500rpx;padding: 0 0 10rpx 0;
}.detail-banner-img {width: 100%;height: 100%;
}/* video */.box-w {width: 100%;height: 500rpx;
}.videocover {width: 100%;overflow: hidden;
}.videocoverbg {position: absolute;left: 0;top: 0;right: 0;bottom: 0;background: rgba(0, 0, 0, 0.3);
}.playIcon {position: absolute;top: 50%;z-index: 2;left: 50%;width: 100rpx;height: 100rpx;background-color: #fff;border-radius: 50%;transform: translate(-50%, -50%);
}.videocover .cover {width: 100%;
}
3、js
Page({data: {details: {}, // 商品详情信息indicatorDots: true, // 是否显示面板指示点autoplay: false, // 自动播放interval: 3000, // 自动切换时间间隔duration: 400, // 滑动动画时长circular: true, //是否循环 是否采用衔接滑动indicatorColor: "lightgray", //指示点颜色indicatorActiveColor: "red", //当前选中的指示点颜色controls: false, // 是否显示播放icon},// 获取商品详情getDetail(spuId) {const selectedAddr = wx.getStorageSync('addressMsg')const storeId = selectedAddr.storeIdconst selectedAddrStr = selectedAddr.streetPromise.all([fetchGood(spuId, storeId), fetchActivityList(spuId, storeId)]).then((res) => {const [details, activityData] = res;const {video,images} = details;let bannerMsg = []bannerMsg = bannerMsg.concat(images)bannerMsg = bannerMsg.map(val => {return {type: 1,url: val}})if (video) {bannerMsg = [{ type: 2, url: video }, ...bannerMsg]}// console.log('bannerMsg', bannerMsg, images[0]);this.setData({details,bannerMsg});});},//预览图片previewImage(e) {console.log('预览图片', e)const current = e.currentTarget.dataset.src;wx.previewImage({current, // 当前显示图片的http链接 urls: this.data.bannerMsg// urls: this.data.imgUrls // 需要预览的图片http链接列表 })},// 播放videoPlay() {console.log("开始播放")this.setData({autoplay: false})let videoplay = wx.createVideoContext("video");videoplay.play()this.setData({controls: true})},// 结束播放endPlay() {console.log("结束播放")this.setData({controls: false,autoplay: true})},onShow() {this.getDetail();}
});
四、其他文章
基于ElementUi或Antd再次封装基础组件文档
vue3+ts基于Element-plus再次封装基础组件文档