<template> 
	<view class="swiperContent">    
		<swiper  
			@transition='transition'
            @change="change"  
            @animationfinish="animationfinish"
            :indicator-dots="indicatorDots"
            :indicator-active-color="indicatorActiveColor"
            :indicator-color="indicatorColor"
            :autoplay="autoplay && !videoPlaySataus"
            :current="activeCurrent"
            :interval="interval"
            :duration="duration"
            :circular="circular"
            :vertical="vertical"
            :previous-margin="effect3d ? effect3dMargin : previousMargin"
            :next-margin="effect3d ? effect3dMargin : nextMargin"
            :display-multiple-items="displayMultipleItems"
            :skip-hidden-item-layout="skipHiddenItemLayout"
            :style="{'height':swiperHeight+'px','border-radius': contentRadius,'overflow': 'hidden'}"
            :class="{
                'effect3D':effect3d && displayMultipleItems ==1,
                'effect3D-X':effect3d && !vertical, 
                'effect3D-Y':effect3d && vertical}"
            class="z-screen-swiper">  
			<swiper-item 
                class="z-swiper-item"   
                v-for="(item,index) in swiperList"
                :key="index" 
                :class="{'active-swiper':activeCurrent===index}"   
				:style="{'backgroundColor':`${bgColor}`}"
                @tap="clickItem(index)">  
                <view class="swiper-box" :style="{'backgroundColor':`${bgColorItem}`}"> 
                   <view 
					class="swiper-top" 
					:class="{'isFloat':topFloat}"
					@click="$emit('clickTop',{item,index})">
                        <slot :row='item' :index='index' name="top"> 
                            <!-- 顶部占位 无值则不占位  -->
							<view  v-if="item[topTextKey]" 
								:style="{'text-align':`${topTextAlign}`,
								'color':`${topColor}`,
								'background-color':`${topBackground}`}"> 
								<text v-text="item[topTextKey]"></text>
							</view>
                        </slot> 
                    </view>
                    <view class="swiper-content"> 
                        <slot :row='item' :index='index'>  
                            <image v-if="item.type==='image'"  :src="item[imageKey]" :mode='imgMode'>   
							<template v-if="item.type==='video'"> 
								<!-- :style="{'height':fullScreen ? '':'100%' }" 解决非全屏video显示问题 -->
								<video  
									:style="{'height':fullScreen ? '':'100%'}"
									@play='play'
									@pause='pause'  
									@timeupdate='timeupdate'
									:initial-time='item.currentTime || 0 '
								    enable-play-gesture
									:enable-progress-gesture='false'
								    x5-video-player-type="h5" 
								    x-webkit-airplay="allow" 
								    objectFit="contain" 
									webkit-playsinline="true" 
								    :id="`video_${index}`" 
								    :src="item[videoKey]" 
								    :poster="item.poster"
								    controls>
									<!-- #ifdef APP-PLUS -->
									  <cover-view :style="{ transform: 'translateX(' + moveX + 'px)'}"></cover-view> 
									<!-- #endif --> 
									</video>    
							</template>
                        </slot> 
                    </view>
                    <view 
						class="swiper-fotter" 
						:class="{'isFloat':fotterFloat}" 
						@click="$emit('clickBottom',{item,index})"> 
                        <slot :row='item' :index='index' name="fotter"> 
                            <!-- 底部盒子 不传值则不占位 --> 
							<view  v-if="item[bottomTextKey]" 
								:style="{'text-align':`${bottomTextAlign}`,
								'color':`${bottomColor}`,
								'background-color':`${bottomBackground}`}"> 
								<text v-text="item[bottomTextKey]"></text>
							</view>
                        </slot>
                    </view> 
                </view>
			</swiper-item> 
		</swiper>
        <!-- indicatorDots 原生指示器开启时不显示下面自定义指示器 
             vertical为true 垂直方向 只写了支持右侧定位
        -->
        <view 
            v-if="!indicatorDots" 
            :style="{'margin':`0 ${effect3dMargin}`}"
            :class="['dot',vertical ? 'verticalDot':`${indicatorPos}`]"
            > 
            <slot :list='list' :total='list.length' :activeIndex='activeCurrent' name="dot">
                <!-- 指示器自定义-返回列表数据list 数组长度total 选中项索引activeIndex --> 
                <template v-if="mode==='number'">
                    <view>
                        {{activeCurrent+1}}/{{list.length}}
                    </view>
                </template>
                <template v-else> 
                    <view   
                        v-for="(item,index) in list"
                        :key="index"  
                        @click="activeCurrent=index" 
                        :style="{'background-color': activeCurrent==index ? indicatorActiveColor:indicatorColor}"
                        :class="['dotItem',`${mode}`, `${ activeCurrent==index ? 'defautActive':'' }` ]"> 
                        <span v-if="mode ==='index'">{{index+1}}</span> 
                    </view> 
                </template> 
            </slot>
        </view>
	</view>
</template>

<script>
	export default {
		name:'z-swiper', 
		props: {  	   
            list:{//滑块视图容器数据
              type:Array,
              default:_=>[
                  {
					type:'video',  
					topTip:'顶部提示',
					poster:'https://img2.baidu.com/it/u=2141851239,1037607188&fm=26&fmt=auto&gp=0.jpg',
					src:'https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/a876efc0-4f35-11eb-97b7-0dc4655d6e68.mp4',
					bottomTip:'底部提示',
				  },
                  {type:'image', src:'https://img0.baidu.com/it/u=875130878,1196408569&fm=11&fmt=auto&gp=0.jpg'},
                  {type:'image', src:'https://img2.baidu.com/it/u=293682470,1155349941&fm=26&fmt=auto&gp=0.jpg'},
                  {type:'image', src:'https://img0.baidu.com/it/u=3464142916,229554071&fm=26&fmt=auto&gp=0.jpg'},
                  {
					type:'video', 
					currentTime:120,//初始帧时间---默认缓存存储
					poster:'https://img1.baidu.com/it/u=1297253752,1185196455&fm=26&fmt=auto&gp=0.jpg',
					src:'https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/a876efc0-4f35-11eb-97b7-0dc4655d6e68.mp4',
				  },
                  {type:'image', src:'https://img1.baidu.com/it/u=2057763469,3313822915&fm=26&fmt=auto&gp=0.jpg'},
                  {type:'image', src:'https://img0.baidu.com/it/u=1570602913,157918019&fm=26&fmt=auto&gp=0.jpg'},
              ]  
            },
			videoKey:{ type:String, default:'src'},// 视频映射的键
			imageKey:{ type:String, default:'src'},//图片映射的键
            indicatorPos:{ type:String, default:'bottomCenter'},//指示器的位置:topLeft/topCenter/topRight/bottomLeft/bottomCenter/bottomRight
            mode:{ type:String, default:'round' },//指示器样式： default  circle  round index number none时不显示
            fullScreen:{ type:Boolean, default:false }, //是否全屏
            navHeight:{type:Number, default:44},//顶部导航高度，默认44---垂直全屏状态无导航栏可设置为0
            height:{ type:Number, default:160 },//swiper 高度单位px
			contentRadius:{ type:String, default:'0rpx' },//盒子圆角设置
            topFloat:{ type:Boolean, default:true },//顶部不占位-浮动定位
            fotterFloat:{ type:Boolean, default:true },//底部不占位-浮动定位
            effect3d:{ type:Boolean, default:false },//是否开启3D效果 注:只有在displayMultipleItems=1时有效 
            effect3dMargin:{type: String, default: '40rpx'},//effect3d=true模式下前后间距接受px和rpx值
            imgMode:{type: String, default: 'scaleToFill'},//图片的裁剪模式,详见https://uniapp.dcloud.io/component/image
            bgColor:{type: String, default: '#f3f4f6'},//swiper背景色
            bgColorItem:{type: String, default: 'rgba(0,0,0,0)'},//swiper当前项背景色
			
			//顶部与底部设置-注：-顶部与底部根据需求自己拓展---也可用插槽自定义内容
			topTextKey:{  type:String, default:'topTip'},//顶部文字说明映射的键
			topColor:{ type:String, default:'#FFF'},//顶部文字颜色
			topBackground:{  type:String, default:'rgba(0, 0, 0, 0)'},//顶部背景色
			topTextAlign:{ type:String, default:'left'},//顶部文字位置
			bottomTextKey:{  type:String, default:'bottomTip'},//底部文字说明映射的键
			bottomColor:{ type:String, default:'#00F'},//底部文字颜色
			bottomBackground:{  type:String, default:'rgba(0, 0, 0, 0)'},//底部背景色
			bottomTextAlign:{ type:String, default:'left'},//底部文字位置
			//---end
			
            // ---swiper原生属性-参考https://uniapp.dcloud.io/component/swiper
			skipHiddenItemLayout:{ //是否跳过未显示的滑块布局，设为 true 可优化复杂情况下的滑动性能，但会丢失隐藏状态滑块的布局信息 
				type:Boolean,
				default:false
			},
			displayMultipleItems:{ type:Number,default:1 },//同时显示的滑块数量
			nextMargin:{ // 后边距，可用于露出后一项的一小部分，接受 px 和 rpx 值 头条小程序不支持
				type:String,
				default:'0rpx'
			},
			previousMargin:{//前边距，可用于露出前一项的一小部分，接受 px 和 rpx 值头条小程序不支持
				type:String,
				default:'0rpx'
			},
			vertical:{ type:Boolean, default:false },//滑动方向是否为纵向 卡牌不支持纵向以及同时显示的2块以上滑块数量
			circular:{ type:Boolean, default:true },//是否采用衔接滑动
			duration:{ type:Number, default:400 },// 滑动动画时长
			interval:{ type:Number, default:2500 },// 自动切换时间间隔
			current:{ type:Number, default:0 },// 初始化时，默认显示第几项
			autoplay:{ type:Boolean, default:true },// 是否自动切换
			indicatorDots: { type: Boolean, default: false },//是否显示面板指示点--默认关闭使用自定义指示器mode设置指示器，原生指示器为true时 则不显示自定义指示器 
			indicatorColor:{ type:String, default:'rgba(0,0,0,0.3)' },// 指示点颜色
			indicatorActiveColor: { type: String, default: '#F1F1F1' },// 选中项指示点颜色
		},
		data() {
			return {
				swiperList:[],//列表数据
				videoContent:'',//视频实例
				videoPlaySataus:false, //视频播放状态---默认禁用
                activeCurrent:0,//当前选中索引
                swiperHeight:0, //轮播图高度
				moveX:0, 
			}
		}, 
        watch: {
            height:{//swiper高度
                handler(newValue) {
                    this.swiperHeight = newValue
                },
                immediate:true
            },
            current:{//初始化选中项
                handler(newValue) {
                    this.activeCurrent = newValue
                },
                immediate:true
            },
			list:{//初始化数据列表--- 处理vue不能直接改变prpos属性
                handler(newValue) {
                    this.swiperList = newValue || []
                },
                immediate:true
            },
			fullScreen:{
				handler(newValue) {
				    if(this.fullScreen){//全屏设置---默认初始化设置一次
				        uni.getSystemInfo({
				            success:(e)=>{
				                console.log('e',e);
				    			this.swiperHeight = e.screenHeight - this.navHeight
				    			// #ifdef APP-PLUS || MP-WEIXIN
				    				this.swiperHeight = e.screenHeight - this.navHeight - e.statusBarHeight  
				    			// #endif  
				            }
				        })
				    }else{
						this.swiperHeight = this.height
					}
				},
				immediate:true
			}
        }, 
		methods: {  
			play(e){
				this.videoPlaySataus = true 
			},
			pause(){
				this.videoPlaySataus = false 
			},
			timeupdate(e){//播放进度变化时触发--更新播放缓存   
				this.$set(this.swiperList[this.activeCurrent],'currentTime',e.detail.currentTime)
			},
			clickItem(index){
				if(this.list.length>0){
					this.$emit('clickItem',this.list[index])
				}
            },   
			change(e){//轮播改变触发  
				try{// 切换前暂停之前视频 
					let preSwiper = this.swiperList[this.activeCurrent]
					if(preSwiper.type==='video'){ 
						uni.createVideoContext(`video_${this.activeCurrent}`,this).pause();
					} 
				}catch(e){
					//TODO handle the exception
				} 
				this.videoPlaySataus = false //自动切换关闭视频播放状态
                this.activeCurrent = e.detail.current;  
				this.$emit('change',e) 
			},
			animationfinish(e){//动画结束后调用    
				this.moveX = 0
				this.$emit('animationfinish',e) 
			},
			transition(e){//滑动
				// #ifdef APP-PLUS
					this.moveX = e.detail.dx 
				// #endif
			}
		}
	}
</script> 
<style lang="scss" scoped>
.swiperContent{//容器
    width:100%;
    position: relative;
    // background-color: #ccc;  
    .z-screen-swiper {//轮播图
        min-height: 320rpx; 
        // background-color: rgb(211, 235, 107); //--调试样式
        box-sizing: border-box;
        .z-swiper-item{ 
            box-sizing: border-box;
            overflow: initial;  
            .swiper-box{//轮播图内容
                // background-color: #e7ca8f;//--调试样式
                // background-color: rgba(0,0,0,0.1);//swiper当前项 背景色---已改为配置
                box-sizing: border-box;
                width: 100%;
                height: 100%;
                overflow: hidden;
                display: flex;
                flex-direction: column; 
                justify-content: space-between;
                position: relative;
                color: #FFF;
                .swiper-top{
                    top: 0;
                    // background-color: rgba(0,0,0,0.2);//背景色---已改为配置
                }
                .swiper-content{
                    // background-color: rgb(61, 41, 175);   
                    flex: 1;  
					display: flex;
					flex-direction: column;
					justify-content: center;
					image{
						width:100%;
						height: 100%;
						max-height: 100%; 
					}
					video {// 视频默认不全屏高度---防止全屏swiper滑动切换
						width: 100%;   
						max-height: 100%; 
                        // pointer-events: auto;  
					} 
                } 
                .swiper-fotter{
                    bottom: 0;
                    // background-color: rgba(0, 0, 0, 0.2); //背景色---已改为配置
                } 
                .isFloat{//是否浮动 顶部、底部定位
                    position: absolute;
                    left: 0;
                    right: 0; 
                    z-index: 999;
                }
            }  
        }
    }
    .effect3D{//3d模式样式 
        .z-swiper-item{//3d模式基础样式  
            .swiper-box{  
                border-radius: 10rpx; 
                opacity: 0.7;
                transition: all 0.1s ease-in 0s;  
            } 
        }  
        &.effect3D-X{ 
            .z-swiper-item{ //选项卡间隔 
                padding: 0 10rpx;   
            } 
            .swiper-box{   
                transform: scale(1,0.9);   
            }    
        } 
        &.effect3D-Y{ 
            .z-swiper-item{ //选项卡间隔 
                padding:10rpx 0;   
            } 
            .swiper-box{   
                transform: scale(0.9,1);   
            }    
        } 
        .active-swiper{//选中样式恢复 
            .swiper-box{
                transform:initial; 
                opacity: 1; 
                transition: all 0.1s ease-in 0s;
            }
        }
       
    }

    .dot{//指示器
        position: absolute; 
        // z-index: 9999;  
        display: flex; 
        color: #FFF;   
        .dotItem{//指示器 颜色与形状 
            background-color: #fff;   
			font-size: 24rpx;
			color: #e2e2e2;
            margin-right: 10rpx;
            &.default{ /*默认条状 */
                height: 8rpx;
                width: 40rpx;
            }
            &.circle{ /* 圆 */
                height: 20rpx;
                width: 20rpx;  
                border-radius: 50%;
            }
            &.index{ /* 数字索引 */
                height: 30rpx;
                width: 30rpx; 
                display: flex;
                justify-content: center;
                align-content: center;
                border-radius: 50%;
            } 
            &.defautActive{//选中项设置
                transition: background-color 0.3s ease-out 0s; //选中动画
            }
            &.round{ /* 弧形 */
                height: 20rpx;
                width: 20rpx;  
                border-radius: 50%;
                &.defautActive{//弧形选中项设置 
                     width: 60rpx;
                     height: 20rpx; 
                     border-radius: 10px; 
                     transition: background-color 0.3s ease-out 0s; //
                }
            } 
        } 
        // 定位位置
        &.verticalDot{//垂直方向 只写了支持右侧定位
            right: 20rpx;
            top: 50%;
            transform: translateY(-50%);
            display: block; 
            margin: 0 !important; 
            .dotItem{
                margin: 0;
                margin-bottom: 10rpx;
                &.round{ /* 弧形 */
                    height: 20rpx;
                    width: 20rpx;  
                    border-radius: 50%;
                    &.defautActive{//弧形选中  
                        width: 20rpx;
                        height: 60rpx; 
                        border-radius: 10px;
                    }
                } 
            }
        }
        &.bottomLeft{//左上角
            left: 20rpx;
            bottom: 20rpx;  
        }
        &.bottomCenter{//
            left: 50%;
            bottom: 20rpx; 
            transform: translateX(-50%);
        }
        &.bottomRight{
            right: 20rpx;
            bottom: 20rpx;  
        }
        &.topLeft{
            left: 20rpx;
            top: 10rpx;  
        }
        &.topCenter{
            left: 50%;
            top: 10rpx;  
            transform: translateX(-50%);
        }
        &.topRight{
            right: 20rpx;
            top: 10rpx; 
        }
    }
} 
</style>
