Uniapp微信小程序视频全屏播放功能极简实现法

*高端的食材,往往只需要最朴素的烹饪方式,本文用css旋转定位实现视频全屏播放,朴实无华,简单实用,本文为原创,分享请标明出处*

实习入职第三周,在经过两周的改bug和切图之后,组里说给我一个有挑战性的需求,做一个视频全屏播放的功能
在这里插入图片描述
在这里插入图片描述
简单来说,就是点击按钮,将视频全屏播放,宽高比例过1.8的横屏播放,小于1.8的仍然竖屏播放,就像下面这样
Uniapp微信小程序视频全屏播放功能极简实现法_第1张图片
看完需求我的思考如下:
1.在原页面操作属实麻烦,需要点击全屏按钮跳转到新页面播放
2.由于需要保留侧边栏的点赞关注等功能,所以需要组件分离复用
3.由于存在横竖屏之分,所以跳转页面时需要传递视频宽高比,新页 面需要分别写出横屏和竖屏的css样式
开工:
项目中视频用的是uniapp的video组件,底部的滑动条用的是uniapp的slider组件,我于是乎我在uniapp的文档中查到一个属性
在这里插入图片描述
由于我们的项目将全屏按钮隐藏掉了,而且这个属性不能手动设置判断的宽高比,所以我选择弃用现有的轮子,另辟蹊径
有可能是前两周切图css写多了,一下就想到既然是横屏直接将视图旋转90度不久好了吗,于是我开始着手尝试
1.直接将视频顺时针旋转90度,并且将视频宽度改为100vh,高度改为100vw,使其充满整个屏幕

 	.full-page-video-horizontal {
 		width: 100vh;
 		height: 100vw;
 		transform: rotate(90deg);
 	}

效果如下
Uniapp微信小程序视频全屏播放功能极简实现法_第2张图片
很明显,这里出现了中心点偏移的情况,css3旋转的中心点默认是元素的中心点,所以我们将宽高改变后元素的中心点由原来的(50vw,50vh)变成了(50vh,50vw),所以接下来要用相对定位将屏幕中心点(即整个元素)移回原来的坐标
Uniapp微信小程序视频全屏播放功能极简实现法_第3张图片
复位

 	.full-page-video-horizontal {
 		width: 100vh;
 		height: 100vw;
 		transform: rotate(90deg);
      +  position: relative;
 	  +  right: calc(50vh - 50vw);
 	  +  top: calc(50vh - 50vw)
 	}

视频旋转完成了,接下来是对slider的处理,这里有一个大坑,因为我们直接将slider也旋转90度再复位到屏幕底部,但是因为uniapp的slider组件并没有给出相应的方向属性,所以在我们把视图旋转过来之后,虽然滑动条竖向显示了,但是它仍然只能横向拖动,简单来说就是:视图旋转了,逻辑没有跟着旋转
Uniapp微信小程序视频全屏播放功能极简实现法_第4张图片
所以当横屏播放时,我们也弃用slider自带的拖动功能,使用touchstart和touchend替代拖动和点击事件
拖动开始,将当前的y坐标保存到状态:

touchStart(e) {
 				this.currentVideoContext.pause()
 				this.nowY = e.changedTouches[0].pageY
 			},

拖动结束,计算当前y和状态中y的差值,得出偏移量,计算偏移量和屏幕总高度的比,并等比移动进度条

		touchEnd(e) {
 				const {
 					windowWidth,
 					windowHeight
 				} = uni.getSystemInfoSync();
 				let sliderWidth = windowHeight * 0.85
 				let y = e.changedTouches[0].pageY
 				let dy = y - this.nowY
 				let value = dy / sliderWidth
 				const {
 					duration,
 					currentTime
 				} = this.progressTime;
 				const time = duration * (value + (currentTime / duration));
 				this.currentVideoContext.seek(time)
 				this.currentVideoContext.play()
 			},

模拟点击事件,即当拖动的距离足够小时,直接记录当前y坐标,获取视口高度,得出当前y坐标在整个视口的相对位置,并且把进度条调到整个进度条的同比相对位置

		tapSlider(e) {
 				const {
 					windowWidth,
 					windowHeight
 				} = uni.getSystemInfoSync();
 				let begin = windowHeight * 0.07
 				let y = e.changedTouches[0].pageY
 				let dy = y - begin
 				let rate = dy / (windowHeight * 0.85)
 				const {
 					duration,
 					currentTime
 				} = this.progressTime;
 				let time = duration * rate
 				this.currentVideoContext.seek(time)
 			},

PS:由于拖动进度条的时候视频仍处于播放中,进度状态不停的在更新,会导致拖动时有闪动的情况,所以需要在拖动开始时暂停视频,在拖动结束后再播放,但是uniapp的slider组件没有拖动开始的属性,只有sliderChanging,它会在拖动中高频率触发,所以我们写一个节流函数让它3秒只触发一次暂停视频,减少不必要的内存消耗

		//进度条拖拽节流
 			sliderChanging() {
 				if (this.t) return
 				this.t = setTimeout(() => {
 					this.t = null
 				}, 3000)
 				this.currentVideoContext.pause()
 			},

具体实现的一些细节需要各位自行写出代码编译尝试,祝大家学有所得

你可能感兴趣的:(前端学习经验记录,uni-app,css,vue)