实现的是拖动或点击进度条,歌词随之滚动到指定位置,做到与歌曲播放同步。
进度条可参考vue.js实现歌曲播放进度条 ,歌词滚动可参考 vue.js实现歌词高亮滚动与播放同步

效果图:

vue.js歌曲播放进度条与歌词滚动绑定

1、布局部分
(1)、template部分

<audio ref="player" autoplay ></audio>

//歌词部分
<div class="detail">
  <div class="song-title">
    <p ref="song">歌名</p>
    <p ref="singer">歌手</p>
  </div>
  <div class="wrapper">
    <ul ref="ul" class="content">
    <li v-for="(item,index) of ms" :key=item.index>{{item.c}}</li>
  </ul>
  </div>
</div>

//进度条
<div class="bar">
  <div class="progressbar" @click="playMusic" ref="runfatbar">
  <div class="greenbar" ref="runbar" >
  <span class="yuan"></span>
  </div>
  </div>
</div>

//时间
<div class="time-text">{{cTime}}</div>
<div class="right-time time-text">{{dTime}}</div> 

(2)、style部分

//歌词部分
.detail
  position absolute
  top 1rem
  bottom 2.6rem
  left 0
  right 0
  text-align center
  color  #26a2ff 
  .song-title
    width 100%
    height 2rem
    // background-color #eeefff
    p
      width 100%
      line-height .8rem
      font-size 18px
      color #FFD700 
      margin-top .1rem
      text-align center
      // background-color #fff
  .wrapper
    overflow hidden
    position absolute
    top 2rem
    right 0
    left 0
    height 545px
    // background-color yellow
    ul
      line-height 32px
      width 100%
      padding-bottom 1rem
      // background-color red
      li
        font-size 16px
        transition-duration 1200ms
        // background-color skyblue
      .lineHigh
        color #FFD700 
//进度条部分
.bar 
  width: 80%;
  height: .3rem
  margin-left 10%
  position fixed 
  bottom 2.5rem
  // background-color red
  .progressbar 
    width: 100%;
    height: .1rem
    background-color: #999999;
    // background-color red
    margin-top: .1rem;
    border-radius: .2rem;
    // position: relative;
    .greenbar 
      height: .1rem;
      border-radius: .2rem;
      position: absolute;
      top: .1rem;
      left: 0;
      // overflow hidden 
      // 圆形变成椭圆
      background-color: #1296db;
      // background-color #fff
      .yuan 
        border-radius 10px
        position absolute
        top -.05rem
        right -0.01rem
        width .2rem
        height .2rem
        background-color #fff
.time-text 
  position fixed
  bottom 2.5rem
  font-size 13px
  line-height .5rem
.right-time 
  right 0
  .audio-btn 
    width: 100%;
    text-align: center;

2、逻辑部分

data () {
    return {
      lineNo: 0,
      Cpos: 7,
      offset: -32,
      ms: [],
    }
  },

mounted () {
    const music = this.$refs.player  // 音频所在对象
    const musicBar = this.$refs.runbar  // 颜色进度条所在对象
    const musicWidth = this.$refs.runfatbar.offsetWidth // 底部进度条总宽
    
    // 监听颜色进度条是否触摸拖动结束
    musicBar.addEventListener('touchend', () => {
      const touwidth = (musicBar.offsetWidth / musicWidth) // 计算进度条所在比例
      music.currentTime = music.duration * touwidth // 通过所在比例赋值给音频应在的播放时间

      const ulist = this.$refs.ul
      const list = ulist.getElementsByTagName("li");//获取全部歌词
      for(var i = 0; i <= this.ms.length; i++) {
        if(parseFloat(this.ms[i].t) <= music.currentTime) {
        // 删除之前的高亮样式与设置当前点击部分高亮样式
        if(this.lineNo < i) {
          list[this.lineNo].removeAttribute("class");//去掉上面的高亮样式
          this.lineNo = i
          list[this.lineNo].className = "lineHigh";//高亮显示当前行
        }else {
          list[this.lineNo-1].removeAttribute("class");//去掉下面的高亮样式
          this.lineNo = i
          list[this.lineNo].className = "lineHigh";//高亮显示当前行
        }
        
        // 进行播放
        music.play()
        this.$refs.icon.innerHTML = ("&#xe6ad;");
      }
      }
      
    })
},

methods: {
    // 点击进度条事件
    playMusic (e) {
      const music = this.$refs.player // 音频所在对象
      const barWidth = e.pageX / this.$refs.runfatbar.offsetWidth // 计算点击位置相对父元素总宽的比例
      this.$refs.runbar.style.width = `${barWidth * 100}%` // 进度条应所在的比例总宽
      music.currentTime = music.duration * barWidth // 计算点击时应播放所在的时间

      const ulist = this.$refs.ul
      const list = ulist.getElementsByTagName("li");
      for(var i = 0; i <= this.ms.length; i++) {
        if(parseFloat(this.ms[i].t) <= music.currentTime) {
        // 删除之前的高亮样式与设置当前点击部分高亮样式
        if(this.lineNo < i) {
          list[this.lineNo].removeAttribute("class");//去掉上面的高亮样式
          this.lineNo = i
          list[this.lineNo].className = "lineHigh";//高亮显示当前行
        }else {
          list[this.lineNo-1].removeAttribute("class");//去掉下面的高亮样式
          this.lineNo = i
          list[this.lineNo].className = "lineHigh";//高亮显示当前行
        }
        
        // 进行播放
        music.play()
        this.$refs.icon.innerHTML = ("&#xe6ad;");
      }
      }
    },

}
Logo

前往低代码交流专区

更多推荐