当前位置:   article > 正文

vue3实现video控件的h5端进度条拖拽与跳转_vue-video-player 拖动进度条

vue-video-player 拖动进度条

代码:

  1. <template>
  2. <div class="video-box">
  3. <!-- poster="static/video/covershu.png"-->
  4. <video
  5. ref="homeVideo"
  6. id="video"
  7. class="video"
  8. src="https://www.w3school.com.cn/i/movie.ogg"
  9. :playsinline="true"
  10. :webkit-playsinline="true"
  11. @canplay="getVideoInfo"
  12. @timeupdate="getCurrentInfo"
  13. @ended="handleEnd"
  14. @click="dispControls"
  15. loop
  16. :x5-video-player-fullscreen="true"
  17. x5-video-orientation="portraint"
  18. >
  19. <p>你的浏览器不支持video标签.</p>
  20. </video>
  21. <div id="controls" class="controls">
  22. <!-- pause play -->
  23. <van-icon
  24. :name="iconName"
  25. class="play-btn"
  26. @click="playOrPause"
  27. color="white"
  28. />
  29. <div class="slider">
  30. <!-- 进度条容器 -->
  31. <div
  32. id="control"
  33. ref="control"
  34. class="control"
  35. @click="setProgress"
  36. @touchmove="controlMove"
  37. @touchend="controlEnd"
  38. >
  39. <!-- 进度条本条 -->
  40. <div
  41. class="progress"
  42. :style="{width: progressWidth + 'px' }"
  43. />
  44. <!-- 滑块 -->
  45. <div
  46. v-if="progressWidth - 10 > 0"
  47. class="slider_circle"
  48. :style="{left: (progressWidth - 10) + 'px' }"
  49. @touchstart="sliderStart"
  50. />
  51. </div>
  52. </div>
  53. <span>
  54. {{currentTime }} / {{ duration}}
  55. </span>
  56. </div>
  57. </div>
  58. </template>
  59. <script setup>
  60. import {ref} from "vue"
  61. //video的ref
  62. const homeVideo = ref(null)
  63. // 展厅或者播放
  64. const iconName = ref('play')
  65. //显示总时长
  66. const duration = ref(0)
  67. //显示播放到的当前时间
  68. const currentTime = ref(0)
  69. //滑动到位置的高度
  70. const progressWidth = ref(0)
  71. //移动的类型,用来标明是否在拖动进度条
  72. const moveType = ref("")
  73. //拖动开始时点击的位置
  74. const moveOffsetX = ref(0)
  75. //拖动开始时进度条的宽度度
  76. const curWidth = ref(0)
  77. //播放暂停
  78. const playOrPause = () => {
  79. if (homeVideo.value.paused) {
  80. homeVideo.value.play()
  81. iconName.value = 'pause'
  82. } else {
  83. homeVideo.value.pause()
  84. iconName.value = 'play'
  85. }
  86. }
  87. //得到视频的时长等信息
  88. const getVideoInfo = () => {
  89. duration.value = formatTime(parseInt(homeVideo.value.duration))
  90. }
  91. // 视频播放完毕
  92. const handleEnd = () => {
  93. iconName.value = 'pause'
  94. }
  95. //得到视频当前播放到哪里的信息
  96. const getCurrentInfo = () => {
  97. // 视频已经播放时长
  98. currentTime.value = formatTime(parseInt(homeVideo.value.currentTime))
  99. let ratio = homeVideo.value.currentTime / homeVideo.value.duration
  100. let allWidth = document.getElementById('control').getBoundingClientRect().width
  101. progressWidth.value = allWidth * ratio
  102. }
  103. // 格式化时间函数
  104. const formatTime = (s) => {
  105. let t
  106. if (s > -1) {
  107. let hour = Math.floor(s / 3600)
  108. let min = Math.floor(s / 60) % 60
  109. let sec = s % 60
  110. if (hour < 0 || hour === 0) {
  111. t = ''
  112. } else if (0 < hour < 10) {
  113. t = '0' + hour + ":"
  114. } else {
  115. t = hour + ":"
  116. }
  117. if (min < 10) {
  118. t += "0"
  119. }
  120. t += min + ":"
  121. if (sec < 10) {
  122. t += "0"
  123. }
  124. t += sec
  125. }
  126. return t
  127. }
  128. //设置进度条的长度
  129. const setProgress = (e) => {
  130. e.preventDefault()
  131. const {left, width} = document.getElementById('control').getBoundingClientRect()
  132. progressWidth.value = e.clientX - left
  133. updadteCurrentTime(progressWidth.value, width)
  134. }
  135. //设置视频播放到指定的长度
  136. const updadteCurrentTime = (progressWidth, width) => {
  137. let dest = (progressWidth / width) * homeVideo.value.duration
  138. homeVideo.value.currentTime = Math.floor(dest)
  139. }
  140. //当开始触摸开始在圆点按下时
  141. const sliderStart = (e) => {
  142. e.preventDefault()
  143. moveOffsetX.value = e.touches[0].clientX
  144. moveType.value = "slider"
  145. curWidth.value = progressWidth.value
  146. }
  147. //当触摸在controls上移动时
  148. const controlMove = (e) => {
  149. if (moveType.value !== 'slider') {
  150. return false
  151. }
  152. e.preventDefault()
  153. // 滑动距离可视区域左侧的距离
  154. const X = e.touches[0].clientX
  155. //得到本次拖动已经过的距离
  156. const cl = X - moveOffsetX.value
  157. //容器的宽度
  158. const { width } = document.getElementById('control').getBoundingClientRect()
  159. //得到已拖动到宽度
  160. const ml = curWidth.value + cl
  161. let proWidth
  162. if (ml <= 0) {
  163. //进度条长度最小和最大值的界定
  164. proWidth = 0
  165. } else if (ml >= width) {
  166. proWidth = width
  167. } else {
  168. proWidth = ml
  169. }
  170. progressWidth.value = proWidth
  171. // 更新当前时间
  172. updadteCurrentTime(progressWidth.value, width)
  173. }
  174. //滑动结束
  175. const controlEnd = () => {
  176. moveType.value = ""
  177. }
  178. const dispControls = () => {
  179. let isDisp = document.getElementById('controls').style.visibility
  180. if (isDisp === 'hidden') {
  181. document.getElementById('controls').style.visibility = 'visible'
  182. } else {
  183. document.getElementById('controls').style.visibility = 'hidden'
  184. }
  185. }
  186. </script>
  187. <style lang="less">
  188. @import "index.less";
  189. </style>

index.less文件:

  1. .video-box {
  2. width:100%;
  3. height: 100vh;
  4. background-color: #000;
  5. .video {
  6. width: 100vw;
  7. height: 422px;
  8. margin-top: 200px;
  9. }
  10. .controls {
  11. width: 100vw;
  12. z-index: 1;
  13. display: flex;
  14. align-items: center;
  15. .play-btn {
  16. width: 30px;
  17. height: 30px;
  18. padding: 20px;
  19. }
  20. .progress {
  21. height: 7px;
  22. border-radius: 3px;
  23. background-color: #e4c487;
  24. }
  25. .slider {
  26. flex: 1;
  27. .control {
  28. width: 100%;
  29. background-color: white;
  30. padding: 20px 0;
  31. position: relative;
  32. background-clip: content-box;
  33. z-index: 2;
  34. }
  35. }
  36. span {
  37. color: white;
  38. font-size: 24px;
  39. padding: 0 20px;
  40. }
  41. .slider_circle {
  42. position: absolute;
  43. left: 0;
  44. top: 13px;
  45. width: 20px;
  46. height: 20px;
  47. border-radius: 10px;
  48. border: 1px;
  49. background: #e4c487;
  50. }
  51. }
  52. }

效果图:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/130252
推荐阅读
相关标签
  

闽ICP备14008679号