H5端齐采药项目,uniapp框架
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

326 lines
8.7 KiB

<template>
<swiper class="m-tiktok-video-swiper" circular @change="swiperChange" :current="current" :vertical="true"
duration="300">
{{originList}}
<swiper-item v-for="(item, index) in displaySwiperList" :key="index">
<view class="swiper-item" @click="handleClick">
<ls-dom-video :ref="'DomVideo'+index" v-if="index === 0 || !isFirstLoad" :src="item.video"
:autoplay="true" :controls="false" @ended="endedVideo" @listener="listener"></ls-dom-video>
<!-- <video class="m-tiktok-video-player" :src="item.src" :id="`video__${index}`" :controls="controls"
:show-center-play-btn="controls" :object-fit="item.objectFit" :autoplay="false" :loop="loop"
:custom-cache="false" @ended="ended" @controlstoggle="controlstoggle" @play="onPlay"
@error="emits('error')" @loadedmetadata="loadVideoData($event, item)"
v-if="index === 0 || !isFirstLoad"></video> -->
<!-- <view class="m-tiktok-video-play-btn" v-if="!controls && displayIndex === index" @click="togglePlay">
<text class="m-tiktok-video-iconfont video-icon" :class="{ active: !isPlaying }">&#xe607;</text>
</view>
<image v-if="item.poster && displayIndex != index" :src="item.poster" class="m-tiktok-video-poster"
mode="aspectFit"></image>
<slot :item="item"></slot> -->
</view>
</swiper-item>
</swiper>
</template>
<script>
export default {
props: {
/**
* 视频列表
*/
videoList: {
type: Array,
default: () => [],
},
/**
* 是否循环播放一个视频
*/
loop: {
type: Boolean,
default: true,
},
/**
* 显示原生控制栏
*/
controls: {
type: Boolean,
default: false,
},
/**
* 是否自动播放
*/
autoplay: {
type: Boolean,
default: true,
},
/**
* 是否自动滚动播放
*/
autoChange: {
type: Boolean,
default: false,
},
/**
* 滚动加载阈值(即播放到剩余多少个之后触发加载更多
*/
loadMoreOffsetCount: {
type: Number,
default: 2,
},
/**
* 视频自动自适应平铺模式
* 竖屏cover,横屏自适应
*/
autoObjectFit: {
type: Boolean,
default: true,
},
},
data() {
return {
originList: [], // 源数据
displaySwiperList: [], // swiper需要的数据
displayIndex: 0, // 用于显示swiper的真正的下标数值只有:0,1,2。
originIndex: 0, // 记录源数据的下标
current: 0,
oid: 0,
videoContexts: [],
isFirstLoad: true,
isPlaying: false,
loadTimer: null,
}
},
watch: {
videoList: {
handler(val) {
if (val.length) {
this.originList = val;
console.log(this.originList);
if (this.isFirstLoad || this.videoContexts.length) {
this.initSwiperData(this.originIndex)
this.initVideoContexts()
}
}
},
immediate: true,
deep: true
},
},
mounted() {
console.log(this.videoList);
},
methods: {
initVideoContexts() {
this.videoContexts = this.videoContexts.map((item, index) => {
return uni.createVideoContext(`video__${index}`, this);
})
},
onPlay(e) {
this.isPlaying = true;
this.initFirstLoad()
this.$emit('play', e)
},
handleClick(e) {
this.$emit("click", e);
},
ended() {
if (this.autoChange) {
if (this.displayIndex < 2) {
this.current = this.displayIndex + 1
} else {
this.current = 0
}
}
this.$emit('ended')
},
/**
* 初始一个显示的swiper数据
* @originIndex 从源数据的哪个开始显示默认0,如从其他页面跳转进来,要显示第n个,这个参数就是他的下标
*/
initSwiperData(originIndex) {
const originListLength = this.originList.length; // 源数据长度
const displayList = []; // 显示的swiper数据
displayList[this.displayIndex] = this.originList[originIndex];
displayList[this.displayIndex - 1 == -1 ? 2 : this.displayIndex - 1] =
this.originList[
originIndex - 1 == -1 ? originListLength - 1 : originIndex - 1
];
displayList[this.displayIndex + 1 == 3 ? 0 : this.displayIndex + 1] =
this.originList[originIndex + 1 == originListLength ? 0 : originIndex + 1];
this.displaySwiperList = displayList;
console.log('displaySwiperList', this.displaySwiperList);
if (this.oid >= this.originList.length) {
this.oid = 0;
}
if (this.oid < 0) {
this.oid = this.originList.length - 1;
}
//暂停所有视频
this.videoContexts.map((item) => item?.stop());
setTimeout(() => {
if (this.autoplay) {
uni.createVideoContext(`video__${this.displayIndex}`, this).play();
}
}, 500)
this.$emit('change', {
index: originIndex,
detail: this.originList[originIndex],
})
// 赋值
this.originIndex = originIndex;
// 加载更多
var pCount = this.originList.length - this.loadMoreOffsetCount;
if (originIndex == pCount) {
this.$emit('loadMore')
}
},
/**
* swiper滑动时候
*/
swiperChange(event) {
const { current } = event.detail;
this.isFirstLoad = false
const originListLength = this.originList.length
// 向后滚动
if (this.displayIndex - current == 2 || this.displayIndex - current == -1) {
this.originIndex =
this.originIndex + 1 == originListLength ? 0 : this.originIndex + 1;
this.displayIndex =
this.displayIndex + 1 == 3 ? 0 : this.displayIndex + 1;
this.oid = this.originIndex - 1;
this.initSwiperData(this.originIndex);
}
// 如果两者的差为-2或者1则是向前滑动
else if (
this.displayIndex - current == -2 ||
this.displayIndex - current == 1
) {
this.originIndex =
this.originIndex - 1 == -1 ?
originListLength - 1 :
this.originIndex - 1;
this.displayIndex =
this.displayIndex - 1 == -1 ? 2 : this.displayIndex - 1;
this.oid = this.originIndex + 1;
this.initSwiperData(this.originIndex);
}
},
controlstoggle(e) {
this.$emit('controlstoggle', e)
},
togglePlay() {
const video = uni.createVideoContext(`video__${this.displayIndex}`, this)
if (this.isPlay) {
video.pause()
this.isPlay = false
} else {
video.play()
this.isPlay = true
}
},
playSeeked(value) {
const video = uni.createVideoContext(`video__${this.displayIndex}`, this)
video.seek(value)
},
initFirstLoad() {
if (this.isFirstLoad) {
this.loadTimer = setTimeout(() => {
this.isFirstLoad = false
clearTimeout(this.loadTimer)
}, 5000)
}
},
/**
* 视频源数据加载时触发
* @param $event
* @param item
*/
loadVideoData($event, item) {
if (item.objectFit) {
return
}
if (!this.autoObjectFit) {
return
}
// 自动计算设置视频平铺模式
if ($event.detail.width < $event.detail.height) {
item.objectFit = 'cover'
} else {
item.objectFit = 'contain'
}
}
},
onUnload() {
clearTimeout(this.loadTimer)
},
}
</script>
<style lang="scss">
// @font-face {
// font-family: "m-tiktok-play-icon";
// src: url(data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAAJ0AA0AAAAABlgAAAIiAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGh4GYACCQhEICkhaCwoAATYCJAMQBCAFhQIHLxt4BcieBXbLR4jiyygbC491Mg0vz9JsPPz/ft/2ufeMmCQP9fXfRhxvMKHjkcSsTkqWplJJqpFFfn79mr4NG5fvwujI+EPeZCbudGJcy6oVklRVp8IAdgMJUqD853ceuhm3iSafWxNoC0bbskAmUGABTlrDAgwsC+xJ3/SJf3DecLgpCpyFgDcXlRJ8uiufSVcHBjENilBVIVGQKS50UZ6U1+ApeD7+6kcvRVcl2fZub1Q8/BfJG9VHbUp9J0UAYBWhomIRgUZWYFHOKkgp+FFsyVvmRkB0E4AooAg/DwF/49FSQIJeBMbBDIAEQIzfDW+OPVHX48vXUy26fUwfJnN0+tW5bLx3+dz5fHT61rQEIBDc77r579ZI8793IDWgftfb8/q83gC9Cggqvex6gvqcDoBMGojkOvpX4wgU9OtHC2DcOwgwoYpA6LWDQNHjDgJVr8cCpF7PBOgy4JUA3Xq9BYF+29EgMGAiLlSRfVgDlgyjlmQx7JSsRgVQYkeyy7RLstuoF7Lfid+qAWtxbiWmkbDEVgmyA2hRBHx6jOEomxtSuCEvAg5k/U4c0Bh2XJIYfiwLaz88BE9oYgkrKPS0dWGtk7/X7rqFOsU+TZzFM4k9Qx9jOkEXC3iErR+f0LhcASEUC9g0CtaGY3Jrsjf6zPrqiLsTyi1RpN9z3wPOMRaa6+jQAzbblCgVWLpySeZmOVzvLw8uOfSjoLSEEiV7Yg==) format("woff2");
// font-weight: normal;
// font-style: normal;
// font-display: swap;
// }
.m-tiktok-video-iconfont {
// font-family: m-tiktok-play-icon;
}
.m-tiktok-video-swiper,
.m-tiktok-video-player {
width: 100%;
height: 100vh;
background-color: #000;
}
.m-tiktok-video-swiper {
.swiper-item {
position: relative;
}
.m-tiktok-video-poster {
background-color: #000;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.m-tiktok-video-play-btn {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
.video-icon {
font-size: 50px;
display: block;
color: rgba(255, 255, 255, 0.8);
opacity: 0;
&.active {
opacity: 1;
}
}
}
}
</style>