010_Vue音乐播放器(player.vue 播放器组件)

不满意之前的页面结构,所以我重构了一下,以home.vue作为父级组件,recommend组件、singer组件、rank组件和search组件

作为子路由自建都归类到tab组件中。

010_Vue音乐播放器(player.vue 播放器组件)_第1张图片

010_Vue音乐播放器(player.vue 播放器组件)_第2张图片

010_Vue音乐播放器(player.vue 播放器组件)_第3张图片

player.vue 组件,放置在home.vue组件下,这个组件一直存在,不过由于v-show="isShow"的关系,vuex中的playList没有数据,所以隐藏掉了,然后根据fullScreen数据,来判断是展示正常播放器还是迷你播放器。





根据传入的 percent(百分比,由currentTime和duration计算而来)播放时间百分比

010_Vue音乐播放器(player.vue 播放器组件)_第26张图片

010_Vue音乐播放器(player.vue 播放器组件)_第27张图片

效果页

接下来通过一系列touch事件实现拖拽按钮调整播放位置的操作

010_Vue音乐播放器(player.vue 播放器组件)_第28张图片

首先 touchstart 事件 ,将 拖拽 标识变量initiated变量置为true,根据event对象的touches[0].pageX得到touchstart的起始位置 startX,存入this.touch对象,然后由已播放进度条的宽度得到按钮的偏移量 left。

在touchmove事件中,首先判断是否 拖拽初始化,未初始化则return,然后通过移动后的touches[0].pageX起始坐标减去记录的起始坐标startX得出移动偏移量deltaX,this.touch.left + deltaX 得出 拖动后的位置,然后跟 this.$refs.progressBar.clientWidth - 16 (进度条最大值)比较,小于它则取得出的拖动width,大于则取this.$refs.progressBar.clientWidth - 16(进度条末尾),然后将拖动的距离作为参数调用_offset函数,在函数中对 进度条 和 按钮的位置进行设置,实现偏移效果。

上面只是实现拖动,歌曲实际播放位置并没有改变,在touchend事件中,修改初始化值为false

010_Vue音乐播放器(player.vue 播放器组件)_第29张图片

调用triggerPercent函数,将进度条偏移的百分比作为参数抛出percent函数给父组件处理。根据进度百分比,设置audio的currentTime的值来进行歌曲播放位置的改变。

010_Vue音乐播放器(player.vue 播放器组件)_第30张图片

010_Vue音乐播放器(player.vue 播放器组件)_第31张图片

010_Vue音乐播放器(player.vue 播放器组件)_第32张图片

效果页

 

修改播放模式(顺序播放,单曲循环,随机播放)

mapGetters引入mode和sequenceList数据

010_Vue音乐播放器(player.vue 播放器组件)_第33张图片

给播放模式绑定样式和事件

010_Vue音乐播放器(player.vue 播放器组件)_第34张图片

010_Vue音乐播放器(player.vue 播放器组件)_第35张图片

010_Vue音乐播放器(player.vue 播放器组件)_第36张图片

010_Vue音乐播放器(player.vue 播放器组件)_第37张图片

洗牌函数

    /*洗牌函数的封装*/
    getRandom(min, max) {
      return Math.floor(Math.random() * (max - min + 1) + min);
    },
    shuffle(arr) {
      //不修改原数组
      let _arr = arr.slice();
      for (let i = 0; i < _arr.length; i++) {
        let j = this.getRandom(0, i);
        let t = _arr[i];
        _arr[i] = _arr[j];
        _arr[j] = t;
      }
      return _arr;
    }

至此,可以通过点击播放模式来切换歌单,且保持当前歌曲的播放状态。

 

根据audio派发的ended事件,对歌曲播放完毕后进行处理

010_Vue音乐播放器(player.vue 播放器组件)_第38张图片

010_Vue音乐播放器(player.vue 播放器组件)_第39张图片

 

点击进度条按钮的bug

当点击到进度条按钮本身时,由于获取的节点对象错误,导致进度条进度移动的错误

010_Vue音乐播放器(player.vue 播放器组件)_第40张图片

 

歌词的显示

将歌词部分(由currentSongInfo中取得)插入到Scroll组件中,以进行滚动,并根据currentShow来表示当前应当显示图片还是歌词部分。

010_Vue音乐播放器(player.vue 播放器组件)_第41张图片

010_Vue音乐播放器(player.vue 播放器组件)_第42张图片

其中,歌词部分使用Lyric函数进行处理(由cnpm install lyric-parser --save安装)

010_Vue音乐播放器(player.vue 播放器组件)_第43张图片

010_Vue音乐播放器(player.vue 播放器组件)_第44张图片

010_Vue音乐播放器(player.vue 播放器组件)_第45张图片

此时歌词即能随着歌曲滚动。

头像和歌词部分左右滑动切换

010_Vue音乐播放器(player.vue 播放器组件)_第46张图片

    //图像/歌词滑动切换的效果
    middleTouchStart(e) {
      this.touch.initiated = true; //初始化
      const touch = e.touches[0];
      this.touch.startX = touch.pageX;
      this.touch.startY = touch.pageY;
    },
    middleTouchMove(e) {
      if (!this.touch.initiated) {
        return;
      }
      const touch = e.touches[0];
      const deltaX = touch.pageX - this.touch.startX;
      const deltaY = touch.pageY - this.touch.startY;

      if (Math.abs(deltaY) > Math.abs(deltaX)) {
        //纵轴上的偏移大于横轴上的位移,认为是纵向滚动,不切换
        return;
      }
      const left = this.currentShow === "img" ? 0 : -window.innerWidth; //为图像则不偏移,为歌词则向左移。
      const offsetWidth = Math.min(
        0,
        Math.max(-window.innerWidth, left + deltaX)
      );
      this.touch.percent = Math.abs(offsetWidth / window.innerWidth); //得到滑动的比例
      this.$refs.lyricList.$el.style.transform = `translate3d(${offsetWidth}px,0,0)`; //vue组件无法直接访问节点,使用$el
      this.$refs.lyricList.$el.style.transform = `transformDuration:300ms`;
      this.$refs.middleL.style.opacity = 1 - this.touch.percent;
      this.$refs.middleL.style.transform = `transformDuration:300ms`;
    },
    middleTouchEnd() {
      let offsetWidth;
      let opacity;      //从右向左滑
      if (this.currentShow == "img") {
        //滑动距离大于10%
        if (this.touch.percent > 0.1) {
          offsetWidth = -window.innerWidth;
          opacity= 0;
          this.$refs.middleL.style.opacity = opacity;
          this.$refs.middleL.style.transform = `transformDuration:300ms`;
          this.currentShow = "lyric"; //同时改变当前显示状态
        } else {
          offsetWidth = 0;
          opacity= 1;
          this.$refs.middleL.style.opacity = opacity;
          this.$refs.middleL.style.transform = `transformDuration:300ms`;
        }
      }
      //从左向右滑
      else {
        if (this.percent < 0.9) {
          offsetWidth = 0;
          opacity= 1;
          this.$refs.middleL.style.opacity = opacity;
          this.$refs.middleL.style.transform = `transformDuration:300ms`;
          this.currentShow = "img";
        } else {
          offsetWidth = -window.innerWidth;
          opacity= 0;
          this.$refs.middleL.style.opacity = opacity;
          this.$refs.middleL.style.transform = `transformDuration:300ms`;
        }
      }
      this.$refs.lyricList.$el.style.transform = `translate3d(${offsetWidth}px,0,0)`; //vue组件无法直接访问节点,使用$el
      this.touch.initiated = false
    }

样式

    .middle {
      width: 202vw;
      .middle-l {
        width: 100vw;
        vertical-align: top;
        display: inline-block;
        transition: all 1s;
        .cd-wrapper {
          .cd {
            .image {
              width: 17rem;
              border: 2px solid gray;
              border-radius: 50%;
              animation: imgRotate 20s linear infinite;
            }
          }
        }
      }
      .middle-r {
        width: 100vw;
        display: inline-block;
        transition: all 1s;
        .lyric-wrapper {
          .text {
            line-height: 2;
            color: rgba(255, 255, 255, 0.5);
            font-size: 1rem;
          }
          // 当前行歌词高亮
          .currentLine {
            font-size: 1.2rem;
            color: rgba(255, 255, 255, 1);
          }
        }
      }
      .wrapper {
        height: 63vh !important;
      }
    }

此时图像和歌词能够左右切换。

循环播放时歌词偏移回初始位置

010_Vue音乐播放器(player.vue 播放器组件)_第47张图片

歌曲播放/暂停时 ,歌词滚动状态的改变

010_Vue音乐播放器(player.vue 播放器组件)_第48张图片

拖动进度条,根据百分比,修改歌词的偏移位置

010_Vue音乐播放器(player.vue 播放器组件)_第49张图片

效果图

 

 

酷狗API歌曲数据请求有次数限制,当天次数限制时,弹出提示框后跳回歌单详情页。

010_Vue音乐播放器(player.vue 播放器组件)_第50张图片

效果页:

 

 

 

 

 

你可能感兴趣的:(Vue音乐播放器)