vue2.0实现音乐/视频播放进度条组件


Posted in Javascript onJune 06, 2018

基于vue2.0实现音乐/视频播放进度条组件的方法及代码解释,具体内容如下

需求分析:

①:进度条随着歌曲的播放延长,歌曲播放完时长度等于黑色总进度条长度;时间实时更新。

②:当滑动按钮时,实时更新播放时间,橙色进度条长度也会随着按钮的滑动而改变,当滑动结束时,橙色区域停留在滑动结束的位置,歌曲从当前进度开始播放。

③:点击进度条,橙色进度条长度变为点击处至起点的长度,并从当前点开始播放歌曲。

vue2.0实现音乐/视频播放进度条组件

大概思路:

①:左边的时间可以通过audio播放时派发的timeupdate事件获取,右边的时间为接口获取的当前歌曲的总时间。

②:进度条子组件的长度通过父组件传入一个percent值计算,percent值为播放进度与总进度的比值。

③:进度条的滑动及点击结束后,需要向父组件传递一个percent值,使用this.$emit()像父组件派发事件,父组件中设置事件响应函数,接收percent参数值,用于改变audio中当前播放的音乐进度。

详细实现,关键代码已经注释:

先上组件源码:

<template> 
 <div class="progress-bar" ref="progressBar" @click="progressClick"> 
  <div class="bar-inner"> 
   <div class="progress" ref="progress"></div> 
   <div class="progress-btn-wrapper"ref="progressBtn" 
      @touchstart.prevent = "progressTouchStart" 
      @touchmove.prevent = "progressTouchMove" 
      @touchend = "progressTouchEnd" 
   > 
    <div class="progress-btn"></div> 
   </div> 
  </div> 
 </div> 
</template> 
 
<script type="text/ecmascript-6"> 
 // 进度条按钮宽度,由于style中没有设置width,因此只能用clientWidth获取 
 export default { 
  data() { 
   return { 
    btnWidth: { 
     type: Number, 
     default: 0 
    }, 
    touchInfo: { 
     initiated: false 
    } 
   } 
  }, 
  props: { 
   percent: { 
    type: Number, 
    default: 0 
   } 
  }, 
  mounted() { 
   this.btnWidth = document.getElementsByClassName('progress-btn')[0].clientWidth 
  }, 
  methods: { 
   // 点击按钮 
   progressTouchStart(e) { 
    // 记录touch事件已经初始化 
    this.touchInfo.initiated = true 
    // 点击位置 
    this.touchInfo.startX = e.touches[0].pageX 
    // 点击时进度条长度 
    this.touchInfo.left = this.$refs.progress.clientWidth 
   }, 
   // 开始移动 
   progressTouchMove(e) { 
    if (!this.touchInfo.initiated) { 
     return 
    } 
    // 计算移动距离 
    const moveX = e.touches[0].pageX - this.touchInfo.startX 
    // 设置偏移值 
    const offsetWidth = Math.min(Math.max(0, this.touchInfo.left + moveX), 
     this.$refs.progressBar.clientWidth - this.btnWidth) 
    this._setOffset(offsetWidth) 
   }, 
   // 移动结束 
   progressTouchEnd(e) { 
    this.touchInfo.initiated = false 
    // 向父组件派发事件,传递当前百分比值 
    this._triggerPercent() 
   }, 
   // 进度条点击事件 
   progressClick(e) { 
    console.log('clikc') 
    // 设置进度条及按钮偏移 
    this._setOffset(e.offsetX) 
    // 通知父组件播放进度变化 
    this._triggerPercent() 
   }, 
   _triggerPercent() { 
    const barWidth = this.$refs.progressBar.clientWidth - this.btnWidth 
    const percent = Math.min(1, this.$refs.progress.clientWidth / barWidth) 
    this.$emit('percentChange', percent) 
   }, 
   // 设置偏移 
   _setOffset(offsetWidth) { 
    // 设置进度长度随着百分比变化 
    this.$refs.progress.style.width = `${offsetWidth}px` 
    // 设置按钮随着百分比偏移 
    this.$refs.progressBtn.style.transform = `translate3d(${offsetWidth}px, 0, 0)` 
   } 
  }, 
  watch: { 
   // 监听歌曲播放百分比变化 
   percent(newPercent, oldPercent) { 
    if (newPercent > 0 && !this.touchInfo.initiated) { 
     // 进度条总长度 
     const barWidth = this.$refs.progressBar.clientWidth - this.btnWidth 
     const offsetWidth = barWidth * newPercent 
     // 设置进度条及按钮偏移 
     this._setOffset(offsetWidth) 
    } 
   } 
  } 
 } 
</script> 
 
<style lang="stylus" rel="stylesheet/stylus"> 
 @import "~common/stylus/variable.styl" 
 
 .progress-bar 
  height 0.5rem 
  .bar-inner 
   position relative 
   top 0.2rem 
   height 0.08rem 
   background rgba(0, 0, 0, 0.3) 
   .progress 
    position absolute 
    height 100% 
    background $color-theme 
   .progress-btn-wrapper 
    position absolute 
    left -0.25rem 
    top -0.25rem 
    width 0.5rem 
    height 0.5rem 
    .progress-btn 
     position relative 
     top 0.12rem 
     left 0.12rem 
     box-sizing border-box 
     width 0.32rem 
     height 0.32rem 
     border 0.06rem solid $color-text 
     border-radius 50% 
     background $color-theme 
</style>

此为progerss-bar.vue组件源码,组件所需要父组件传入的值只有一个“percent”,为父组件中audio当前播放时间与总时间的比值,用于计算此组件中橙色进度条的长度。

组件的使用:

首先导入并注册组件(在此不做解释),随后使用此组件,dom:

<div class="progress-wrapper"> 
 <span class="time time-l">{{formatTime(currentTime)}}</span> 
 <div class="progress-bar-wrapper"> 
  <progress-bar :percent="percent" @percentChange="setProgress"></progress-bar> 
 </div> 
 <span class="time time-r">{{formatTime(currentSong.duration)}}</span> 
</div>

解释:两个span为左右两个时间值,progress-bar为调用的组件,需要传入percent值,用于子组件设置进度条长度
percent值来自于audio的currenTime与歌曲总长度的比值:

// 计算百分比 
percent() { 
 return Math.min(1, this.currentTime / this.currentSong.duration) 
}

@percentChange为子组件中派发过来的事件,详细请看子组件中源码及注释“_triggerPercent()”部分,此事件调用的方法用于接收子组件传过来的拖动按钮、点击进度条改变歌曲播放进度后的播放百分比,用于改变父组件中audio标签的currentTime,进而将歌曲播放进度设置为当前时间。

以下为父组件中,接收到子组件派发过来的事件后调用的函数。

// 设置进度 
  setProgress(percent) { 
   // 根据子组件传过来的百分比设置播放进度 
   this.$refs.audio.currentTime = this.currentSong.duration * percent 
   // 拖动后设置歌曲播放 
   if (!this.playing) { 
    this.togglePlaying() 
   } 
  },

样式(本人使用stylus):

.progress-wrapper 
     display flex 
     .time 
      font-size 0.24rem 
      &.time-l 
       position absolute 
       bottom 1.62rem 
       left 1rem 
      &.time-r 
       position absolute 
       bottom 1.62rem 
       right 1rem 
     .progress-bar-wrapper 
      position absolute 
      bottom 1.5rem 
      left 1.7rem 
      width 4.2rem

至此,进度条组件的实现及使用方法均介绍完毕。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Mootools 1.2教程(3) 数组使用简介
Sep 14 Javascript
Ruffy javascript 学习笔记
Nov 30 Javascript
JavaScript框架(iframe)操作总结
Apr 16 Javascript
AngularJs解决跨域问题案例详解(简单方法)
May 19 Javascript
Angular ng-repeat 对象和数组遍历实例
Sep 14 Javascript
Javascript 数组去重的方法(四种)详解及实例代码
Nov 24 Javascript
微信小程序实现日历功能
Nov 27 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【圆形情况】
Dec 13 Javascript
从零撸一个pc端vue的ui组件库( 计数器组件 )
Aug 08 Javascript
JS实现秒杀倒计时特效
Jan 02 Javascript
vue实现顶部菜单栏
Nov 08 Javascript
Javascript实现单选框效果
Dec 09 Javascript
vue实现简单loading进度条
Jun 06 #Javascript
security.js实现的RSA加密功能示例
Jun 06 #Javascript
Vue ElementUi同时校验多个表单(巧用new promise)
Jun 06 #Javascript
基于vue实现可搜索下拉框定制组件
Mar 26 #Javascript
深入浅析Vue中的 computed 和 watch
Jun 06 #Javascript
详解创建自定义的Angular Schematics
Jun 06 #Javascript
vue组件实现进度条效果
Jun 06 #Javascript
You might like
php表单转换textarea换行符的方法
2010/09/10 PHP
php中AES加密解密的例子小结
2014/02/18 PHP
在WordPress中安装使用视频播放器插件Hana Flv Player
2016/01/04 PHP
php求数组全排列,元素所有组合的方法
2016/05/05 PHP
浅谈php中变量的数据类型判断函数
2017/03/04 PHP
Yii2中添加全局函数的方法分析
2017/05/04 PHP
使用jQuery同时控制四张图片的伸缩实现代码
2013/04/19 Javascript
JS根据变量保存方法名并执行方法示例
2014/04/04 Javascript
jQuery如何将选中的对象转化为原始的DOM对象
2014/06/09 Javascript
将List对象列表转换成JSON格式的类实现方法
2016/07/04 Javascript
同步异步动态引入js文件的几种方法总结
2016/09/23 Javascript
使用PBFunc在Powerbuilder中支付宝当面付款功能
2016/10/01 Javascript
nodejs实现发出蜂鸣声音(系统报警声)的方法
2017/01/18 NodeJs
BootStrap TreeView使用实例详解
2017/11/01 Javascript
Vue组件的使用教程详解
2018/01/05 Javascript
详解node child_process模块学习笔记
2018/01/24 Javascript
vue-cli的工程模板与构建工具详解
2018/09/27 Javascript
jQuery添加新内容的四个常用方法分析【append,prepend,after,before】
2019/03/19 jQuery
vue学习笔记五:在vue项目里面使用引入公共方法详解
2019/04/04 Javascript
Vue+Express实现登录注销功能的实例代码
2019/05/05 Javascript
微信小程序使用canvas自适应屏幕画海报并保存图片功能
2019/07/25 Javascript
vue-element-admin 菜单标签失效的解决方式
2019/11/12 Javascript
ssm+vue前后端分离框架整合实现(附源码)
2020/07/08 Javascript
解决vue项目获取dom元素宽高总是不准确问题
2020/07/29 Javascript
基于element-ui封装表单金额输入框的方法示例
2021/01/06 Javascript
python getopt详解及简单实例
2016/12/30 Python
python3调用R的示例代码
2018/02/23 Python
Scrapy基于selenium结合爬取淘宝的实例讲解
2018/06/13 Python
Python+PyQt5实现美剧爬虫可视工具的方法
2019/04/25 Python
Python3 itchat实现微信定时发送群消息的实例代码
2019/07/12 Python
Python随机函数库random的使用方法详解
2019/08/21 Python
python调用c++返回带成员指针的类指针实例
2019/12/12 Python
css3动画效果抖动解决方法
2018/09/03 HTML / CSS
国贸专业大学生职业生涯规划范文
2014/01/10 职场文书
学校学雷锋活动总结
2014/06/26 职场文书
学生党支部工作总结2015
2015/05/26 职场文书