WY音乐播放器制作(2)

  • 完整代码地址
    https://github.com/Kevin5979/WYmusic.git

首页完善

实现效果

首页

详情页

最新专辑和歌单详情差不多,可以封装成一个组件

详情页

头部功能

  1. 换肤换背景,前面写过
  2. 可返回,back
头部

中间图片功能:

  1. 下拉图片变大
  2. 上拉图片变模糊
  3. 注意:高斯模糊效果十分消耗性能的,不推荐使用,非要使用,建议只设置一次
if (offsetY < 0) {
  // 向上滚动,图片变淡
  let opacity = Math.abs(offsetY) / defaultHeight;
  this.$refs.top.changeMask(opacity);
  // let scale = 1 + Math.abs(offsetY) / defaultHeight;
  // this.$refs.top.$el.style.filter = `blur(${scale}px)`
} else {
  // 向上滚动,图片变大
  let scale = 1 + offsetY / defaultHeight;
  this.$refs.top.$el.style.transform = `scale(${scale})`;
}

底部播放列表功能

播放列表
  1. 实现滚动效果

    使用自己编写的滚动组件
    
     
    
    
  1. 点击某一首歌,跳转到播放界面,歌曲详情展示

    // 映射Actions
    ...mapActions(["setFullScreen", "setSongDetail"])
        
    selectMusic(id) {
        // 修改vuex的数据,展示全局的播放器并且请求数据、渲染数据
       this.setFullScreen(true);
       this.setSongDetail([id]);
    }
    
  1. 点击播放全部,跳转到播放界面,默认播放第一首

    selectAllMusic() {
      this.setFullScreen(true);
      let ids = this.tracks.map(item => item.id);
      this.setSongDetail([ids]);
    }
    

主播放界面

播放界面

使用插件:vue-awesome-swiper

头部封装,点击向下箭头,能关闭主播放界面

头部
...mapActions(["setFullScreen", "setMiniPlayer"]),
hiddenNormalPlayer() {
  this.setFullScreen(false);
  this.setMiniPlayer(true);
}

中间,可左滑,切换成歌词界面

左边
右边
  1. 搭建vue-awesome-swiper结构(三层结构)

    
    
    import { Swiper, SwiperSlide } from "vue-awesome-swiper";
    import "swiper/css/swiper.css";
    
  2. vue-awesome-swiper配置

      data() {
        return {
          swiperOption: {
            // 分页器
            pagination: {
              el: ".swiper-pagination",
              bulletClass: "my-bullet", // 自定义默认类名
              bulletActiveClass: "my-bullet-active" // 自定义默认类名
            },
            // 异步加载
            observer: true,
            observeParents: true,
            observeSlideChildren: true
          }
        };
      }
    
  3. 踩坑:前面已经使用过vue-awesome-swiper默认激活的类名,这里要自定义类名

    并且style不能加 scoped 属性,建议新建一个style标签

设置播放键切换(watch,vuex)

底部
  1. 进度条设置

        
    00:00
    00:00
  2. 点击图标切换

    // vuex设置全局的播放状态
    import { mapGetters, mapActions } from "vuex";
      methods: {
        ...mapActions(["setIsPlaying", "setModeType"]),
        play() {
            // 播放暂停切换
          this.setIsPlaying(!this.isPlaying);
        },
        mode() {
            // 循环模式的切换
          if (this.modeType === modeType.loop) {
            this.setModeType(modeType.one);
          } else if (this.modeType === modeType.one) {
            this.setModeType(modeType.random);
          } else if (this.modeType === modeType.random) {
            this.setModeType(modeType.loop);
          }
        }
      },
      computed: {
        ...mapGetters(["isPlaying", "modeType"])
      }
    
    /**************************改变图标*****************************/
    // 通过类名
      watch: {
        isPlaying(newValue, oldValue) {
          if (newValue) {
            this.$refs.play.classList.add("active");
          } else {
            this.$refs.play.classList.remove("active");
          }
        },
        modeType(newValue, oldValue) {
          if (newValue === modeType.loop) {
            this.$refs.mode.classList.remove("random")
            this.$refs.mode.classList.add("loop")
          } else if (newValue === modeType.one) {
            this.$refs.mode.classList.remove("loop")
            this.$refs.mode.classList.add("one")
          } else if (newValue === modeType.random) {
            this.$refs.mode.classList.remove("one")
            this.$refs.mode.classList.add("random")
          }
        }
      }
    
    

列表播放器

  1. 使用插件: velocity-animate

    使用Vue动画

播放列表
  1. 播放模式和主要播放器同步

    前面一样的功能: 通过watch观察模式/播放的状态,在同步到vuex中

  2. velocity-animate的使用

    // 导入
    import Velocity from "velocity-animate";
    import "velocity-animate/velocity.ui";
    // 使用
    /** 
    * el:元素 Dom,
    * 第二个参数: 动画名称 String
    * 第三个参数: 动画配置
    * 第四个参数: 回调函数
    */
    Velocity(el, "transition.perspectiveUpIn", { duration: 500 }, function() {});
    
  3. velocity-animate配合Vue自定义动画使用

      
          内容
      
    
    
     methods: {
         // 进入动画
       // done 调用该函数,告诉vue,该动画执行完毕
       enter(el, done) {
         Velocity(el, "transition.perspectiveUpIn", { duration: 500 }, function() {
           done();
         });
       },
       leave(el, done) {
         Velocity(
           el,
           "transition.perspectiveUpOut",
           { duration: 500 },
           function() {
             done();
           }
         );
       },
    }
    
  4. 踩坑:歌曲列表不能滚动

    原因:一开始就初始化,但是数据后面过来,导致高度不正确

    解决:IScroll中的refresh()刷新高度

    // ScrollView 组件
      methods: {
        // 重新获取高度
        refresh() {
            // 停留100ms刷新
          setTimeout(() => {
            this.iscroll.refresh();
          }, 100);
        }
      },
    
    // 列表播放组件,每次数据变化,刷新高度
    watch: {
       isShowListPlayer(newValue, oldValue) {
          if (newValue) {
            // 刷新高度
            this.$refs.ScrollView.refresh();
          }
        }
     }
    
  5. 删除所有歌曲后,退出该列表播放器、主播放器、底部播放器

    // 通过设置vue的state属性,来清空列表
    delAll() {
        this.setDelSong();
    }
    
      // 播放列表删除歌曲
      [SET_DEL_SONG](state, index) {
        if (index !== undefined) {
          state.songs.splice(index, 1)
        } else {
          // 清空
          state.songs = []
        }
        if (state.songs.length === 0) {
          state.isFullScreen = false,
            state.isShowMiniPlayer = false,
            state.isShowListPlayer = false
        }
      }
    
  6. 有坑:删除所有歌曲后,页面报错

    原因:每次列表歌曲变化,去设置当前播放歌曲的详情,删除完后,没有歌曲去获取详情

    解决:修改监听歌曲变化的函数

    // 主播放界面  
    // 只要歌曲一变化,就切换歌词
      watch: {
        currentSong(newValue, oldValue) {
          if (newValue.id === undefined) {
              // 没有歌曲时,不操作
            return;
          }
            // 切换歌词
          this.setSongLyric(newValue.id);
        }
      }
    
END

你可能感兴趣的:(WY音乐播放器制作(2))