点击查看更新记录

更新记录

2021-01-20:内测版v0.05

  1. 沿用B站同款样式动态banner
  2. 提取可配置元素
  3. 修复pjax问题
  4. 提供秋冬两套主题方案
  5. 可以通过主题配置文件全站配置
  6. 也可以通过设置页面Front-matter实现单页配置
  7. 优化逻辑,以页面Front-matter为最优先配置
点击查看参考教程
参考方向教程原贴
秋主题bannerCodePen-BiliBili Autumn Banner
冬主题bannerCodePen-BiliBili Winter Banner

资源下载

由于本教程涉及的所有修改对缩进格式等有严格要求,担心自己控制不好的可以直接下载静态资源。参照教程进行修改。本帖基于Butterfly_v3.5.1版本进行配置,低版本可能需要对index.pug稍加修改。精力有限没时间做全版本适配。读者如果有困难可以考虑群内交流或者直接升级最新版本主题。


魔改步骤

  1. 新建[Blogroot]\themes\butterfly\layout\includes\header\bilibili-banner.pug
    if (!is_home())
    - var banner_style = (typeof(page.bilibili_banner) != "undefined" && page.bilibili_banner!=null) ? page.bilibili_banner : theme.bilibili_banner.style
    if (banner_style === 'autumn')
    #autumnBanner
    div
    img(src='/bilibiliBanner/autumn/bilibili-autumn-1.png')
    div
    img(src='/bilibiliBanner/autumn/bilibili-autumn-2.png')
    div
    img(src='/bilibiliBanner/autumn/bilibili-autumn-3.png')
    div
    img(src='/bilibiliBanner/autumn/bilibili-autumn-4.png')
    div
    img(src='/bilibiliBanner/autumn/bilibili-autumn-5.png')
    div
    img(src='/bilibiliBanner/autumn/bilibili-autumn-6.png')
    else if (banner_style === 'winter')
    #winterBanner
    .view
    img.morning(src='/bilibiliBanner/winter/bilibili-winter-view-1.png' alt='')
    img.afternoon(src='/bilibiliBanner/winter/bilibili-winter-view-2.png' alt='')
    video.evening(autoplay='' loop='' muted='')
    source(src='/bilibiliBanner/winter/bilibili-winter-view-3.webm' type='video/webm')
    img.window-cover(src='/bilibiliBanner/winter/bilibili-winter-view-3-snow.png' alt='')
    .tree
    img.morning(src='/bilibiliBanner/winter/bilibili-winter-tree-1.png' alt='')
    img.afternoon(src='/bilibiliBanner/winter/bilibili-winter-tree-2.png' alt='')
    img.evening(src='/bilibiliBanner/winter/bilibili-winter-tree-3.png' alt='')
    script(async data-pjax src=url_for(theme.CDN.bilibili_banner))
  2. 新建[Blogroot]\themes\butterfly\source\css\bilibiliBanner.css,
    /* autumnBanner */
    @media screen and (max-width: 1000px) {
    #autumnBanner {
    display: none !important;
    }
    }
    #autumnBanner {
    height: 100%;
    position: relative;
    overflow: hidden;
    filter: brightness(70%);
    }

    #autumnBanner > div {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;

    --offset: 0px;
    --blur: 2px;
    }

    #autumnBanner > div > img {
    display: block;
    width: 110%;
    height: 100%;
    object-fit: cover;

    transform: translatex(var(--offset));
    filter: blur(var(--blur));
    }

    /* winterBanner */
    @media screen and (max-width: 1000px) {
    #winterBanner {
    display: none !important;
    }
    }

    #winterBanner {
    height: 100%;
    position: relative;
    width: 100%;
    overflow: hidden;
    --percentage: 0.5;
    }

    #winterBanner .view, #winterBanner .tree {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    }

    #winterBanner img, #winterBanner video {
    position: absolute;
    display: block;
    max-width: 120% !important;
    width: 120% !important;
    ;
    height: 100%;
    object-fit: cover;
    filter: brightness(70%);
    }

    #winterBanner .morning {
    z-index: 20;
    opacity: calc(1 - (var(--percentage) - 0.25) / 0.25);
    }

    #winterBanner .afternoon {
    z-index: 10;
    opacity: calc(1 - (var(--percentage) - 0.5) / 0.5);
    }

    #winterBanner .view {
    transform: translatex(calc(var(--percentage) * 100px));
    }

    #winterBanner .tree {
    transform: translatex(calc(var(--percentage) * 50px));
    filter: blur(3px);
    }

    #winterBanner .view,
    #winterBanner .tree,
    #winterBanner .morning,
    #winterBanner .afternoon {
    transition: .2s all ease-in;
    }

    #winterBanner.moving .view,
    #winterBanner.moving .tree,
    #winterBanner.moving .morning,
    #winterBanner.moving .afternoon {
    transition: none;
    }

    #winterBanner .window-cover {
    opacity: calc((var(--percentage) - 0.9) / 0.1);
    }
  3. 新建[Blogroot]\themes\butterfly\source\js\bilibili-banner.js
    //autumn_banner

    var autumnBanner = document.querySelector('#autumnBanner')
    if (autumnBanner) {
    var images = document.querySelectorAll('#autumnBanner > div > img')
    autumnBanner.addEventListener('mousemove', (e) => {
    let percentage = e.clientX / window.outerWidth
    let offset = 10 * percentage
    let blur = 20

    for (let [index, image] of images.entries()) {
    offset *= 1.3

    let blurValue = (Math.pow((index / images.length - percentage), 2) * blur)

    image.style.setProperty('--offset', `${offset}px`)
    image.style.setProperty('--blur', `${blurValue}px`)
    }
    })
    }
    //winter_banner

    var winterBanner = document.querySelector('#winterBanner')
    if (winterBanner) {
    var startingPoint
    winterBanner.addEventListener('mouseenter', (e) => {
    startingPoint = e.clientX
    winterBanner.classList.add('moving')
    })

    winterBanner.addEventListener('mouseout', (e) => {
    winterBanner.classList.remove('moving')
    winterBanner.style.setProperty('--percentage', 0.5)
    })

    winterBanner.addEventListener('mousemove', (e) => {
    let percentage = (e.clientX - startingPoint) / window.outerWidth + 0.5

    winterBanner.style.setProperty('--percentage', percentage)
    })
    }
  4. 将静态资源文件夹内的bilibiliBanner图片文件夹放到[Blogroot]\themes\butterfly\source\目录下。
  5. 修改[Blogroot]\themes\butterfly\layout\includes\header\index.pug,注入bilibili_banner组件
      header#page-header(class=isHomeClass style=bg_img)
    include ./nav.pug
    + if top_img !== false
    + - var bilibili_banner = (typeof(page.bilibili_banner) != "undefined" && page.bilibili_banner!=null) ? page.bilibili_banner : theme.bilibili_banner.enable
    + if (bilibili_banner)
    + include ./bilibili-banner.pug
    if is_post()
    include ./post-info.pug
    else if is_home()
  6. 在站点配置文件中添加配置项,打开[Blogroot]\_config.butterfly.yml,
    • 添加CDN配置项
        CDN:
      # main
      main_css: /css/index.css
      jquery: https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js
      main: /js/main.js
      utils: /js/utils.js
      + bilibili_banner: /js/bilibili-banner.js
    • 添加css配置项。此处使用了异步加载,同时做了媒体选择,对手机是不会生效的。因为手机的banner高度会导致适配效果很差。
      inject:
      head:
      - <link rel="stylesheet" href="/css/bilibiliBanner.css" media="defer" onload="this.media='screen'">
      bottom:

      这次不用stylus是因为我们需要加载全部的样式来支持每篇文章可以设置不同的主题,而且calc()函数在stylus中使用变量来动态计算语法很难写。

    • 添加bilibili_banner控制开关
      # banner样式
      bilibili_banner:
      enable: false # 开关banner
      style: winter # autumn 秋季样式 ;winter 冬季样式
  7. 除了在主题配置文件通过配置bilibili_banner:的默认项,还可以在每个页面的markdown文件中通过front-matter控制单页配置。提供了三个选项
    • false关闭该页面的动态banner显示
    • autumn开启该页面的动态banner,并设置主题为秋季
    • winter开启该页面的动态banner,并设置主题为冬季
      页面配置项优先级高于主题配置项。
    • 示例
      ---
      title: 给博客添加B站同款动态banner
      date: 2021-01-20 21:54:35
      bilibili_banner: autumn
      ---

TO DO

配置B站同款样式动态banner

适配pjax

提供秋冬两套主题方案

通过主题配置文件全站配置

通过设置页面Front-matter实现单页配置

春夏两款坐等小破站发资源