前言

起因是觉得原有的全局吸底播放器放在左侧,一图流背景下有点碍眼,就想到把它放到右边菜单栏,跟着菜单栏一起移动。

效果预览
  • 适配了暗黑模式,并修改了毛玻璃效果。

教程

基础配置

  1. 首先安装 Aplayer 插件,输入以下命令安装:
    1
    npm install --save hexo-tag-aplayer
  2. 在配置文件 [Blogroot]\_config.yml 或主题配置文件 [Blogroot]\_config.butterfly.yml 中添加以下配置项:
    1
    2
    3
    aplayer:
    meting: true
    asset_inject: false
  3. 在主题配置文件 [Blogroot]\_config.butterfly.yml 中开启 aplayerInject 配置项:
    1
    2
    3
    aplayerInject:
    enable: true
    per_page: true
  4. 在主题配置文件 [Blogroot]\_config.butterfly.ymlinject 配置项中添加以下内容:
    1
    2
    3
    4
    5
    6
    inject:
    head:
    # - <link rel="stylesheet" href="/xxx.css">
    bottom:
    # - <script src="xxxx"></script>
    - <div class="aplayer rightside-aplayer no-destroy" id="aplayer" data-id="8429082619" data-server="tencent" data-type="playlist" data-fixed="true" data-autoplay="false" data-lrcType="-1"> </div>
    参数说明
    OptionDefaultDescription
    idrequiredsong id / playlist id / album id / search keyword
    serverrequiredMusic platform: netease, tencent, kugou, xiami, baidu
    typerequiredsong, playlist, album, search, artist
    fixedfalseEnable fixed mode
    minifalseEnable mini mode
    loopallPlayer loop play, values: ‘all’, ‘one’, ‘none’
    orderlistPlayer play order, values: ‘list’, ‘random’
    volume0.7Default volume, notice that player will remember user setting, default volume will not work after user set volume themselves
    lrctype0Lyric type
    listfoldedfalseIndicate whether list should folded at first
    autoplayfalseAutoplay song(s), not supported by mobile browsers
    mutextruePause other players when this player playing
    listmaxheight340pxMax height of play list
    preloadautoThe way to load music, can be none, metadata, auto
    storagenamemetingjsLocalStorage key that store player setting
    theme#ad7a86Theme color

魔改步骤

  1. [Blogroot]\themes\butterfly\source\css\custom\ 目录下新建 rightside_aplayer.css 文件:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    #aplayer.rightside-aplayer {
    bottom: -38px;
    border-radius: 0.75rem;
    /* right: -48px; */
    width: 38px;
    height: 38px;
    opacity: 0;
    visibility: hidden;
    /* 关键:确保 transition 包含 opacity 和 transform (或 right) */
    transition: all 0.5s ease-in-out;
    transform: translateX(100%);
    }

    #aplayer.rightside-aplayer.aplayer-active {
    right: 20px;
    opacity: 1;
    visibility: visible;
    transform: translateX(0);

    }


    #aplayer.rightside-aplayer .aplayer-pic {
    width: 38px !important;
    height: 38px !important;
    border-radius: 0.75rem;
    }

    #aplayer.rightside-aplayer .aplayer-body {
    margin-top: 100px;
    /* left: calc(100% - 48px) !important;
    right: 11px; */
    width: 38px !important;
    height: 38px;
    /* bottom: 49px; */
    padding-right: 0px;
    border-radius: 0.75rem;
    /* animation: slideInFromLeft 1s ease forwards; */
    }

    #aplayer.rightside-aplayer.aplayer-fixed {
    left: revert;
    right: 10px;
    bottom: 49px;
    position: fixed;
    }

    #aplayer.rightside-aplayer .aplayer-info {
    position: absolute;
    right: 44px;
    width: 0;
    padding: 0 6px 0 5px;
    width: 0;
    opacity: 0;
    overflow: hidden;
    transition: width 0.3s ease, opacity 0.3s ease; /* 宽度动画 */
    height: 38px;
    border-radius: 0.75rem;
    /* 背景颜色 */
    background: rgba(255, 255, 255, 0.3);
    backdrop-filter: blur(19px) saturate(170%);
    -webkit-backdrop-filter: blur(19px) saturate(170%);
    border: 1px solid rgba(255, 255, 255, 0.3);
    box-shadow:
    0 4px 30px rgba(0, 0, 0, 0.1),
    0 10px 20px rgba(0, 0, 0, 0.1);
    }

    #aplayer.rightside-aplayer .aplayer-info.aplayer-info-show{
    width: 400px; /* 设置你想要的展开宽度 */
    opacity: 1;
    }

    [data-theme="dark"] #aplayer.rightside-aplayer .aplayer-info {
    background: rgba(18, 18, 18, 0.15) !important;
    }

    [data-theme="dark"] #aplayer.rightside-aplayer .aplayer-info .aplayer-music {
    color: rgba(255, 255, 255, 0.7);
    }

    [data-theme="dark"] #aplayer.rightside-aplayer .aplayer-info .aplayer-title {
    color: rgba(255, 255, 255, 0.7);
    }

    [data-theme="dark"] #aplayer.rightside-aplayer .aplayer-info .aplayer-music .aplayer-author {
    color: rgba(255, 255, 255, 0.7);
    }

    #aplayer.rightside-aplayer .aplayer-icon-play {
    bottom: 20px;
    width: 20px;
    height: 16px;
    left: 30.5px;
    }

    #aplayer.rightside-aplayer .aplayer-icon-play svg{
    margin: 2px 0 0 0;
    }

    [data-theme="dark"] #aplayer.rightside-aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon path {
    fill: rgba(255, 255, 255, 0.7);
    }

    #aplayer.rightside-aplayer .aplayer-icon-back {
    bottom: 20px;
    width: 20px;
    height: 16px;
    left: 6px;
    }

    #aplayer.rightside-aplayer .aplayer-icon-back svg{
    margin-top: 2px;
    }

    #aplayer.rightside-aplayer .aplayer-icon-forward {
    bottom: 20px;
    width: 20px;
    height: 16px;
    left: 55px;
    }

    #aplayer.rightside-aplayer .aplayer-icon-forward svg{
    margin-top: -2px;
    }

    #aplayer.rightside-aplayer .aplayer-icon-menu {
    bottom: 20px;
    width: 15px;
    height: 16px;
    }

    #aplayer.rightside-aplayer .aplayer-miniswitcher {
    right: 25px;
    width: 13px;
    border-radius: 8px 0 0 8px;
    border: none;
    background: transparent;
    }

    #aplayer.rightside-aplayer .aplayer-miniswitcher .aplayer-icon svg path{
    fill: #fff;
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.5), 0 2px 2px rgba(0, 0, 0, 0.5);
    }

    #aplayer.rightside-aplayer .aplayer-info .aplayer-music {
    height: 16px;
    margin: 3px 0 0 3px;
    }

    #aplayer.rightside-aplayer .aplayer-info .aplayer-music .aplayer-title {
    font-size: 10px;
    }



    #aplayer.rightside-aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap {
    padding: 5px 0;
    margin-left: 3px;
    }
    #aplayer.rightside-aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played {
    background: rgba(245, 166, 185, 0.7)!important;
    }

    #aplayer.rightside-aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played .aplayer-thumb{
    background: rgba(245, 166, 185, 0.85)!important;
    }
    #aplayer.rightside-aplayer .aplayer-info .aplayer-controller .aplayer-time {
    bottom: 1px;
    }

    #aplayer.rightside-aplayer .aplayer-list {
    position: fixed;
    right: 44px;
    margin-bottom: 102px;
    bottom: -75px;
    border: none;
    border-radius: 0.75rem 0.75rem 0 0;
    width: 0;
    opacity: 0;
    padding-bottom: 7px;
    visibility: visible;
    overflow: hidden;
    transition: width 0.3s ease, opacity 0.3s ease; /* 宽度动画 */
    display: block !important;
    overflow: hidden;
    /* 背景颜色 */
    background: rgba(255, 255, 255, 0.3);
    backdrop-filter: blur(19px) saturate(170%);
    -webkit-backdrop-filter: blur(19px) saturate(170%);
    border: 1px solid rgba(255, 255, 255, 0.3);
    box-shadow:
    0 4px 30px rgba(0, 0, 0, 0.1),
    0 10px 20px rgba(0, 0, 0, 0.1);

    }

    #aplayer.rightside-aplayer .aplayer-list.aplayer-list-show {
    width: 398.5px; /* 设置你想要的展开宽度 */
    opacity: 1;
    }


    #aplayer.rightside-aplayer .aplayer-list ol {
    scrollbar-width: none;
    /* 隐藏滚动条 */
    }

    #aplayer.rightside-aplayer .aplayer-list ol li {
    border-top: 0.5px solid rgba(255, 255, 255, 0.3);
    }

    #aplayer.rightside-aplayer .aplayer-list ol li:first-child {
    border: none;
    }

    #aplayer.rightside-aplayer .aplayer-list ol .aplayer-list-light .aplayer-list-cur {
    background-color: rgba(245, 166, 185, 0.45) !important;
    }

    [data-theme="dark"] #aplayer.rightside-aplayer .aplayer-list {
    background: rgba(18, 18, 18, 0.15) !important;

    }

    [data-theme="dark"] #aplayer.rightside-aplayer .aplayer-list ol li {
    color: rgba(255, 255, 255, 0.7) !important;
    }

    [data-theme="dark"] #aplayer.rightside-aplayer .aplayer-list ol li .aplayer-list-author {
    color: rgba(255, 255, 255, 0.7) !important;
    }

    #aplayer.rightside-aplayer .aplayer-list ol .aplayer-list-light {
    background: rgba(255, 255, 255, 0.2);
    }

    /* [data-theme="dark"] #aplayer.rightside-aplayer .aplayer-list ol .aplayer-list-light{
    background: rgba(255, 255, 255, 0.2);
    } */

    [data-theme="dark"] #aplayer.rightside-aplayer .aplayer-list ol .aplayer-list-index {
    color: rgba(255, 255, 255, 0.7);
    }

    #aplayer.rightside-aplayer .aplayer-list ol li:hover {

    background: rgba(255, 255, 255, 0.2);
    }

    #aplayer.rightside-aplayer .aplayer-pic .aplayer-play {
    width: 16px;
    height: 16px;
    border: 2px solid #fff;
    bottom: 27px;
    right: 29px;
    margin: 0 -25px -23px 0;
    }

    #aplayer.rightside-aplayer .aplayer-pic .aplayer-play svg {
    position: absolute;
    top: 1.5px;
    left: 2.5px;
    height: 13px;
    width: 13px;
    }

    #aplayer.rightside-aplayer .aplayer-notice {
    display: none;
    }

    .aplayer.aplayer-fixed>.aplayer-lrc {
    display: none;
    }



    @media (max-width: 460px) {
    #aplayer.rightside-aplayer .aplayer-info.aplayer-info-show {
    overflow: hidden;
    display: inline-block;
    width: 300px;
    }
    }

    @media (max-width: 460px) {
    #aplayer.rightside-aplayer .aplayer-list.aplayer-list-show {
    width: 298.5px; /* 设置你想要的展开宽度 */
    opacity: 1;
    }
    }
    • 我这里通过添加自建 css 文件覆盖原有的样式,有点乱,也可以将原始的 css 文件下载到本地修改。
  2. 在主题配置文件 [Blogroot]\_config.butterfly.ymlinject 配置项中添加以下内容:
    1
    2
    3
    4
    5
    inject:
    head:
    - <link rel="stylesheet" href="/css/custom/rightside_aplayer.css">
    bottom:
    # - <script src="xxxx"></script>
  3. [Blogroot]\themes\butterfly\source\js\custom\ 目录下新建 rightside_aplayer.js 文件:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    (function () {
    const initAplayerScroll = () => {
    // 1. 获取目标元素
    const target = document.getElementById('aplayer');

    // 2. 容错判断:如果当前页面没这个元素,直接结束,不执行后续逻辑
    if (!target) return;

    // 3. 核心滚动逻辑
    const handleScroll = () => {
    // 获取滚动距离(兼容各浏览器)
    const scrollTop = window.scrollY || document.documentElement.scrollTop;

    // 超过 100px 则添加类名,否则移除
    if (scrollTop > 95) {
    target.classList.add('aplayer-active');
    } else {
    target.classList.remove('aplayer-active');
    }
    };

    // 4. 监听滚动事件(增加节流以优化性能)
    let ticking = false;
    window.addEventListener('scroll', () => {
    if (!ticking) {
    window.requestAnimationFrame(() => {
    handleScroll();
    ticking = false;
    });
    ticking = true;
    }
    }, { passive: true });

    // 5. 初始化执行一次,防止刷新页面时已在滚动条下方
    handleScroll();
    };

    // 确保 DOM 加载后运行
    if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initAplayerScroll);
    } else {
    initAplayerScroll();
    }
    })();


    const btn = document.querySelector('.aplayer-miniswitcher .aplayer-icon');
    const list = document.querySelector('.aplayer-list');

    document.addEventListener('click', (e) => {
    // 1. 检查点击的是否是切换按钮或其图标
    const toggleBtn = e.target.closest('.aplayer-miniswitcher .aplayer-icon');

    if (toggleBtn) {
    const list = document.querySelector('.aplayer-list');
    if (list) {
    list.classList.toggle('aplayer-list-show');
    }
    }
    });

    const info = document.querySelector('.aplayer-info');

    document.addEventListener('click', (e) => {
    // 1. 检查点击的是否是切换按钮或其图标
    const toggleBtn = e.target.closest('.aplayer-miniswitcher .aplayer-icon');

    if (toggleBtn) {
    const list = document.querySelector('.aplayer-info');
    if (list) {
    list.classList.toggle('aplayer-info-show');
    }
    }
    });

    • 这个是用于监听页面滚动,控制播放器的显示和隐藏,并与侧边按钮的显隐同步。
  4. 在主题配置文件 [Blogroot]\_config.butterfly.ymlinject 配置项中添加以下内容:
    1
    2
    3
    4
    5
    6
    inject:
    head:
    # - <link rel="stylesheet" href="/xxx.css">
    bottom:
    # - <script src="xxxx"></script>
    - <script src="/js/custom/rightside_aplayer.js"></script>
  5. 输入 hexo cl&hexo g&hexo s 重新生成静态文件,刷新页面即可查看效果。

后记

  1. 为什么没有直接写进 rightsidepug 文件里?
    • 试过,而且这样可以完全和侧边栏同步,效果也很好,但是 MetingJS 会失效,切换页面后播放器也会强制刷新,没有找到更合适的解决办法,欢迎大佬们完善。
  2. 代码写的比较乱,可以自行优化下。