LiuShen revised this gist 3 months ago. Go to revision
1 file changed, 174 insertions, 1 deletion
1.readme.md
| @@ -1 +1,174 @@ | |||
| 1 | - | # 说明 | |
| 1 | + | ## 🎵 音乐胶囊模块使用说明 | |
| 2 | + | ||
| 3 | + | 本仓库提供了一个可集成到 Hexo 主题 **liushen** 的音乐胶囊播放器模块。模块包含四个主要部分: | |
| 4 | + | ||
| 5 | + | * **主题配置文件** | |
| 6 | + | * **布局模板文件** | |
| 7 | + | * **样式文件** | |
| 8 | + | * **前端脚本** | |
| 9 | + | ||
| 10 | + | 本文档将详细介绍它们的放置位置、引用方式和变量配置。 | |
| 11 | + | ||
| 12 | + | --- | |
| 13 | + | ||
| 14 | + | ### 1️⃣ 配置文件(根目录) | |
| 15 | + | ||
| 16 | + | **文件:** `_config.liushen.yml` | |
| 17 | + | **位置:** 项目根目录(`blog/_config.liushen.yml`),**不是主题根目录**。 | |
| 18 | + | ||
| 19 | + | 该文件用于存放音乐模块的相关配置(如是否启用、播放列表、API 接口等)。 | |
| 20 | + | 示例(按需调整): | |
| 21 | + | ||
| 22 | + | ```yaml | |
| 23 | + | # 页脚音乐胶囊 | |
| 24 | + | capsule: | |
| 25 | + | enable: true | |
| 26 | + | # 歌单 ID / 单曲 ID | |
| 27 | + | id: 13597135963 | |
| 28 | + | # 服务商:netease / qq / xiami / kugou / baidu | |
| 29 | + | server: netease | |
| 30 | + | # 类型:playlist / song | |
| 31 | + | type: playlist | |
| 32 | + | meting_api: https://met.example.com/api?server=:server&type=:type&id=:id&r=:r | |
| 33 | + | volume: 0.8 | |
| 34 | + | ``` | |
| 35 | + | ||
| 36 | + | --- | |
| 37 | + | ||
| 38 | + | ### 2️⃣ 布局模板文件 | |
| 39 | + | ||
| 40 | + | **文件:** `music.pug` | |
| 41 | + | **位置:** `blog/themes/liushen/layout/includes/third-party/music.pug` | |
| 42 | + | ||
| 43 | + | 该文件用于渲染音乐胶囊播放器 UI,需要在 `layout.pug` 中手动引入。 | |
| 44 | + | ||
| 45 | + | 在 `blog/themes/liushen/layout/includes/layout.pug` **底部** 添加以下代码(保留现有内容,仅在末尾追加): | |
| 46 | + | ||
| 47 | + | ```pug | |
| 48 | + | if theme.capsule && theme.capsule.enable | |
| 49 | + | include ./third-party/music.pug | |
| 50 | + | ``` | |
| 51 | + | ||
| 52 | + | > 📌 该判断会根据 `_config.liushen.yml` 中的 `capsule.enable` 来决定是否加载播放器。 | |
| 53 | + | ||
| 54 | + | --- | |
| 55 | + | ||
| 56 | + | ### 3️⃣ 样式文件 | |
| 57 | + | ||
| 58 | + | **文件:** `music-capsule.styl` | |
| 59 | + | **位置:** `blog/themes/liushen/source/css/__layout/music-capsule.styl` | |
| 60 | + | ||
| 61 | + | 该位置的`styl`样式表会被自动整合到`main.css` | |
| 62 | + | ||
| 63 | + | #### 💡 样式变量对照表 | |
| 64 | + | ||
| 65 | + | 音乐胶囊使用了一些 CSS 变量,这些变量在亮色与暗色模式下分别定义。 | |
| 66 | + | ||
| 67 | + | ##### 🌞 亮色模式(默认) | |
| 68 | + | ||
| 69 | + | ```css | |
| 70 | + | /* nav */ | |
| 71 | + | --liushen-nav-bg: rgba(255, 255, 255, 0.8); | |
| 72 | + | --liushen-nav-shadow: rgba(133, 133, 133, 0.6) 0px 5px 6px -5px; | |
| 73 | + | ||
| 74 | + | /* ai_summary */ | |
| 75 | + | --liushen-title-font-color: #0883b7; | |
| 76 | + | --liushen-maskbg: rgba(255, 255, 255, 0.85); | |
| 77 | + | --liushen-ai-bg: conic-gradient(from 1.5708rad at 50% 50%, #d6b300 0%, #42A2FF 54%, #d6b300 100%); | |
| 78 | + | ||
| 79 | + | /* card */ | |
| 80 | + | --liushen-card-bg: #fff; | |
| 81 | + | --liushen-card-secondbg: #f1f3f8; | |
| 82 | + | --liushen-card-border: 1px solid #e3e8f7; | |
| 83 | + | ||
| 84 | + | /* button */ | |
| 85 | + | --liushen-button-bg: #f1f3f8; | |
| 86 | + | --liushen-button-hover-bg: $theme-color; | |
| 87 | + | ||
| 88 | + | /* text */ | |
| 89 | + | --liushen-text: #4c4948; | |
| 90 | + | --liushen-secondtext: #3c3c43cc; | |
| 91 | + | ||
| 92 | + | /* snackbar */ | |
| 93 | + | --snackbar-bg: rgba(255, 255, 255, 0.809); | |
| 94 | + | --snackbar-text: #4c4948; | |
| 95 | + | --snackbar-border: 1px solid rgba(126, 126, 126, 0.527); | |
| 96 | + | ||
| 97 | + | /* menu child */ | |
| 98 | + | --menu-child-bg: rgba(255,255,255,0.8); | |
| 99 | + | ||
| 100 | + | /* fancybox */ | |
| 101 | + | --liushen-fancybox-bg: rgba(255,255,255,0.5); | |
| 102 | + | --liushen-fancybox-button-color: #000000; | |
| 103 | + | ``` | |
| 104 | + | ||
| 105 | + | ##### 🌙 暗色模式 | |
| 106 | + | ||
| 107 | + | ```css | |
| 108 | + | [data-theme='dark'] { | |
| 109 | + | /* nav */ | |
| 110 | + | --liushen-nav-bg: rgba(18,18,18,.8); | |
| 111 | + | --liushen-nav-shadow: rgba(133, 133, 133, 0) 0px 5px 6px -5px; | |
| 112 | + | ||
| 113 | + | /* ai_summary */ | |
| 114 | + | --liushen-maskbg: rgba(0, 0, 0, 0.85); | |
| 115 | + | --liushen-ai-bg: conic-gradient(from 1.5708rad at 50% 50%,rgba(214, 178, 0, 0.46) 0%,rgba(66, 161, 255, 0.53) 54%,rgba(214, 178, 0, 0.49) 100%); | |
| 116 | + | ||
| 117 | + | /* card */ | |
| 118 | + | --liushen-card-bg: #2d2d2d; | |
| 119 | + | --liushen-card-secondbg: #3e3f41; | |
| 120 | + | --liushen-card-border: 1px solid #42444a; | |
| 121 | + | ||
| 122 | + | /* button */ | |
| 123 | + | --liushen-button-bg: #30343f; | |
| 124 | + | --liushen-button-hover-bg: $theme-color; | |
| 125 | + | ||
| 126 | + | /* text */ | |
| 127 | + | --liushen-text: #ffffffb3; | |
| 128 | + | --liushen-secondtext: #a1a2b8; | |
| 129 | + | ||
| 130 | + | /* snackbar */ | |
| 131 | + | --snackbar-bg: rgba(48, 48, 48, 0.809); | |
| 132 | + | --snackbar-text: #dfdfdf; | |
| 133 | + | --snackbar-border: 1px solid #cfd4dc40; | |
| 134 | + | ||
| 135 | + | /* menu child */ | |
| 136 | + | --menu-child-bg: rgba(18,18,18,0.8); | |
| 137 | + | ||
| 138 | + | /* fancybox */ | |
| 139 | + | --liushen-fancybox-bg: rgba(0,0,0,0.5); | |
| 140 | + | --liushen-fancybox-button-color: #ffffff; | |
| 141 | + | } | |
| 142 | + | ``` | |
| 143 | + | ||
| 144 | + | > 你可以将这些变量整合到主题的全局变量文件中,或根据配色需求自行调整。 | |
| 145 | + | ||
| 146 | + | --- | |
| 147 | + | ||
| 148 | + | ### 4️⃣ 前端脚本 | |
| 149 | + | ||
| 150 | + | **文件:** `music.js` | |
| 151 | + | **位置:** 可放在主题的任意 JS 文件中(例如 `blog/themes/liushen/source/js/music.js`)或合并到 `main.js` 中。 | |
| 152 | + | ||
| 153 | + | ### 引入方式一(单独文件) | |
| 154 | + | ||
| 155 | + | 在主题 `layout.pug` 的底部或 `additional-js.pug` 中添加: | |
| 156 | + | ||
| 157 | + | ```pug | |
| 158 | + | script(src='/js/music.js') | |
| 159 | + | ``` | |
| 160 | + | ||
| 161 | + | #### 引入方式二(合并代码) | |
| 162 | + | ||
| 163 | + | 将 `music.js` 中的代码直接复制到 `main.js` 或其他已加载的脚本文件中。 | |
| 164 | + | ||
| 165 | + | --- | |
| 166 | + | ||
| 167 | + | ### 🔗 集成流程总结 | |
| 168 | + | ||
| 169 | + | 1. 将 `_config.liushen.yml` 添加到 **项目根目录** 并配置 `capsule.enable: true`。 | |
| 170 | + | 2. 将 `music.pug` 放入 `blog/themes/liushen/layout/includes/third-party/`。 | |
| 171 | + | 3. 编辑 `layout.pug`,在底部添加 `include ./third-party/music.pug`(带条件判断)。 | |
| 172 | + | 4. 将 `music-capsule.styl` 放入 `blog/themes/liushen/source/css/__layout/`。 | |
| 173 | + | 5. 将 `music.js` 放入 JS 目录并在页面加载时引入,或者可以添加到任意js文件中。 | |
| 174 | + | 6. 根据需要修改 CSS 变量配色。 | |
LiuShen revised this gist 3 months ago. Go to revision
4 files changed, 273 insertions
1.readme.md(file created)
| @@ -0,0 +1 @@ | |||
| 1 | + | # 说明 | |
music-capsule.styl(file created)
| @@ -0,0 +1,230 @@ | |||
| 1 | + | @keyframes changeright | |
| 2 | + | 0%, 50%, 100% | |
| 3 | + | transform: rotate(0deg) scale(1.1) | |
| 4 | + | box-shadow: 0 0 2px #ffffff00 | |
| 5 | + | 25%, 75% | |
| 6 | + | transform: rotate(90deg) scale(1.1) | |
| 7 | + | box-shadow: 0 0 14px #ffffff | |
| 8 | + | ||
| 9 | + | @keyframes playingShadow | |
| 10 | + | 0%, 100% | |
| 11 | + | box-shadow: 0 0px 12px -3px #00000000 | |
| 12 | + | 50% | |
| 13 | + | box-shadow: 0 0px 12px 0px var(--default-bg-color) | |
| 14 | + | ||
| 15 | + | @keyframes lightBar | |
| 16 | + | 0%, 100% | |
| 17 | + | opacity: 0.1 | |
| 18 | + | 60% | |
| 19 | + | opacity: 0.3 | |
| 20 | + | ||
| 21 | + | .aplayer.aplayer-narrow | |
| 22 | + | .aplayer-body, | |
| 23 | + | .aplayer-pic | |
| 24 | + | height: 66px | |
| 25 | + | width: 66px | |
| 26 | + | ||
| 27 | + | #nav-music | |
| 28 | + | display: flex | |
| 29 | + | align-items: center | |
| 30 | + | position: fixed | |
| 31 | + | z-index: 10000 | |
| 32 | + | bottom: 10px | |
| 33 | + | left: 10px | |
| 34 | + | cursor: pointer | |
| 35 | + | transition: all 0.5s, left 0s | |
| 36 | + | transform-origin: left bottom | |
| 37 | + | box-shadow: var(--liushen-nav-shadow) | |
| 38 | + | border-radius: 40px | |
| 39 | + | overflow: hidden | |
| 40 | + | ||
| 41 | + | &:active | |
| 42 | + | transform: scale(0.97) | |
| 43 | + | ||
| 44 | + | &.playing | |
| 45 | + | border: var(--liushen-card-border) | |
| 46 | + | box-shadow: 0 0px 12px -3px #00000000 | |
| 47 | + | animation: playingShadow 5s linear infinite | |
| 48 | + | ||
| 49 | + | .aplayer.aplayer-withlrc | |
| 50 | + | .aplayer-pic | |
| 51 | + | box-shadow: 0 0 14px #ffffffa6 | |
| 52 | + | transform: rotate(0deg) scale(1.1) | |
| 53 | + | border-color: white | |
| 54 | + | animation-play-state: running | |
| 55 | + | ||
| 56 | + | .aplayer-info | |
| 57 | + | color: white | |
| 58 | + | ||
| 59 | + | #nav-music-hoverTips | |
| 60 | + | width: 0 | |
| 61 | + | ||
| 62 | + | .aplayer | |
| 63 | + | background: var(--default-bg-color) | |
| 64 | + | border: var(--liushen-card-border) | |
| 65 | + | backdrop-filter: saturate(180%) blur(20px) | |
| 66 | + | transform: translateZ(0) | |
| 67 | + | ||
| 68 | + | .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played | |
| 69 | + | animation-play-state: running | |
| 70 | + | ||
| 71 | + | &:hover:not(.playing) #nav-music-hoverTips | |
| 72 | + | opacity: 1 | |
| 73 | + | ||
| 74 | + | .aplayer.aplayer-withlrc | |
| 75 | + | .aplayer-pic | |
| 76 | + | height: 25px | |
| 77 | + | width: 25px | |
| 78 | + | border-radius: 40px | |
| 79 | + | z-index: 1 | |
| 80 | + | transition: 0.3s | |
| 81 | + | transform: rotate(0deg) scale(1) | |
| 82 | + | border: var(--liushen-card-border) | |
| 83 | + | animation: changeright 24s linear infinite | |
| 84 | + | animation-play-state: paused | |
| 85 | + | ||
| 86 | + | .aplayer-info | |
| 87 | + | height: 100% | |
| 88 | + | color: var(--liushen-text) | |
| 89 | + | margin: 0 | |
| 90 | + | padding: 0 | |
| 91 | + | display: flex | |
| 92 | + | align-items: center | |
| 93 | + | ||
| 94 | + | #nav-music-hoverTips | |
| 95 | + | color: white | |
| 96 | + | background: var(--default-bg-color) | |
| 97 | + | width: 100% | |
| 98 | + | height: 100% | |
| 99 | + | position: absolute | |
| 100 | + | top: 0 | |
| 101 | + | left: 0 | |
| 102 | + | align-items: center | |
| 103 | + | justify-content: center | |
| 104 | + | display: flex | |
| 105 | + | border-radius: 40px | |
| 106 | + | opacity: 0 | |
| 107 | + | font-size: 12px | |
| 108 | + | z-index: 2 | |
| 109 | + | transition: 0.3s | |
| 110 | + | ||
| 111 | + | .aplayer | |
| 112 | + | background: var(--liushen-card-bg) | |
| 113 | + | border-radius: 60px | |
| 114 | + | height: 41px | |
| 115 | + | display: flex | |
| 116 | + | margin: 0 | |
| 117 | + | transition: 0.3s | |
| 118 | + | border: var(--liushen-card-border) | |
| 119 | + | box-shadow: none | |
| 120 | + | ||
| 121 | + | .aplayer-notice, | |
| 122 | + | .aplayer-miniswitcher, | |
| 123 | + | .aplayer-list | |
| 124 | + | display: none | |
| 125 | + | ||
| 126 | + | .aplayer-body | |
| 127 | + | position: relative | |
| 128 | + | display: flex | |
| 129 | + | align-items: center | |
| 130 | + | min-width: 180px | |
| 131 | + | ||
| 132 | + | .aplayer-info | |
| 133 | + | .aplayer-music | |
| 134 | + | margin: 0 | |
| 135 | + | display: flex | |
| 136 | + | align-items: center | |
| 137 | + | padding: 0 12px 0 8px | |
| 138 | + | cursor: pointer | |
| 139 | + | z-index: 1 | |
| 140 | + | height: 100% | |
| 141 | + | ||
| 142 | + | .aplayer-title | |
| 143 | + | cursor: pointer | |
| 144 | + | line-height: 1 | |
| 145 | + | display: inline-block | |
| 146 | + | white-space: nowrap | |
| 147 | + | max-width: 120px | |
| 148 | + | overflow: hidden | |
| 149 | + | text-overflow: ellipsis | |
| 150 | + | transition: 0.3s | |
| 151 | + | user-select: none | |
| 152 | + | ||
| 153 | + | .aplayer-controller | |
| 154 | + | position: absolute | |
| 155 | + | width: 100% | |
| 156 | + | height: 100% | |
| 157 | + | top: 0 | |
| 158 | + | left: 0 | |
| 159 | + | ||
| 160 | + | .aplayer-bar-wrap | |
| 161 | + | margin: 0 | |
| 162 | + | padding: 0 | |
| 163 | + | ||
| 164 | + | .aplayer-bar | |
| 165 | + | height: 100% | |
| 166 | + | background: 0 0 | |
| 167 | + | ||
| 168 | + | .aplayer-loaded | |
| 169 | + | display: none | |
| 170 | + | ||
| 171 | + | .aplayer-played | |
| 172 | + | height: 100% | |
| 173 | + | opacity: 0.1 | |
| 174 | + | background-color: white !important | |
| 175 | + | animation: lightBar 5s ease infinite | |
| 176 | + | animation-play-state: paused | |
| 177 | + | ||
| 178 | + | .aplayer-pic | |
| 179 | + | pointer-events: none | |
| 180 | + | ||
| 181 | + | .aplayer-button | |
| 182 | + | bottom: 50% | |
| 183 | + | right: 50% | |
| 184 | + | transform: translate(50%, 50%) | |
| 185 | + | margin: 0 | |
| 186 | + | transition: 0.3s | |
| 187 | + | pointer-events all | |
| 188 | + | ||
| 189 | + | &:has(.aplayer-button.aplayer-play) | |
| 190 | + | animation-play-state: paused | |
| 191 | + | transform: rotate(0deg) scale(1) !important | |
| 192 | + | ||
| 193 | + | margin-left: 8px | |
| 194 | + | ||
| 195 | + | .aplayer-info .aplayer-controller .aplayer-time, | |
| 196 | + | .aplayer-info .aplayer-music .aplayer-author | |
| 197 | + | display: none | |
| 198 | + | ||
| 199 | + | &.aplayer-withlist .aplayer-info | |
| 200 | + | border: none | |
| 201 | + | ||
| 202 | + | .aplayer-lrc | |
| 203 | + | width: 0 | |
| 204 | + | opacity: 0 | |
| 205 | + | transition: 0.3s | |
| 206 | + | margin-bottom: -26px | |
| 207 | + | ||
| 208 | + | p.aplayer-lrc-current | |
| 209 | + | color: white | |
| 210 | + | border: none | |
| 211 | + | min-height: 20px | |
| 212 | + | filter: none | |
| 213 | + | ||
| 214 | + | &:after, | |
| 215 | + | &:before | |
| 216 | + | display: none | |
| 217 | + | ||
| 218 | + | p | |
| 219 | + | color: #ffffffb3 | |
| 220 | + | filter: blur(.8px) | |
| 221 | + | ||
| 222 | + | @media screen and (min-width: 600px) | |
| 223 | + | #nav-music.stretch .aplayer.aplayer-withlrc .aplayer-lrc | |
| 224 | + | width: 200px | |
| 225 | + | margin-left: 8px | |
| 226 | + | opacity: 1 | |
| 227 | + | ||
| 228 | + | .aplayer-thumb | |
| 229 | + | width: 0 !important | |
| 230 | + | height: 0 !important | |
music.js(file created)
| @@ -0,0 +1,39 @@ | |||
| 1 | + | const liuMusic = { | |
| 2 | + | musicPlaying: false, | |
| 3 | + | isMusicBind: false, | |
| 4 | + | ||
| 5 | + | musicToggle(isMeting = true) { | |
| 6 | + | if (!this.isMusicBind) { | |
| 7 | + | this.musicBind(); | |
| 8 | + | } | |
| 9 | + | ||
| 10 | + | const $music = document.querySelector("#nav-music"); | |
| 11 | + | const $meting = document.querySelector("meting-js"); | |
| 12 | + | const $console = document.getElementById("consoleMusic"); | |
| 13 | + | ||
| 14 | + | this.musicPlaying = !this.musicPlaying; | |
| 15 | + | $music?.classList.toggle("playing", this.musicPlaying); | |
| 16 | + | $music?.classList.toggle("stretch", this.musicPlaying); | |
| 17 | + | $console?.classList.toggle("on", this.musicPlaying); | |
| 18 | + | ||
| 19 | + | if (isMeting) { | |
| 20 | + | this.musicPlaying ? $meting?.aplayer?.play() : $meting?.aplayer?.pause(); | |
| 21 | + | } | |
| 22 | + | }, | |
| 23 | + | ||
| 24 | + | musicBind() { | |
| 25 | + | const $music = document.querySelector("#nav-music"); | |
| 26 | + | const $name = document.querySelector("#nav-music .aplayer-music"); | |
| 27 | + | const $button = document.querySelector("#nav-music .aplayer-button"); | |
| 28 | + | ||
| 29 | + | $name?.addEventListener("click", () => { | |
| 30 | + | $music?.classList.toggle("stretch"); | |
| 31 | + | }); | |
| 32 | + | ||
| 33 | + | $button?.addEventListener("click", () => { | |
| 34 | + | this.musicToggle(false); | |
| 35 | + | }); | |
| 36 | + | ||
| 37 | + | this.isMusicBind = true; | |
| 38 | + | } | |
| 39 | + | }; | |
music.pug(file created)
| @@ -0,0 +1,3 @@ | |||
| 1 | + | div.needEndHide#nav-music | |
| 2 | + | #nav-music-hoverTips(onclick='liuMusic.musicToggle()')= __('music.hit') | |
| 3 | + | meting-js(id=theme.capsule.id server=theme.capsule.server type=theme.capsule.type mutex="true" preload="none" data-lrctype="0" order="random" volume=theme.capsule.volume api=theme.capsule.meting_api) | |
LiuShen revised this gist 3 months ago. Go to revision
1 file changed, 11 insertions
_comfig.liushen.yml(file created)
| @@ -0,0 +1,11 @@ | |||
| 1 | + | # 页脚音乐胶囊 | |
| 2 | + | capsule: | |
| 3 | + | enable: true | |
| 4 | + | # 歌单 ID / 单曲 ID | |
| 5 | + | id: 13597135963 | |
| 6 | + | # 服务商:netease / qq / xiami / kugou / baidu | |
| 7 | + | server: netease | |
| 8 | + | # 类型:playlist / song | |
| 9 | + | type: playlist | |
| 10 | + | meting_api: https://met.example.com/api?server=:server&type=:type&id=:id&r=:r | |
| 11 | + | volume: 0.8 | |