mrr.sj.front/pages/album/components/videoSlide.nvue

822 lines
26 KiB
Plaintext
Raw Normal View History

2026-03-24 11:45:13 +08:00
<template>
<view style="z-index: 100;">
<!-- 视频滑动主容器 -->
<view class="view-box" :style="viewTopLength">
<!-- 复用的5个视频容器 - 核心复用节点,不可删减 -->
<view class="video-box" :style="itemViewTopLength0">
<video :src="videoInfo_0.src" :style="fillScreen" :autoplay="videoInfo_0.autoplay"
:loop="videoInfo_0.loop" :controls="videoInfo_0.controls"
:enable-play-gesture="videoInfo_0.enablePlayGesture" :objectFit="videoInfo_0.objectFit || objectFit"
:show-fullscreen-btn="videoInfo_0.showFullscreenBtn"
:enable-progress-gesture="videoInfo_0.enableProgressGesture" @timeupdate="timeupdate(0,$event)"
@ended='ended' :show-play-btn="videoInfo_0.showPlayBtn" :show-progress="videoInfo_0.showProgress"
initial-time="0" id='video_id_0' @play="playing(0)" :muted="videoInfo_0.isMuted"
webkit-playsinline="true" playsinline="true">
</video>
<cover-view v-if="!videoInfo_0.flag" :style="stopIcon" class="cover-view-stop" />
<cover-view v-if="cover && videoInfo_0.coverStatus" :style="fillScreen2" class="video-image">
<image :mode="videoInfo_0.mode || mode" :src="videoInfo_0.coverUrl" :style="fillScreen"></image>
</cover-view>
<view class="video-action" @touchstart.stop='videotouchstart' @touchmove.stop="videotochmove"
@touchend.stop='videotouchend' @click.stop="videoClick"></view>
<!-- 视频文本区域 - 每个视频都有 -->
<view class="video-texts">
2026-03-25 13:29:04 +08:00
<view class="flex-row-center" style="flex: 1;">
<text class="video-title">{{ videoInfo_0.src }}</text>
2026-03-24 11:45:13 +08:00
<text class="video-score">评分 4.8</text>
2026-03-25 13:29:04 +08:00
</view>
2026-03-24 11:45:13 +08:00
<view class="flex-row-center-between" style="flex: 1;">
<text class="video-text">{{videoInfo_0.name}}</text>
<!-- 声音图标 - 绑定0号视频的状态点击切换静音 -->
<image class="video-sound"
:src="videoInfo_0.isMuted ? '/static/images/icons/sound_no.png' : '/static/images/icons/sound_yes.png'"
@click.stop="toggleMute(0)"></image>
</view>
</view>
</view>
<view class="video-box" :style="itemViewTopLength1">
<video :src="videoInfo_1.src" :style="fillScreen" :autoplay="videoInfo_1.autoplay"
:loop="videoInfo_1.loop" :controls="videoInfo_1.controls"
:enable-play-gesture="videoInfo_1.enablePlayGesture" :objectFit="videoInfo_1.objectFit || objectFit"
:show-fullscreen-btn="videoInfo_1.showFullscreenBtn"
:enable-progress-gesture="videoInfo_1.enableProgressGesture" @timeupdate="timeupdate(1,$event)"
@ended='ended' :show-play-btn="videoInfo_1.showPlayBtn" :show-progress="videoInfo_1.showProgress"
initial-time="0" id='video_id_1' @play="playing(1)" :muted="videoInfo_1.isMuted"
webkit-playsinline="true" playsinline="true">
</video>
<cover-view v-if="!videoInfo_1.flag" :style="stopIcon" class="cover-view-stop" />
<cover-view v-if="cover && videoInfo_1.coverStatus" :style="fillScreen2" class="video-image">
<image :mode="videoInfo_1.mode || mode" :src="videoInfo_1.coverUrl" :style="fillScreen"></image>
</cover-view>
<view class="video-action" @touchstart='videotouchstart' @touchmove="videotochmove"
@touchend='videotouchend' @click="videoClick"></view>
<!-- 视频文本区域 - 1号视频 -->
<view class="video-texts">
2026-03-25 13:29:04 +08:00
<view class="flex-row-center" style="flex: 1;">
2026-03-24 11:45:13 +08:00
<text class="video-title">珍草品汇理疗馆珍馆服务流程11订单</text>
<text class="video-score">评分 4.8</text>
2026-03-25 13:29:04 +08:00
</view>
2026-03-24 11:45:13 +08:00
<view class="flex-row-center-between" style="flex: 1;">
<text class="video-text">{{videoInfo_1.name}}</text>
<!-- 声音图标 - 绑定1号视频的状态 -->
<image class="video-sound"
:src="videoInfo_1.isMuted ? '/static/images/icons/sound_no.png' : '/static/images/icons/sound_yes.png'"
@click.stop="toggleMute(1)"></image>
</view>
</view>
</view>
<view class="video-box" :style="itemViewTopLength2">
<video :src="videoInfo_2.src" :style="fillScreen" :autoplay="videoInfo_2.autoplay"
:loop="videoInfo_2.loop" :controls="videoInfo_2.controls"
:enable-play-gesture="videoInfo_2.enablePlayGesture" :objectFit="videoInfo_2.objectFit || objectFit"
:show-fullscreen-btn="videoInfo_2.showFullscreenBtn"
:enable-progress-gesture="videoInfo_2.enableProgressGesture" @timeupdate="timeupdate(2,$event)"
@ended='ended' :show-play-btn="videoInfo_2.showPlayBtn" :show-progress="videoInfo_2.showProgress"
initial-time="0" id='video_id_2' @play="playing(2)" :muted="videoInfo_2.isMuted"
webkit-playsinline="true" playsinline="true">
</video>
<cover-view v-if="!videoInfo_2.flag" :style="stopIcon" class="cover-view-stop" />
<cover-view v-if="cover && videoInfo_2.coverStatus" :style="fillScreen2" class="video-image">
<image :mode="videoInfo_2.mode || mode" :src="videoInfo_2.coverUrl" :style="fillScreen"></image>
</cover-view>
<view class="video-action" @touchstart='videotouchstart' @touchmove="videotochmove"
@touchend='videotouchend' @click="videoClick"></view>
<!-- 视频文本区域 - 2号视频 -->
<view class="video-texts">
2026-03-25 13:29:04 +08:00
<view class="flex-row-center" style="flex: 1;">
2026-03-24 11:45:13 +08:00
<text class="video-title">珍草品汇理疗馆珍馆服务流程11订单</text>
<text class="video-score">评分 4.8</text>
2026-03-25 13:29:04 +08:00
</view>
2026-03-24 11:45:13 +08:00
<view class="flex-row-center-between" style="flex: 1;">
<text class="video-text">{{videoInfo_2.name}}</text>
<!-- 声音图标 - 绑定2号视频的状态 -->
<image class="video-sound"
:src="videoInfo_2.isMuted ? '/static/images/icons/sound_no.png' : '/static/images/icons/sound_yes.png'"
@click.stop="toggleMute(2)"></image>
</view>
</view>
</view>
<view class="video-box" :style="itemViewTopLength3">
<video :src="videoInfo_3.src" :style="fillScreen" :autoplay="videoInfo_3.autoplay"
:loop="videoInfo_3.loop" :controls="videoInfo_3.controls"
:enable-play-gesture="videoInfo_3.enablePlayGesture" :objectFit="videoInfo_3.objectFit || objectFit"
:show-fullscreen-btn="videoInfo_3.showFullscreenBtn"
:enable-progress-gesture="videoInfo_3.enableProgressGesture" @timeupdate="timeupdate(3,$event)"
@ended='ended' :show-play-btn="videoInfo_3.showPlayBtn" :show-progress="videoInfo_3.showProgress"
initial-time="0" id='video_id_3' @play="playing(3)" :muted="videoInfo_3.isMuted"
webkit-playsinline="true" playsinline="true">
</video>
<cover-view v-if="!videoInfo_3.flag" :style="stopIcon" class="cover-view-stop" />
<cover-view v-if="cover && videoInfo_3.coverStatus" :style="fillScreen2" class="video-image">
<image :mode="videoInfo_3.mode || mode" :src="videoInfo_3.coverUrl" :style="fillScreen"></image>
</cover-view>
<view class="video-action" @touchstart='videotouchstart' @touchmove="videotochmove"
@touchend='videotouchend' @click="videoClick"></view>
<!-- 视频文本区域 - 3号视频 -->
<view class="video-texts">
2026-03-25 13:29:04 +08:00
<view class="flex-row-center" style="flex: 1;">
2026-03-24 11:45:13 +08:00
<text class="video-title">珍草品汇理疗馆珍馆服务流程11订单</text>
<text class="video-score">评分 4.8</text>
2026-03-25 13:29:04 +08:00
</view>
2026-03-24 11:45:13 +08:00
<view class="flex-row-center-between" style="flex: 1;">
<text class="video-text">{{videoInfo_3.name}}</text>
<!-- 声音图标 - 绑定3号视频的状态 -->
<image class="video-sound"
:src="videoInfo_3.isMuted ? '/static/images/icons/sound_no.png' : '/static/images/icons/sound_yes.png'"
@click.stop="toggleMute(3)"></image>
</view>
</view>
</view>
<view class="video-box" :style="itemViewTopLength4">
<video :src="videoInfo_4.src" :style="fillScreen" :autoplay="videoInfo_4.autoplay"
:loop="videoInfo_4.loop" :controls="videoInfo_4.controls"
:enable-play-gesture="videoInfo_4.enablePlayGesture" :objectFit="videoInfo_4.objectFit || objectFit"
:show-fullscreen-btn="videoInfo_4.showFullscreenBtn"
:enable-progress-gesture="videoInfo_4.enableProgressGesture" @timeupdate="timeupdate(4,$event)"
@ended='ended' :show-play-btn="videoInfo_4.showPlayBtn" :show-progress="videoInfo_4.showProgress"
initial-time="0" id='video_id_4' @play="playing(4)" :muted="videoInfo_4.isMuted"
webkit-playsinline="true" playsinline="true">
</video>
<cover-view v-if="!videoInfo_4.flag" :style="stopIcon" class="cover-view-stop" />
<cover-view v-if="cover && videoInfo_4.coverStatus" :style="fillScreen2" class="video-image">
<image :mode="videoInfo_4.mode || mode" :src="videoInfo_4.coverUrl" :style="fillScreen"></image>
</cover-view>
<view class="video-action" @touchstart='videotouchstart' @touchmove="videotochmove"
@touchend='videotouchend' @click="videoClick"></view>
<!-- 视频文本区域 - 4号视频 -->
<view class="video-texts">
2026-03-25 13:29:04 +08:00
<view class="flex-row-center" style="flex: 1;">
2026-03-24 11:45:13 +08:00
<text class="video-title">珍草品汇理疗馆珍馆服务流程11订单</text>
<text class="video-score">评分 4.8</text>
2026-03-25 13:29:04 +08:00
</view>
2026-03-24 11:45:13 +08:00
<view class="flex-row-center-between" style="flex: 1;">
<text class="video-text">{{videoInfo_4.name}}</text>
<!-- 声音图标 - 绑定4号视频的状态 -->
<image class="video-sound"
:src="videoInfo_4.isMuted ? '/static/images/icons/sound_no.png' : '/static/images/icons/sound_yes.png'"
@click.stop="toggleMute(4)"></image>
</view>
</view>
</view>
2026-03-25 13:29:04 +08:00
<view @touchend='progressTouchend' class="progress-view">
2026-03-24 11:45:13 +08:00
<uv-slider v-if="showSlider" v-model="progressValue" activeColor="#D8D8D8" block-size="6"
backgroundColor="#494949;" class="progress-slider"></uv-slider>
</view>
<!-- 修改Dot指示器 - 最多显示5个 -->
2026-03-25 13:29:04 +08:00
<view class="dots" :style="{top:`${0.5*winHeight}px`}" v-if="videoListLength > 1">
2026-03-24 11:45:13 +08:00
<view class="dots-container">
<view class="dot-item" v-for="(dotIndex, idx) in visibleDots" :key="idx"
:class="{ active: dotIndex === videoIndex }" @click="jumpToVideo(dotIndex)"></view>
</view>
<text class="pageNumber">
{{ videoIndex+1 }}/{{ videoListLength }}
</text>
</view>
</view>
</view>
</template>
<script>
let VIDEO_LIST = []
let initVideoInfo = {
src: "",
coverStatus: true,
coverUrl: "",
flag: false,
objectFit: "",
mode: "",
isMuted: false, // 默认不静音
autoplay: false,
loop: true,
controls: false,
enablePlayGesture: true,
showFullscreenBtn: false,
enableProgressGesture: false,
showPlayBtn: false,
showProgress: false
}
export default {
props: {
popVideoList: {
type: Array,
default: [] // 默认值设为空数组JSON避免parse报错
},
marginTop: {
type: String,
default: "88" // 默认值设为空数组JSON避免parse报错
}
},
data() {
return {
playSetTime:null,
showSlider: true,
progressTime: 0,
progressValue: 0,
boxHeight: 0,
objectFit: "fill",
mode: "scaleToFill",
winWidth: 1,
winHeight: 1,
videoIndex: 0,
viewTop: 0,
viewTopPostion: 0,
videoList: [],
videoListLength: 0,
itemViewTop0: 0,
itemViewTop1: 0,
itemViewTop2: 0,
itemViewTop3: 0,
itemViewTop4: 0,
videoInfo_0: initVideoInfo,
videoInfo_1: initVideoInfo,
videoInfo_2: initVideoInfo,
videoInfo_3: initVideoInfo,
videoInfo_4: initVideoInfo,
stopIcon: '',
videotouchstartTimestamp: 0,
videotouchendTimestamp: 0,
moveView: true,
cover: true,
slidingStatus: false,
videoPlayingStatus: false,
preloadedIndex: [],
startPageY: 0,
endPageY: 0,
// 新增控制可视dot的数组
visibleDots: [],
};
},
watch: {
// videoList: {
// handler(newVal, oldVal) {
// },
// immediate: true, // 可选:组件初始化时立即执行一次(即使值未变化)
// deep: false // 普通类型无需深度监听默认false
// }
},
created(options) {
//#ifdef APP-PLUS
plus.screen.lockOrientation("portrait-primary")
//#endif
if (this.popVideoList.length) {
try {
VIDEO_LIST = []
this.popVideoList.forEach((item, index) => {
let obj = {
"src": "",
"coverStatus": true,
"coverUrl": "",
"flag": false,
"objectFit": "contain",
"mode": "aspectFit",
"isMuted": false, // 默认不静音
"autoplay": false,
"loop": true,
"controls": false,
"enablePlayGesture": true,
"showFullscreenBtn": false,
"enableProgressGesture": false,
"showPlayBtn": false,
"showProgress": false,
"name": ""
}
obj.name = item.name
obj.src = item.url
obj.coverUrl = item.url +
`?x-oss-process=video/snapshot,t_1000,m_fast,f_jpg,w_600,ar_auto`
VIDEO_LIST.push(obj)
if (index == 0) {
initVideoInfo = obj
}
})
} catch (e) {}
this.getSystemInfo();
this.videoList = VIDEO_LIST;
this.videoListLength = this.videoList.length;
this.boxHeight = this.videoListLength * this.winHeight;
for (let i = 0; i < 5; i++) {
if (this.videoList[i]) {
this['videoInfo_' + i] = this.videoList[i]
}
}
// 初始化可视dot范围
this.updateVisibleDots();
// setTimeout(() => {
// this.playVideo(0)
// }, 500)
}
},
onUnload() {
for (let i = 0; i < 5; i++) {
this.unloadVideo(i)
}
},
computed: {
getVideoTop() {
return uni.upx2px(this.marginTop)
},
viewTopLength() {
return `height:${this.boxHeight}px;top:${this.viewTop}px;`
},
fillScreen() {
let style = `height:${this.winHeight}px;width:${this.winWidth}px;`
return style
},
fillScreen2() {
let style = `height:auto;width:${this.winWidth}px;`
return style
},
itemViewTopLength0() {
return `height:${this.winHeight}px;top:${this.itemViewTop0}px;`
},
itemViewTopLength1() {
return `height:${this.winHeight}px;top:${this.itemViewTop1}px;`
},
itemViewTopLength2() {
return `height:${this.winHeight}px;top:${this.itemViewTop2}px;`
},
itemViewTopLength3() {
return `height:${this.winHeight}px;top:${this.itemViewTop3}px;`
},
itemViewTopLength4() {
return `height:${this.winHeight}px;top:${this.itemViewTop4}px;`
}
},
methods: {
// 新增:切换视频静音状态
toggleMute(videoNum) {
// 1. 切换数据层状态
this['videoInfo_' + videoNum].isMuted = !this['videoInfo_' + videoNum].isMuted;
// 2. 同步视频实例静音状态(恢复并完善原有注释代码,加容错)
const videoCtx = uni.createVideoContext("video_id_" + videoNum, this);
if (videoCtx) {
videoCtx.mute(this['videoInfo_' + videoNum].isMuted);
}
},
// 修改点击dot跳转 - 传真实的视频索引
jumpToVideo(targetIndex) {
if (targetIndex === this.videoIndex || this.slidingStatus) return;
this.stopVideo(this.videoIndex % 5, true);
const diff = targetIndex - this.videoIndex;
this.videoIndex = targetIndex;
this.viewTopPostion = -this.videoIndex * this.winHeight;
this.viewTop = this.viewTopPostion;
if (this.videoListLength > 5) {
this.sortItemView(diff > 0 ? -1 : 1);
}
// 更新可视dot范围
this.updateVisibleDots();
setTimeout(() => {
this.playVideo(this.videoIndex % 5);
}, 400);
},
// 核心更新可视dot范围 - 最多显示5个
updateVisibleDots() {
const maxShow = 5;
const total = this.videoListLength;
// 视频总数 ≤ 5显示全部
if (total <= maxShow) {
this.visibleDots = Array.from({
length: total
}, (_, i) => i);
return;
}
// 视频总数 > 5显示包含当前索引的5个dot
// 计算起始索引,避免越界
let start = Math.max(0, Math.min(this.videoIndex - 2, total - maxShow));
// 生成5个连续的索引
this.visibleDots = Array.from({
length: maxShow
}, (_, i) => start + i);
},
progressTouchend() {
let s = Math.round(this.progressValue / 100 * this.time)
let i = this.videoIndex % 5
uni.createVideoContext("video_id_" + i, this).seek(s)
uni.createVideoContext("video_id_" + i, this).play()
},
sliderchanging(e) {
console.log(3333, e)
},
getSystemInfo() {
var _this = this;
uni.getSystemInfo({
success: function(res) {
_this.winWidth = res.windowWidth;
_this.winHeight = res.windowHeight;
let p = uni.upx2px(150)
_this.stopIcon = `left:${(res.windowWidth - p)/2}px;top:${(res.windowHeight - p)/2}px;`
_this.itemViewTop1 = res.windowHeight
_this.itemViewTop2 = res.windowHeight * 2
_this.itemViewTop3 = res.windowHeight * 3
_this.itemViewTop4 = res.windowHeight * 4
},
})
},
unloadVideo(index) {
if (index < 0 || index >= this.videoListLength) return;
const nodeNum = index % 5;
const videoCtx = uni.createVideoContext("video_id_" + nodeNum, this);
videoCtx.stop();
this.preloadedIndex = this.preloadedIndex.filter(item => item !== index);
},
playVideo(num) {
clearTimeout(this.playSetTime)
uni.$uv.debounce(() => {
this.videoPlayingStatus = true
this["videoInfo_" + num].flag = true
let VideoContext = uni.createVideoContext("video_id_" + num, this)
this.playSetTime = setTimeout(() => {
VideoContext.play()
}, 400)
}, 30)
},
stopVideo(num, control = false) {
const videoCtx = uni.createVideoContext("video_id_" + num, this);
if (!control) {
this['videoInfo_' + num].coverStatus = true;
videoCtx.stop()
} else {
videoCtx.pause()
}
this["videoInfo_" + num].flag = false
},
nowPlayVideo() {
clearTimeout(this.playSetTime)
uni.$uv.debounce(() => {
this.videoPlayingStatus = true
this["videoInfo_" + this.videoIndex].flag = true
let VideoContext = uni.createVideoContext("video_id_" + this.videoIndex, this)
this.playSetTime = setTimeout(() => {
VideoContext.play()
}, 400)
}, 30)
},
nowStopVideo() {
const videoCtx = uni.createVideoContext("video_id_" + this.videoIndex, this);
videoCtx.pause()
this["videoInfo_" + this.videoIndex].flag = false
},
videoClick() {
let num = this.videoIndex % 5
if (this["videoInfo_" + num].flag) {
this.stopVideo(num, true)
} else {
this.playVideo(num, true)
}
},
videotouchstart(e) {
this.videotouchendTimestamp = this.videotouchstartTimestamp
this.videotouchstartTimestamp = e.timestamp
if ((this.videotouchstartTimestamp - this.videotouchendTimestamp) < 500) return
if (this.slidingStatus) return
this.startPageY = e.changedTouches[0].screenY;
},
videotochmove(e) {
if ((this.videotouchstartTimestamp - this.videotouchendTimestamp) < 500) return
if (this.slidingStatus) return
this.endPageY = e.changedTouches[0].screenY;
let sliding = this.endPageY - this.startPageY
if (sliding > 20 || sliding < -20) {
this.moveView = false
} else {
this.moveView = true
}
if (this.videoIndex == 0 && sliding > 50) {
this.viewTop = 50
} else if (this.videoIndex == this.videoListLength - 1 && sliding < 0) {
this.viewTop = this.viewTopPostion
} else {
this.viewTop = this.viewTopPostion + sliding
}
},
videotouchend(e) {
if ((this.videotouchstartTimestamp - this.videotouchendTimestamp) < 500) return
if (this.slidingStatus) return
this.moveView = true
this.endPageY = e.changedTouches[0].screenY;
let sliding = this.endPageY - this.startPageY
if ((sliding >= -40 && sliding < 0) || (sliding <= 40 && sliding > 0)) {
this.slidingStatus = true
this.videoSlidingReset(sliding)
return
}
if (sliding < -30) {
this.slidingStatus = true
if (this.videoIndex == this.videoListLength - 1) {
this.videoSlidingReset(sliding)
uni.showToast({
title: "已经到底了",
icon: "none"
})
return
}
this.moveView = false
this.videoSlidingToTop(sliding)
return
}
if (sliding > 30) {
this.slidingStatus = true
if (this.videoIndex == 0) {
this.videoSlidingReset(sliding)
return
}
this.moveView = false
this.videoSlidingToBottom(sliding)
}
},
videoSlidingReset(sliding) {
this.viewTop = this.viewTopPostion
this.slidingStatus = false
},
videoSlidingToTop(sliding) {
this.stopVideo(this.videoIndex % 5, true)
this.videoIndex++
if (this.videoListLength > 5) {
this.sortItemView(sliding)
}
this.viewTopPostion = this.viewTopPostion - this.winHeight
setTimeout(() => {
this.playVideo(this.videoIndex % 5)
}, 5)
let timer = setInterval(() => {
this.viewTop = this.viewTop - 35
if (this.viewTop < (this.viewTopPostion + 10)) {
this.viewTop = this.viewTopPostion
clearInterval(timer)
this.slidingStatus = false
this.slidingCallback()
}
}, 3)
},
videoSlidingToBottom(sliding) {
this.stopVideo(this.videoIndex % 5, true)
this.videoIndex--
if (this.videoListLength > 5) {
this.sortItemView(sliding)
}
this.viewTopPostion = this.viewTopPostion + this.winHeight
setTimeout(() => {
this.playVideo(this.videoIndex % 5)
}, 5)
let timer = setInterval(() => {
this.viewTop = this.viewTop + 35
if (this.viewTop > (this.viewTopPostion - 10)) {
this.viewTop = this.viewTopPostion
clearInterval(timer)
this.slidingStatus = false
this.slidingCallback()
}
}, 3)
},
// 修改滑动结束后更新可视dot
slidingCallback() {
this.progressValue = 0
this.updateVisibleDots();
},
//滑动组件排序
sortItemView(silding) {
// 向上滑动
if (silding < 0) {
if (this.videoIndex > 2 && this.videoIndex < this.videoListLength - 2) {
let i = (this.videoIndex - 3) % 5
this["itemViewTop" + i] = this["itemViewTop" + i] + this.winHeight * 5
this['videoInfo_' + i] = this.videoList[this.videoIndex + 2]
}
return
}
// 向下滑动
if (silding > 0) {
if (this.videoIndex > 1 && this.videoIndex < this.videoListLength - 3) {
let i = (this.videoIndex + 3) % 5
this["itemViewTop" + i] = this["itemViewTop" + i] - this.winHeight * 5
this['videoInfo_' + i] = this.videoList[this.videoIndex - 2]
}
}
},
playing(i) {
setTimeout(() => {
this['videoInfo_' + i].coverStatus = false
this.moveView = true
this.slidingStatus = false
}, 600)
},
timeupdate(i, e) {
if (this.videoPlayingStatus) {
this.slidingStatus = false
this.videoPlayingStatus = false
setTimeout(() => {
this['videoInfo_' + i].coverStatus = false
this.moveView = true
}, 200)
}
this["videoInfo_" + i].flag = true
if (e.detail.duration >= this.progressTime) {
if (this.videoIndex%5 == i) {
this.time = e.detail.duration
this.progress = e.detail.currentTime
this.progressValue = (e.detail.currentTime / e.detail.duration) * 100
}
this.showProgress = true
} else {
this.showProgress = false
}
},
ended() {
let num = this.videoIndex % 5
this["videoInfo_" + num].flag = false
this.progressValue = 0
}
}
}
</script>
<style scoped lang="less">
.view-box {
// position: fixed;
// left: 0;
// right: 0;
background-color: #000;
// z-index: 900;
}
.video-box {
position: absolute;
left: 0;
right: 0;
z-index: 2000;
}
.video-image {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 2001;
}
.video-action {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 2008;
}
.video-texts {
position: absolute;
left: 30rpx;
right: 30rpx;
bottom: 120rpx;
z-index: 2009; // 确保在视频上方显示
.video-title {
font-weight: 500;
font-size: 24rpx;
color: #FFFFFF;
text-align: left;
font-style: normal;
lines: 1;
max-width: 240rpx;
}
.video-score {
font-weight: 500;
font-size: 24rpx;
color: #FFFFFF;
text-align: left;
font-style: normal;
margin-left: 20rpx;
}
.video-text {
font-weight: 400;
font-size: 28rpx;
color: #FFFFFF;
text-align: left;
font-style: normal;
}
.video-sound {
width: 44rpx;
height: 42rpx;
cursor: pointer; // 点击指针,提示可点击
}
}
.cover-view-stop {
position: absolute;
z-index: 9999;
width: 150rpx;
height: 200rpx;
background-color: rgba(0, 0, 0, 0.3);
border-radius: 50%;
}
.progress-view {
z-index: 9999;
position: fixed;
left: 30rpx;
right: 30rpx;
bottom: 80rpx;
.progress-slider {}
}
// 修改Dot指示器样式 - 最多显示5个 + 过渡动画
.dots {
position: fixed;
left: 20rpx;
top: 0;
transform: translateY(-50%);
z-index: 9999;
flex-direction: row;
.dots-container {
// 限制最多显示5个超出隐藏
width: fit-content;
overflow: hidden;
margin: auto 0;
.dot-item {
width: 10rpx;
height: 10rpx;
background: #FFFFFF;
border-radius: 50%;
// 核心:过渡动画,切换更丝滑
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
cursor: pointer;
margin-bottom: 10rpx;
&.active {
width: 10rpx;
height: 30rpx;
background: #FFFFFF;
border-radius: 5rpx;
}
}
}
.pageNumber {
font-weight: bold;
font-size: 28rpx;
color: #FFFFFF;
line-height: 36rpx;
text-align: left;
font-style: normal;
margin-left: 6rpx;
}
}
.flex-row-center-between {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.flex-row-start-between {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
}
.flex-row-center-center {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.flex-row-center {
display: flex;
flex-direction: row;
align-items: center;
}
.flex-row-start {
display: flex;
flex-direction: row;
align-items: flex-start;
}
.flex-row-end-between {
display: flex;
flex-direction: row;
align-items: flex-end;
justify-content: space-between;
}
</style>