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