很久之前就想把整个音乐界面好好写一写,不过一直迫于咕咕咕的属性没有去做这件事,以至于悔之不及,没有早点做,对我这种重度音乐控来说真的是太爽了,很快啊,马上就听了一下午。

前两天看到 叶子 重做了音乐界面于是马上就搞过来了啊,很快啊哈哈哈哈哈,谢谢大叶子的投喂!

博主思路和叶子有所不同,每个人都有每个人的实现方法,本文仅做分享博主自己的实现思路。

在线体验

一个优雅的音乐界面

效果图

整体效果我还是非常满意的hhh

移动端

魔改步骤

博主使用的meting2的版本,修改主题配置文件 _config.butterfly.yml 最下面 CDN.option.meting_js,有能力的建议自己下载下来并传到自己的oss或直接使用本地路径引用。

meting_js: https://npm.elemecdn.com/hexo-anzhiyu-music@1.0.1/assets/js/Meting2.min.js

创建页面, 新建 source/music/index.md 文件

---
title: 音乐馆
date: 2021-04-24 21:41:30
type: music
aplayer: true
top_img: false
comments: false
aside: false
---

创建页面,新建themes/butterfly/layout/includes/page/music.pug,并方便后续可以使用css将页面(page)本身的样式给去除。此处可以自行修改server歌单id,我的id是8152976493,歌单id是对应的服务商的歌单页面路径最后面的那个数字。

music.pug

#anMusic-page
  meting-js(id="8152976493" server="netease" type="playlist" mutex="true" preload="auto" theme="var(--anzhiyu-main)" order="list")

修改themes/butterfly/layout/page.pug

  #page
-   if top_img === false
+   if top_img === false && page.type != 'music'
      h1.page-title= page.title
    case page.type
      when 'link'
        include includes/page/flink.pug
      ...
+     when 'music'
+       include includes/page/music.pug
      default
        include includes/page/default-page.pug

创建背景元素,修改themes/butterfly/layout/includes/layout.pug

  body
    if theme.background
      #web_bg
+     #an_music_bg

js部分

css部分和js部分不会引用的同学可以去看 https://www.bilibili.com/video/BV1rT411w7gj/?spm_id_from=333.999.0.0

# 自定义js
- <script async data-pjax src="/js/anzhiyu.js"></script>

anzhiyu.js,其中有一部分代码是暂停nav的音乐的,需要的同学可以打开注释自己实现一下musicToggle方法。

var anzhiyu = {
  // 音乐节目切换背景
  changeMusicBg: function (isChangeBg = true) {
    if (window.location.pathname != "/music/") {
      return;
    }
    const anMusicBg = document.getElementById("an_music_bg")

    if (isChangeBg) {
      // player listswitch 会进入此处
      const musiccover = document.querySelector("#anMusic-page .aplayer-pic");
      anMusicBg.style.backgroundImage = musiccover.style.backgroundImage;
    } else {
      // 第一次进入,绑定事件,改背景
      let timer = setInterval(()=>{
        const musiccover = document.querySelector("#anMusic-page .aplayer-pic");
        // 确保player加载完成
        console.info(anMusicBg);
        if (musiccover) {
          clearInterval(timer)
          anMusicBg.style.backgroundImage = musiccover.style.backgroundImage;
          // 绑定事件
          anzhiyu.addEventListenerChangeMusicBg();
          
          // 暂停nav的音乐
          if (document.querySelector("#nav-music meting-js").aplayer && !document.querySelector("#nav-music meting-js").aplayer.audio.paused){
            anzhiyu.musicToggle()
          }
        }
      }, 100)
    }
  },
  addEventListenerChangeMusicBg: function () {
    const anMusicPage = document.getElementById("anMusic-page");
    const aplayerIconMenu = anMusicPage.querySelector(".aplayer-info .aplayer-time .aplayer-icon-menu");

    anMusicPage.querySelector("meting-js").aplayer.on('loadeddata', function () {
      anzhiyu.changeMusicBg();
      console.info('player loadeddata');
    });

    aplayerIconMenu.addEventListener("click", function () {
      document.getElementById('menu-mask').style.display = "block";
      document.getElementById('menu-mask').style.animation = "0.5s ease 0s 1 normal none running to_show";
    })

    document.getElementById('menu-mask').addEventListener("click", function () {
      if (window.location.pathname != "/music/") return;
      anMusicPage.querySelector('.aplayer-list').classList.remove("aplayer-list-hide");
    })
  },
}

// 调用
anzhiyu.changeMusicBg(false);

css

css部分, 自行建立css能成功引入即可

music.css

#page:has(#anMusic-page) {
  border: 0;
  box-shadow: none !important;
  padding: 0 !important;
  background: transparent !important;
}
#an_music_bg {
  display: none;
  filter: blur(63px);
  opacity: 0.6;
  position: fixed;
  z-index: -999;
  background-attachment: local;
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
  width: 200%;
  height: 200%;
  top: -50%;
  left: -50%;
  transform: rotate(0deg);
}
body:has(#anMusic-page) #an_music_bg {
  display: block;
}

body:has(#anMusic-page) {
  background: rgb(13, 13, 13);
}

#anMusic-page meting-js .aplayer {
  display: flex;
  flex-direction: row-reverse;
  background: rgba(0, 0, 0, 0);
  border: none;
  box-shadow: none;
}

body:has(#anMusic-page) #web_bg {
  display: none;
}
body:has(#anMusic-page) #footer,
body:has(#anMusic-page) #nav-music {
  display: none;
}

#anMusic-page .aplayer-body {
  width: 40%;
  height: 75vh;
}

#anMusic-page ol > li:hover {
  background: #ffffff33;
  border-radius: 6px;
}
#anMusic-page .aplayer-pic {
  float: none;
  width: 180px;
  height: 180px;
  border-radius: 12px;
  margin: auto;
  left: 0;
  right: 0;
}

#anMusic-page .aplayer-info {
  margin: 0 20px 0 20px;
  border-bottom: none;
}

#anMusic-page .aplayer-info .aplayer-music {
  text-align: center;
  height: auto;
  margin: 15px;
}

#anMusic-page .aplayer-info .aplayer-music .aplayer-author,
#anMusic-page .aplayer-info .aplayer-music .aplayer-title {
  font-size: 2rem;
  font-weight: 700;
  color: #fff;
}

#anMusic-page .aplayer-info .aplayer-lrc {
  height: 800%;
  margin-top: 80px;
  mask-image: linear-gradient(to bottom, #000, #000, #000, #000, #000, #000, #000, #000, #000, #000, #0000, #0000);
}
#anMusic-page .aplayer-info .aplayer-lrc p {
  font-size: 14px;
  color: #fff;
}
#anMusic-page .aplayer .aplayer-lrc:after,
#anMusic-page .aplayer .aplayer-lrc:before {
  display: none;
}

/* 控制器 */
#anMusic-page .aplayer-info .aplayer-controller {
  position: fixed;
  max-width: 1500px;
  margin: auto;
  left: 0;
  right: 0;
  bottom: 50px;
}
#anMusic-page .aplayer-info .aplayer-controller .aplayer-bar-wrap {
  margin: 0 160px 0 150px;
}
#anMusic-page .aplayer-info .aplayer-controller .aplayer-played {
  background: var(--anzhiyu-white) !important;
}
#anMusic-page .aplayer-info .aplayer-controller .aplayer-thumb {
  -webkit-transform: none;
  transform: none;
  background: #fff !important;
}
#anMusic-page .aplayer-info .aplayer-time .aplayer-icon-back,
#anMusic-page .aplayer-info .aplayer-time .aplayer-icon-forward,
#anMusic-page .aplayer-info .aplayer-time .aplayer-icon-play {
  display: inline;
  position: fixed;
}
#anMusic-page .aplayer-info .aplayer-time {
  position: absolute;
  width: 100%;
  bottom: 21px;
  height: 0;
  display: flex;
  justify-content: flex-end;
}
#anMusic-page .aplayer-info .aplayer-time .aplayer-time-inner {
  margin-right: 18px;
  margin-top: -8px;
}
#anMusic-page .aplayer-info .aplayer-time .aplayer-icon-back {
  position: absolute;
  left: 0;
}
#anMusic-page .aplayer-info .aplayer-time .aplayer-icon-play {
  position: absolute;
  left: 40px;
}
#anMusic-page .aplayer-info .aplayer-time .aplayer-icon-forward {
  position: absolute;
  left: 80px;
}

#anMusic-page .aplayer-info .aplayer-time .aplayer-icon {
  width: 2rem;
  height: 2rem;
  margin-left: 15px;
}

#anMusic-page .aplayer-info .aplayer-time .aplayer-icon-menu {
  display: none;
}

#anMusic-page .aplayer-info .aplayer-time .aplayer-icon path {
  fill: var(--anzhiyu-white);
  opacity: 0.8;
}

#anMusic-page .aplayer-list {
  width: 60%;
  max-height: none !important;
  height: 100%;
}
#anMusic-page ol {
  max-height: 75vh !important;
  padding-right: 25px;
}
#anMusic-page ol > li {
  border-top: 1px solid transparent;
  font-size: 14px;
}
#anMusic-page ol > li.aplayer-list-light {
  background: rgb(255 255 255 / 20%);
  border-radius: 6px;
}

#anMusic-page ol > li span {
  color: var(--anzhiyu-white);
}

#anMusic-page ol > li.aplayer-list-light .aplayer-list-cur {
  display: none;
}
#anMusic-page ol > li span.aplayer-list-author {
  opacity: 0.6;
}

/* 导航栏 */
.page:has(#anMusic-page) #nav {
  backdrop-filter: none !important;
  background: 0 0 !important;
  border-bottom: none !important;
}

.page:has(#anMusic-page) #page-header.not-top-img #nav a,
.page:has(#anMusic-page) #page-header #nav .back-home-button {
  color: var(--anzhiyu-white);
}

body:has(#anMusic-page) .s-sticker div {
  color: var(--anzhiyu-white) !important;
}

body:has(#anMusic-page) .aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon.aplayer-icon-loop {
  margin-right: 15px;
}

[data-theme="dark"] .page:has(#anMusic-page) #page-header:before {
  background-color: transparent;
}

/* **** 移动端样式 ***** */
@media screen and (max-width: 768px) {
  body:has(#anMusic-page) #rightside {
    display: none;
  }
  body:has(#anMusic-page) #content-inner,
  body:has(#anMusic-page) #page {
    z-index: auto;
  }
  /* 歌曲列表 */
  #anMusic-page .aplayer-list {
    position: fixed;
    z-index: 1002;
    width: 100%;
    bottom: -76%;
    left: 0;
    background: var(--sidebar-bg);
    height: auto;
    border-radius: 15px 15px 0px 0px;
    padding: 15px 0px;
  }
  #anMusic-page .aplayer-list.aplayer-list-hide {
    bottom: 0% !important;
  }
  #anMusic-page ol {
    max-height: 60vh !important;
    padding-right: 0px;
  }
  #anMusic-page ol > li {
    display: flex;
    margin: 0 10px;
  }
  #anMusic-page ol > li span {
    color: var(--font-color);
  }
  #anMusic-page ol > li span.aplayer-list-title {
    width: 30%;
  }
  #anMusic-page ol > li.aplayer-list-light {
    background: #33a673;
    padding: 5px 20px;
    border-radius: 10px;
  }
  #anMusic-page ol > li.aplayer-list-light span {
    color: #fff;
  }
  #anMusic-page ol > li span.aplayer-list-title {
    max-width: 55%;
    width: auto;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    overflow: hidden;
    -webkit-box-orient: vertical;
  }
  #anMusic-page ol > li span.aplayer-list-author {
    position: absolute;
    right: 10px;
    width: auto;
    max-width: 35%;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    overflow: hidden;
    -webkit-box-orient: vertical;
  }
  #anMusic-page ol > li.aplayer-list-light span.aplayer-list-author {
    right: 15px;
  }
  /* 歌词信息 */
  #anMusic-page .aplayer-body {
    width: 100%;

    position: fixed;
    margin: auto;
    left: 0;
    right: 0;
    top: 100px;
  }
  #anMusic-page .aplayer-info .aplayer-lrc {
    margin-top: 40px;
    height: auto;
    max-height: 200%;
    min-height: 100%;
    mask-image: linear-gradient(to bottom, #000, #000, #000, #000, #0000, #0000);
  }
  #anMusic-page .aplayer-info .aplayer-lrc p.aplayer-lrc-current {
    color: #33a673;
  }
  /* 控制按键和进度条 */
  #anMusic-page .aplayer-info .aplayer-controller {
    width: 100%;
    bottom: 100px;
  }
  #anMusic-page .aplayer-info .aplayer-controller .aplayer-bar-wrap {
    margin: 0 30px;
  }
  #anMusic-page .aplayer-info .aplayer-time {
    bottom: -40px;
  }
  #anMusic-page .aplayer-info .aplayer-time .aplayer-time-inner {
    position: absolute;
    width: 100%;
    margin-right: 0;
    margin-top: -33px;
  }
  #anMusic-page .aplayer-info .aplayer-time .aplayer-time-inner .aplayer-dtime {
    position: absolute;
    right: 30px;
  }
  #anMusic-page .aplayer-info .aplayer-time .aplayer-time-inner .aplayer-ptime {
    position: absolute;
    left: 35px;
  }
  #anMusic-page .aplayer-info .aplayer-time .aplayer-icon-back {
    margin: auto;
    right: 110px;
  }
  #anMusic-page .aplayer-info .aplayer-time .aplayer-icon-play {
    margin: auto;
    right: 0;
    left: 0;
  }
  #anMusic-page .aplayer-info .aplayer-time .aplayer-icon-forward {
    margin: auto;
    left: 110px;
    right: 0;
  }
  #anMusic-page .aplayer-info .aplayer-time .aplayer-icon-order {
    position: absolute;
    left: 22px;
  }
  #anMusic-page .aplayer-info .aplayer-time .aplayer-icon-loop {
    position: absolute;
    right: 25px;
  }
  #anMusic-page .aplayer-info .aplayer-time .aplayer-icon-menu {
    display: inline;
    position: absolute;
    right: 25px;
    top: -90px;
  }
  #anMusic-page .aplayer-volume-bar-wrap {
    bottom: 0px;
    right: 7px;
  }
  #anMusic-page .aplayer .aplayer-info .aplayer-controller .aplayer-volume-wrap {
    left: -66px;
  }
}