代码:
<template>
<div class="video-box">
<!-- poster="static/video/covershu.png"-->
<video
ref="homeVideo"
id="video"
class="video"
src="https://www.w3school.com.cn/i/movie.ogg"
:playsinline="true"
:webkit-playsinline="true"
@canplay="getVideoInfo"
@timeupdate="getCurrentInfo"
@ended="handleEnd"
@click="dispControls"
loop
:x5-video-player-fullscreen="true"
x5-video-orientation="portraint"
>
<p>你的浏览器不支持video标签.</p>
</video>
<div id="controls" class="controls">
<!-- pause play -->
<van-icon
:name="iconName"
class="play-btn"
@click="playOrPause"
color="white"
/>
<div class="slider">
<!-- 进度条容器 -->
<div
id="control"
ref="control"
class="control"
@click="setProgress"
@touchmove="controlMove"
@touchend="controlEnd"
>
<!-- 进度条本条 -->
<div
class="progress"
:style="{width: progressWidth + 'px' }"
/>
<!-- 滑块 -->
<div
v-if="progressWidth - 10 > 0"
class="slider_circle"
:style="{left: (progressWidth - 10) + 'px' }"
@touchstart="sliderStart"
/>
</div>
</div>
<span>
{{currentTime }} / {{ duration}}
</span>
</div>
</div>
</template>
<script setup>
import {ref} from "vue"
//video的ref
const homeVideo = ref(null)
// 展厅或者播放
const iconName = ref('play')
//显示总时长
const duration = ref(0)
//显示播放到的当前时间
const currentTime = ref(0)
//滑动到位置的高度
const progressWidth = ref(0)
//移动的类型,用来标明是否在拖动进度条
const moveType = ref("")
//拖动开始时点击的位置
const moveOffsetX = ref(0)
//拖动开始时进度条的宽度度
const curWidth = ref(0)
//播放暂停
const playOrPause = () => {
if (homeVideo.value.paused) {
homeVideo.value.play()
iconName.value = 'pause'
} else {
homeVideo.value.pause()
iconName.value = 'play'
}
}
//得到视频的时长等信息
const getVideoInfo = () => {
duration.value = formatTime(parseInt(homeVideo.value.duration))
}
// 视频播放完毕
const handleEnd = () => {
iconName.value = 'pause'
}
//得到视频当前播放到哪里的信息
const getCurrentInfo = () => {
// 视频已经播放时长
currentTime.value = formatTime(parseInt(homeVideo.value.currentTime))
let ratio = homeVideo.value.currentTime / homeVideo.value.duration
let allWidth = document.getElementById('control').getBoundingClientRect().width
progressWidth.value = allWidth * ratio
}
// 格式化时间函数
const formatTime = (s) => {
let t
if (s > -1) {
let hour = Math.floor(s / 3600)
let min = Math.floor(s / 60) % 60
let sec = s % 60
if (hour < 0 || hour === 0) {
t = ''
} else if (0 < hour < 10) {
t = '0' + hour + ":"
} else {
t = hour + ":"
}
if (min < 10) {
t += "0"
}
t += min + ":"
if (sec < 10) {
t += "0"
}
t += sec
}
return t
}
//设置进度条的长度
const setProgress = (e) => {
e.preventDefault()
const {left, width} = document.getElementById('control').getBoundingClientRect()
progressWidth.value = e.clientX - left
updadteCurrentTime(progressWidth.value, width)
}
//设置视频播放到指定的长度
const updadteCurrentTime = (progressWidth, width) => {
let dest = (progressWidth / width) * homeVideo.value.duration
homeVideo.value.currentTime = Math.floor(dest)
}
//当开始触摸开始在圆点按下时
const sliderStart = (e) => {
e.preventDefault()
moveOffsetX.value = e.touches[0].clientX
moveType.value = "slider"
curWidth.value = progressWidth.value
}
//当触摸在controls上移动时
const controlMove = (e) => {
if (moveType.value !== 'slider') {
return false
}
e.preventDefault()
// 滑动距离可视区域左侧的距离
const X = e.touches[0].clientX
//得到本次拖动已经过的距离
const cl = X - moveOffsetX.value
//容器的宽度
const { width } = document.getElementById('control').getBoundingClientRect()
//得到已拖动到宽度
const ml = curWidth.value + cl
let proWidth
if (ml <= 0) {
//进度条长度最小和最大值的界定
proWidth = 0
} else if (ml >= width) {
proWidth = width
} else {
proWidth = ml
}
progressWidth.value = proWidth
// 更新当前时间
updadteCurrentTime(progressWidth.value, width)
}
//滑动结束
const controlEnd = () => {
moveType.value = ""
}
const dispControls = () => {
let isDisp = document.getElementById('controls').style.visibility
if (isDisp === 'hidden') {
document.getElementById('controls').style.visibility = 'visible'
} else {
document.getElementById('controls').style.visibility = 'hidden'
}
}
</script>
<style lang="less">
@import "index.less";
</style>
index.less文件:
.video-box {
width:100%;
height: 100vh;
background-color: #000;
.video {
width: 100vw;
height: 422px;
margin-top: 200px;
}
.controls {
width: 100vw;
z-index: 1;
display: flex;
align-items: center;
.play-btn {
width: 30px;
height: 30px;
padding: 20px;
}
.progress {
height: 7px;
border-radius: 3px;
background-color: #e4c487;
}
.slider {
flex: 1;
.control {
width: 100%;
background-color: white;
padding: 20px 0;
position: relative;
background-clip: content-box;
z-index: 2;
}
}
span {
color: white;
font-size: 24px;
padding: 0 20px;
}
.slider_circle {
position: absolute;
left: 0;
top: 13px;
width: 20px;
height: 20px;
border-radius: 10px;
border: 1px;
background: #e4c487;
}
}
}
效果图: