From cb07426138f701d38e11e9469d9ba4735098e7e0 Mon Sep 17 00:00:00 2001 From: xiangpei <xiangpei@timesnew.cn> Date: 星期一, 09 六月 2025 14:49:26 +0800 Subject: [PATCH] 自定义视频进度条 --- pages/tabbar/index/home.vue | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 155 insertions(+), 3 deletions(-) diff --git a/pages/tabbar/index/home.vue b/pages/tabbar/index/home.vue index e65155f..9ba0f38 100644 --- a/pages/tabbar/index/home.vue +++ b/pages/tabbar/index/home.vue @@ -25,13 +25,39 @@ :controls="false" :loop="true" :object-fit="item.objectFit" + :enable-progress-gesture="false" class="video-item" @play="onPlay(item.id, index)" @pause="onPause(index)" @ended="onEnded(index)" @click="togglePlay(index)" @timeupdate="onTimeUpdate($event)" + @loadedmetadata="onLoadedMetadata($event)" + ></video> + <!-- 鑷畾涔夋帶鍒舵潯 --> + <view + @touchstart="handleTouchStart" + @touchmove="handleTouchMove" + @touchend="handleTouchEnd" + class="container"> + <!-- 杩涘害鏉� - 鏁翠釜鍖哄煙鍙嫋鍔� --> + <view class="process-warp" :style="{ opacity: showProcess ? 1 : 0 }"> + <!-- 鏄剧ず褰撳墠杩涘害 --> + <view class="progress-text">{{ hasPlayTime }}/{{formartDuration}}</view> + <view + class="progress-bar" + id="progressBar" + > + + <!-- 宸插~鍏呴儴鍒� --> + <view class="progress-fill" :style="{ width: progress + '%' }"></view> + </view> + </view> + + + + </view> <!-- 鎮寕鍟嗗搧閾炬帴灞� --> <view class="goods-link-warp"> @@ -181,8 +207,24 @@ import { getRecommendVideos, savePlayRecord, subscribe, getVideoComments, addVideoComment, thubmsUpComment, cancelThubmsUpComment } from "@/api/video.js"; import { changeCollect } from "@/api/collect.js"; export default { + computed: { + hasPlayTime() { + return this.sliderFormatTime(this.progress > 0 ? this.duration * this.progress / 100 : 0); + } + }, data() { return { + currentTime: 0, + formartDuration: '', + duration: 0, + startX: 0, + progress: 0, // 瑙嗛杩涘害 + startProgress : 0, // 寮�濮嬫粦鍔ㄦ椂鐨勮繘搴� + barLeft: 0, // 杩涘害鏉″乏杈圭晫浣嶇疆 + barWidth: 0, // 杩涘害鏉″搴� + isDragging: false, // 鏄惁姝e湪鎷栧姩 + processHidenTimer: null, // 杩涘害鏉¢殣钘忓畾鏃跺櫒 + showProcess: false, // 鏄惁鏄剧ず杩涘害鏉� videoNoMore: false, // 鏄惁杩樻湁鏇村瑙嗛 commentNoMore: false, // 鏄惁杩樻湁鏇村璇勮 commentQuery: { @@ -255,6 +297,16 @@ this.initVideoContexts(); }, methods: { + // 鑾峰彇杩涘害鏉$殑浣嶇疆鍜屽昂瀵� + getBarRect() { + const query = uni.createSelectorQuery().in(this); + query.select('#progressBar').boundingClientRect(rect => { + if (rect) { + this.barLeft = rect.left; + this.barWidth = rect.width; + } + }).exec(); + }, // 璺宠浆涓汉涓婚〉 jumpToHomePage(authorId) { uni.navigateTo({ @@ -351,6 +403,12 @@ const input = this.$refs.commentInput; if (input) input.focus(); }); + }, + // 杩涘害鏉℃椂闂存牸寮忓寲 (00:00) + sliderFormatTime(seconds) { + const mins = Math.floor(seconds / 60); + const secs = Math.floor(seconds % 60); + return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; }, // 鏍煎紡鍖栨椂闂� formatTime(time) { @@ -584,6 +642,8 @@ }, // 瑙嗛鎾斁浜嬩欢 onPlay(id, index) { + this.getBarRect() + this.progress = 0 console.log(id, index, "瑙﹀彂鎾斁"); if(index === this.currentIndex) { this.currentVideoIsPlaying = true; @@ -613,7 +673,6 @@ } this.startPauseTime = Date.now() }, - // 瑙嗛缁撴潫浜嬩欢 onEnded(index) { // this.currentVideoIsPlaying = false; @@ -621,9 +680,66 @@ // 璁板綍鎾斁鏃堕暱 onTimeUpdate(e) { - this.playRecord.playAt = e.detail.currentTime + this.playRecord.playAt = e.detail.currentTime; + + this.currentTime = e.detail.currentTime; + this.progress = (e.detail.currentTime / this.duration) * 100 + }, + // 瑙︽懜寮�濮� + handleTouchStart(e) { + this.isDragging = true; + this.showProcess = true; + this.startProgress = this.progress; // 璁板綍寮�濮嬫椂鐨勮繘搴� + this.startX = e.touches[0].pageX; + console.log("璁板綍寮�濮嬫椂鐨勮繘搴�", this.startProgress); + this.videoContexts[this.currentIndex].pause() + // this.updateProgress(e); }, + // 瑙︽懜绉诲姩 + handleTouchMove(e) { + if (!this.isDragging || !this.barWidth) return; + clearTimeout(this.processHidenTimer) + this.videoContexts[this.currentIndex].pause() + this.updateProgress(e); + }, + + // 瑙︽懜缁撴潫 + handleTouchEnd() { + this.isDragging = false; + console.log("婊戝姩缁撴潫", this.duration * this.progress); + this.videoContexts[this.currentIndex].seek(this.duration * this.progress / 100) + this.videoContexts[this.currentIndex].play() + this.processHidenTimer = setTimeout(() => { + this.showProcess = false; + }, 1000); + }, + + // 鏇存柊杩涘害 + updateProgress(e) { + // 鑾峰彇褰撳墠瑙︽懜鐐筙鍧愭爣 + const currentX = e.touches[0].pageX; + + // 璁$畻婊戝姩璺濈(鍍忕礌) + const deltaX = currentX - this.startX; + + // 灏嗗儚绱犺窛绂昏浆鎹负杩涘害澧為噺 + const deltaProgress = (deltaX / this.barWidth) * 100; + console.log("杩涘害澧為噺", deltaProgress); + // 璁$畻鏂拌繘搴� = 寮�濮嬫椂鐨勮繘搴� + 婊戝姩澧為噺 + let newProgress = this.startProgress + deltaProgress; + + // 闄愬埗鑼冨洿鍦�0-100涔嬮棿 + newProgress = Math.max(0, Math.min(100, newProgress)); + + this.progress = newProgress; + }, + // 鑾峰彇瑙嗛鎬绘椂闀� + onLoadedMetadata(e) { + this.duration = e.detail.duration; + this.formartDuration = this.sliderFormatTime(this.duration); + console.log("瑙嗛鎬绘椂闀�", this.duration); + }, // 淇濆瓨鎾斁璁板綍 async savePlayRecord() { console.log(Date.now(), this.playRecord.startPlayTime, this.totalHidenTime); @@ -659,7 +775,7 @@ .video-swiper { width: 100%; - height: 100%; + height: calc(100% - 50px); } .video-item { @@ -1015,4 +1131,40 @@ .thumbs-num { margin-left: 4rpx; } + .container { + display: flex; + flex-direction: column; + align-items: center; + position: absolute; + bottom: 0; + width: 100%; + } + + .progress-bar { + position: relative; + width: 100%; + height: 16px; + background-color: #eee; + overflow: hidden; + } + + .progress-fill { + position: absolute; + left: 0; + top: 0; + height: 100%; + background-color: lightgray; + transition: width 0.1s; + } + .process-warp { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + } + .progress-text { + margin-top: 10px; + font-size: 14px; + color: #666; + } </style> \ No newline at end of file -- Gitblit v1.8.0