前言

折腾 Butterfly 主题也有一年多了,也是时候写篇文章记录一下本站的所有美化,美化过的一点一滴都会记录在此篇文章里,后续也会在此篇文章更新!

PS:基本没修改过源码!本博主 Butterfly 版本 3.7.7

适用人群:Butterfly 主题使用者!

首页背景图

查看预览

images

配置

这个背景图其实很简单,在主题的配置文件(_config.yml)里,CTRL + F 找到 index_img 配置项,修改它即可img

首页字体

查看预览

img

配置

这个就需要你自己新建一个 css 文件,在主题文件里的 source \ css 文件夹里新建一个 css 文件,命名随意

img

往里写几行代码就完事了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@font-face {
font-family:'arzhu';
src:url('https://cdn.jsdelivr.net/gh/xxx/xxx/font/xxx.ttf'); /* 修改成你的字体 */
font-display:swap
}
h1#site-title {
font-family:arzhu!important
}
span#subtitle {
font-family:arzhu!important
}
a#site-name {
font-family:arzhu!important
}

这里推荐俩字体网站

挑选您心爱的字体,并把它下载下来,可以存在本地,也可以利用 jsdelivr 的方式加速,最后替换 css 文件中的 url 即可,arzhu 只是别名,可以任意修改,不过引用的时候,要确保名字相同

最后在主题的配置文件里找到 inject 配置项,引用刚刚新建的 css 文件即可

img

href 这里我是采用 CDN 的方式,如果你是存在本地的话,那么此时的 href 就应该是

1
- <link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'">

media="defer" onload="this.media='all'" 这个只是 css 的异步加载,当然,你不写也可以!

全局背景透明渐变

查看预览

img

配置

同理,在刚刚新建的 css 文件里,添加如下代码

1
2
3
4
5
6
7
8
9
10
11
#recent-posts>.recent-post-item,.layout_page>div:first-child:not(.recent-posts),.layout_post>#page,.layout_post>#post,.read-mode .layout_post>#post {
background: var(--light_bg_color)
}

#aside-content .card-widget {
background: var(--light_bg_color)
}

#web_bg {
background: linear-gradient(90deg,rgba(247,149,51,.1),rgba(243,112,85,.1) 15%,rgba(239,78,123,.1) 30%,rgba(161,102,171,.1) 44%,rgba(80,115,184,.1) 58%,rgba(16,152,173,.1) 72%,rgba(7,179,155,.1) 86%,rgba(109,186,130,.1))
}

页脚透明渐变

完成了如上全局背景透明渐变,那么你的部落格背景就应该会有所变化了,但是发现这个页脚和我们的背景完全不搭

img

那我们就进行美化页脚部分

查看预览

img

配置

一样在刚刚新建的 css 文件里,添加如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#footer {
background: rgba(255,255,255,.15);
color: #000;
border-top-right-radius: 20px;
border-top-left-radius: 20px;
backdrop-filter: saturate(100%) blur(5px)
}

#footer::before {
background: rgba(255,255,255,.15)
}

#footer #footer-wrap {
color: var(--font-color)
}

#footer #footer-wrap a {
color: var(--font-color)
}

此时,页脚部分就和我们的背景很般配了

社交图标

查看预览

img

配置

社交图标我采用的是阿里巴巴矢量图标库

首先打开 阿里巴巴矢量图标库

在搜索框输入你想要的图标,比如 QQ

img

看中哪个就加入购物车

img

加购完毕之后点击右上角的购物车,添加至项目,选择其中一种快捷方式登录,项目名称随便填

然后在我的项目里选择 Font class,点击查看在线链接并在浏览器中打开此链接,最后另存为本地

img

吧刚刚另存为的文件复制到主题文件下的 source \ css 里面

img

然后在主题的配置文件(_config.yml)里的 inject 引入刚刚的图标 css 文件

img

接着不要关闭配置文件,继续在配置文件里 CTRL + F 找到 social 配置项

格式为:iconfont class 名: 链接 || 名称

其中

  • iconfont:是固定的

  • class 名:可在刚刚的阿里巴巴矢量图标库生成的 css 文件里找到

    img

  • 链接:点击图标之后跳转的链接

  • 名称:对应你图标的含义,例如:Twitter、Facebook

如下图:

img

此时你高兴的回到首页查看效果,可是你发现这图标又小又丑又黑,心情都不好了

img

不慌,打开 icon.css 也就是刚刚在阿里巴巴矢量图标库中生成的 css 文件

给他们穿件衣裳

img

果然,穿上衣裳就好看多了

img

如果你还想加其他的,比如微博、GitHub、哔哩哔哩等,其方法大同小异

页脚徽标

查看预览

footer

配置

这个挺简单的,可以直接通过 shields.io 在线生成

  • label:标签,徽标左侧内容
  • message:信息,徽标右侧内容
  • color:色值,支持支持十六进制、rgb、rgba、hsl、hsla 和 css 命名颜色。十六进制记得删除前面的 # 号

输入相关信息后,点击 make badge 即可得到徽标的 URL。可以用 img 标签引用

接着打开主题的配置文件(_config.yml)找到 custom_text 配置项并修改它,最后建议把 footer 配置下的 copyright 设为 false

img

我这里只是简单的举了个例子,想要啥就在 shields.io 直接生成即可

示例:

1
<p><a style="margin-inline:5px"target="_blank" href="https://hexo.io/"><img src="https://img.shields.io/badge/Frame-Hexo-blue?style=flat&logo=hexo" title="博客框架为 Hexo" alt="HEXO"></a><a style="margin-inline:5px"target="_blank" href="https://butterfly.js.org/"><img src="https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&logo=bitdefender" title="主题采用 Butterfly" alt="Butterfly"></a><a style="margin-inline:5px"target="_blank" href="https://www.jsdelivr.com/"><img src="https://img.shields.io/badge/CDN-jsDelivr-orange?style=flat&logo=jsDelivr" title="本站使用 Jsdelivr 为静态资源提供CDN加速" alt="Jsdelivr"></a><a style="margin-inline:5px"target="_blank" href="https://github.com/"><img src="https://img.shields.io/badge/Source-Github-d021d6?style=flat&logo=GitHub" title="本站项目由 GitHub 托管" alt="GitHub"></a><a style="margin-inline:5px"target="_blank"href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img src="https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&logo=Claris" alt="img" title="本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可"></a></p>

关闭侧边栏

这个其实官方文档也有讲,在某个页面如果你不想要侧边栏的话,可以在对应页面的 Markdown 里加如下配置

1
2
3
4
5
6
7
8
---
title: 标签
date: 2020-03-07 12:33:35
type: "tags"
comments: false
aside: false <-- 关闭侧边栏
top_img: false
---

此时我们对应的页面就没有侧边栏了

img

留言板信封

message_gif

首先最起码你得要有一个留言的页面

博客根目录右键 Git Bash 输入如下命令

1
hexo new page "message"

接着在博客根目录的 source 下就会发现刚刚新建的文件了

images

我们点进去打开 index.md

复制如下代码,即可完事

1
2
3
<link rel="stylesheet" href="https://npm.elemecdn.com/nanshen/css/blog/messagebar.css"/>

<div id="computer"><div id="maincontent"><br><div id="form-wrap"><img src="https://npm.elemecdn.com/cover_img/msg/before.webp"id="beforeimg"><div id="envelope"><form><div class="formmain"><img class="headerimg"src="https://npm.elemecdn.com/cover_img/msg/U5bb04af32be544c4b41206d9a42fcacfd.webp"/><div style="padding: 5px 20px;"><center><h3 calss="title3">来自小嘉的留言:</h3></center><center class="comments">有什么想问的?<br>有什么想说的?<br>有什么想吐槽的?<br></center><div class="bottomcontent"><img class="bottomimg"src="https://npm.elemecdn.com/cover_img/msg/U0968ee80fd5c4f05a02bdda9709b041eE.webp"/></div><p class="bottomhr">自动书记人偶竭诚为您服务!</p></div></div></form></div><img id="afterimg"src="https://npm.elemecdn.com/cover_img/msg/after.webp"></div></div></div><div id="mobile"><form><div class="formmain"><img class="headerimg"src="https://npm.elemecdn.com/cover_img/msg/U5bb04af32be544c4b41206d9a42fcacfd.webp"/><div style="padding: 5px 20px;"><center><h3 class="title3">来自小嘉的留言:</h3></center><center class="comments">有什么想问的?<br>有什么想说的?<br>有什么想吐槽的?<br></center><div class="bottomcontent"><img src="https://npm.elemecdn.com/cover_img/msg/U0968ee80fd5c4f05a02bdda9709b041eE.webp"class="bottomhr"></div><p class="bottomhr"">自动书记人偶竭诚为您服务!</p></div></div></form></div>

然后按照自己的需求,该改的改

注:如果你是用 Typora 写作的话,粘贴时请用 CTRL + SHIFT + V

新版使用的是 npm 插件的方式,作者:Akilar

在站点根目录执行

1
npm install hexo-butterfly-envelope --save

安装完成之后打开站点的配置文件或主题的配置文件,添加如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
envelope_comment:
enable: true
cover: https://ae01.alicdn.com/kf/U5bb04af32be544c4b41206d9a42fcacfd.jpg # 信笺封面图
message: # 信笺内容,支持多行
- 有什么想问的?
- 有什么想说的?
- 有什么想吐槽的?
bottom: 自动书记人偶竭诚为您服务! # 信笺结束语,只能单行
height: # 调整信笺划出高度,默认1050px
path: # 【可选】comments 的路径名称。默认为 comments , 生成的页面为 comments/index.html
front_matter: # 【可选】comments页面的 front_matter 配置
title: 留言板
comments: false
aside: false

最后 hexo 三连

gulp 压缩

查看预览

img

配置

一个可以自动压缩 HTML、JS、CSS 文件、图片,可以将 ES6 语法转换成 ES5,减少网络请求,同时降低网络负担

首先全局安装 gulp

1
npm install --global gulp-cli

安装压缩 HTML

1
2
npm install gulp-htmlclean --save-dev
npm install --save gulp-html-minifier-terser

安装压缩 CSS

1
npm install gulp-clean-css --save-dev

安装压缩 JS

这里我选择 gulp-uglify + gulp-babel,可以把 ES6 转换成 ES5,因为兼容所以选择

1
2
npm install --save-dev gulp-uglify
npm install --save-dev gulp-babel @babel/core @babel/preset-env

安装如上插件之后,在你的博客根目录创建一个 gulpfile.js 文件并把如下代码 CV 进去

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
var gulp = require('gulp');
var cleanCSS = require('gulp-clean-css');
var htmlmin = require('gulp-html-minifier-terser');
var htmlclean = require('gulp-htmlclean');
var uglify = require('gulp-uglify')
var babel = require('gulp-babel')
// 压缩js
gulp.task('compress', () =>
gulp.src(['./public/**/*.js', '!./public/**/*.min.js'])
.pipe(babel({
presets: ['@babel/preset-env']
}))
.pipe(uglify().on('error', function (e) {
console.log(e)
}))
.pipe(gulp.dest('./public'))
)
// 压缩css
gulp.task('minify-css', () => {
return gulp.src(['./public/**/*.css'])
.pipe(cleanCSS({
compatibility: 'ie11'
}))
.pipe(gulp.dest('./public'));
});
// 压缩html
gulp.task('minify-html', () => {
return gulp.src('./public/**/*.html')
.pipe(htmlclean())
.pipe(htmlmin({
removeComments: true, // 清除 html 注释
collapseWhitespace: true, // 压缩 html
collapseBooleanAttributes: true,
// 省略布尔属性的值,例如:<input checked="true"/> ==> <input />
removeEmptyAttributes: true,
// 删除所有空格作属性值,例如:<input id="" /> ==> <input />
removeScriptTypeAttributes: true,
// 删除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true,
// 删除<style>和<link>的 type="text/css"
minifyJS: true, // 压缩页面 JS
minifyCSS: true, // 压缩页面 CSS
minifyURLs: true // 压缩页面 URL
}))
.pipe(gulp.dest('./public'))
});

// 运行gulp命令时依次执行以下任务
gulp.task('default', gulp.parallel(
'compress', 'minify-css', 'minify-html'
))

使用:

在 hexo g 之后运行 gulp 即可

例如:

1
hexo cl && hexo g && gulp && hexo d

不过要注意的是,gulp 在本地运行是没有效果的,请部署之后再看效果

图片压缩

图片压缩我用的是 Imagine

根据自己系统选择下载。

使用也很简单,下载安装之后,把想压缩的图片拖进去就好

外挂标签

关于外挂标签请移步至 Akilar 的 基于 Butterfly 的外挂标签引入

此时,您的部落格整体样貌就基本和我的差不多了

友链魔改

查看预览

link

配置

原教程:Friend Link Card Beautify

友链这块修改了主题源码,是否要修改自行斟酌

魔改适用 Butterfly@3.6.0 +

3.3.0-3.5.1 的请看 Akilar 的原帖:Friend Link Card Beautify

  1. 修改 butterfly\layout\includes\page\flink.pug

    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
    #article-container
    if top_img === false
    h1.page-title= page.title

    if (theme.flink_style === 'butterfly')
    .flink
    if site.data.link
    each i in site.data.link
    if i.class_name
    h2!= i.class_name
    if i.class_desc
    .flink-desc!=i.class_desc
    .flink-list
    each item in i.link_list
    .flink-list-item
    a(href=url_for(item.link) title=item.name target="_blank")
    if theme.lazyload.enable
    img(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
    else
    img(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
    span.flink-item-name= item.name
    span.flink-item-desc(title=item.descr)= item.descr
    != page.content
    else if (theme.flink_style === 'volantis')
    .flink
    if site.data.link
    each i in site.data.link
    if i.class_name
    h2!= i.class_name
    if i.class_desc
    .flink-desc!=i.class_desc
    .site-card-group
    each item in i.link_list
    a.site-card(target='_blank' rel='noopener' href=url_for(item.link))
    .img
    - var siteshot = item.siteshot ? url_for(item.siteshot) : 'https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/' + item.link
    if theme.lazyload.enable
    img(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' )
    else
    img(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
    .info
    if theme.lazyload.enable
    img(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
    else
    img(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
    span.title= item.name
    span.desc(title=item.descr)= item.descr
    != page.content
    else if (theme.flink_style === 'flexcard')
    .flink
    if site.data.link
    each i in site.data.link
    if i.class_name
    h2!= i.class_name
    if i.class_desc
    .flink-desc!=i.class_desc
    .flink-list
    each item in i.link_list
    a.flink-list-card(href=url_for(item.link) target='_blank' data-title=item.descr)
    .wrapper.cover
    - var siteshot = item.siteshot ? url_for(item.siteshot) : 'https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/' + item.link
    if theme.lazyload.enable
    img.cover.fadeIn(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' )
    else
    img.cover.fadeIn(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
    .info
    if theme.lazyload.enable
    img.flink-avatar(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
    else
    img(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
    span.flink-sitename= item.name
    != page.content
  2. 修改 butterfly\source\css\_page\flink.styl

    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
    if hexo-config('flink_style') == 'butterfly'
    .flink#article-container
    .flink-desc
    margin: .2rem 0 .5rem

    .flink-list
    overflow: auto
    padding: 10px 10px 0
    text-align: center

    & > .flink-list-item
    position: relative
    float: left
    overflow: hidden
    margin: 15px 7px
    width: calc(100% / 3 - 15px)
    height: 90px
    border-radius: 8px
    line-height: 17px
    -webkit-transform: translateZ(0)

    +maxWidth1024()
    width: calc(50% - 15px) !important

    +maxWidth600()
    width: calc(100% - 15px) !important

    &:hover
    img
    transform: rotate(360deg)

    &:before
    position: absolute
    top: 0
    right: 0
    bottom: 0
    left: 0
    z-index: -1
    background: var(--text-bg-hover)
    content: ''
    transition: transform .3s ease-out
    transform: scale(0)

    &:hover:before,
    &:focus:before,
    &:active:before
    transform: scale(1)

    a
    color: var(--font-color)
    text-decoration: none

    img
    float: left
    margin: 15px 10px
    width: 60px
    height: 60px
    border-radius: 35px
    transition: all .3s

    .img-alt
    display: none

    .flink-item-name
    @extend .limit-one-line
    display: block
    padding: 16px 10px 0 0
    height: 40px
    font-weight: bold
    font-size: 1.43em

    .flink-item-desc
    @extend .limit-one-line
    display: block
    padding: 16px 10px 16px 0
    height: 50px
    font-size: .93em
    else if hexo-config('flink_style') == 'volantis'
    trans($time = 0.28s)
    transition: all $time ease
    -moz-transition: all $time ease
    -webkit-transition: all $time ease
    -o-transition: all $time ease
    .site-card-group
    display: flex
    flex-wrap: wrap
    justify-content: flex-start
    margin: -0.5 * 16px
    align-items: stretch
    .site-card
    margin: 16px * 0.5
    width: "calc(100% / 4 - %s)" % 16px
    @media screen and (min-width: 2048px)
    width: "calc(100% / 5 - %s)" % 16px
    @media screen and (max-width: 768px)
    width: "calc(100% / 3 - %s)" % 16px
    @media screen and (max-width: 500px)
    width: "calc(100% / 2 - %s)" % 16px
    display: block
    line-height: 1.4
    height 100%
    .img
    width: 100%
    height 120px
    @media screen and (max-width: 500px)
    height 100px
    overflow: hidden
    border-radius: 12px * 0.5
    box-shadow: 0 1px 2px 0px rgba(0, 0, 0, 0.2)
    background: #f6f6f6
    img
    width: 100%
    height 100%
    // trans(.75s)
    transition: transform 2s ease
    object-fit: cover

    .info
    margin-top: 16px * 0.5
    img
    width: 32px
    height: 32px
    border-radius: 16px
    float: left
    margin-right: 8px
    margin-top: 2px
    span
    display: block
    .title
    font-weight: 600
    font-size: $fontsize-list
    color: #444
    display: -webkit-box
    -webkit-box-orient: vertical
    overflow: hidden
    -webkit-line-clamp: 1
    trans()
    .desc
    font-size: $fontsize-footnote
    word-wrap: break-word;
    line-height: 1.2
    color: #888
    display: -webkit-box
    -webkit-box-orient: vertical
    overflow: hidden
    -webkit-line-clamp: 2
    .img
    trans()
    &:hover
    .img
    box-shadow: 0 4px 8px 0px rgba(0, 0, 0, 0.1), 0 2px 4px 0px rgba(0, 0, 0, 0.1), 0 4px 8px 0px rgba(0, 0, 0, 0.1), 0 8px 16px 0px rgba(0, 0, 0, 0.1)
    .info .title
    color: #ff5722
    else if hexo-config('flink_style') == 'flexcard'
    #article-container img
    margin 0 auto!important
    .flink-list
    overflow auto
    & > a
    width calc(25% - 15px)
    height 130px
    position relative
    display block
    margin 15px 7px
    float left
    overflow hidden
    border-radius 10px
    transition all .3s ease 0s, transform .6s cubic-bezier(.6, .2, .1, 1) 0s
    box-shadow 0 14px 38px rgba(0, 0, 0, .08), 0 3px 8px rgba(0, 0, 0, .06)
    &:hover
    .info
    transform translateY(-100%)
    .wrapper
    img
    transform scale(1.2)
    &:before
    position: fixed
    width:inherit
    margin:auto
    left:0
    right:0
    top:10%
    border-radius: 10px
    text-align: center
    z-index: 100
    content: attr(data-title)
    font-size: 20px
    color: #fff
    padding: 10px
    background-color: rgba($theme-color,0.8)
    .cover
    width 100%
    transition transform .5s ease-out
    .wrapper
    position relative
    .fadeIn
    animation coverIn .8s ease-out forwards
    img
    height 130px
    pointer-events none
    .info
    display flex
    flex-direction column
    justify-content center
    align-items center
    width 100%
    height 100%
    overflow hidden
    border-radius 3px
    background-color hsla(0, 0%, 100%, .7)
    transition transform .5s cubic-bezier(.6, .2, .1, 1) 0s
    img
    position relative
    top 22px //因为字体大小不同,可能导致头像偏高,可以在此处通过修改top的值来微调头像框的位置至卡片正中。
    width 66px
    height 66px
    border-radius 50%
    box-shadow 0 0 10px rgba(0, 0, 0, .3)
    z-index 1
    text-align center
    pointer-events none
    span
    padding 20px 10% 60px 10%
    font-size 16px
    width 100%
    text-align center
    box-shadow 0 0 10px rgba(0, 0, 0, .3)
    background-color hsla(0, 0%, 100%, .7)
    color var(--font-color)
    white-space nowrap
    overflow hidden
    text-overflow ellipsis
    .flink-list>a .info,
    .flink-list>a .wrapper .cover
    position absolute
    top 0
    left 0

    @media screen and (max-width:1024px)
    .flink-list
    & > a
    width calc(33.33333% - 15px)

    @media screen and (max-width:600px)
    .flink-list
    & > a
    width calc(50% - 15px)

    [data-theme=dark]
    .flink-list a .info,
    .flink-list a .info span
    background-color rgba(0, 0, 0, .6)
    .flink-list
    & > a
    &:hover
    &:before
    background-color: rgba(#121212,0.8);

  3. blog\source\_data\link.yml 根据自身是否添加 siteshot,因为 Volantis 的 site-card 比 Butterfly 的 flink-card 多了一个站点缩略图,所以需要再额外添加一条 siteshot 配置项,不添加也可以,通过 butterfly\layout\includes\page\flink.pug 源码可以看出,如果你配置了 siteshot 的话,它就走 siteshot,没有配置的话,默认就调 API,其优先级 siteshot 高于 API

    flink.pug

    1
    2
    3
    4
    5
    6
    7
    8
    - class_name: xxx
    class_desc: xxx
    link_list:
    - name: xxx
    link: xxx
    avatar: xxx
    descr: xxx
    siteshot: # 站点缩略图
  4. blog\_config.butterfly.yml 中添加配置项,如果你没有用主题升级方法的话,那么在 butterfly\_config.yml 中添加。

    1
    2
    # 友链样式,butterfly 为默认样式,volantis 为站点卡片样式.flexcard 为弹性卡片样式
    flink_style: flexcard # butterfly | volantis | flexcard

    继续配置懒加载和 404 配置,因为站点卡片添加了懒加载和图片失效替换

    1
    2
    3
    4
    # 替换无法显示的图片
    error_img:
    flink: //cdn.jsdelivr.net... # 头像失效替换图
    post_page: //cdn.jsdelivr.net... # 文章图失效替换图
  5. hexo cl && hexo g && hexo s 本地调式查看效果

已知问题

相册样式错乱

link

解决:

在你的自定义 css 文件中,添加如下代码

1
2
3
4
5
6
7
8
9
10
11
12
a > img, .justified-gallery > div > img,
.justified-gallery > figure > img,
.justified-gallery > a > a > img,
.justified-gallery > div > a > img,
.justified-gallery > figure > a > img,
.justified-gallery > a > svg,
.justified-gallery > div > svg,
.justified-gallery > figure > svg,
.justified-gallery > a > a > svg,
.justified-gallery > div > a > svg,
.justified-gallery > figure > a > svg{
position:static!important;}

其它问题

参考:可能遇到的 Bug

友链朋友圈

参考:基于 hexo 的友链朋友圈

link_pyq

GitHub 贡献度

查看预览

images

配置

项目地址:hexo-github-calendar

先安装插件

1
npm i hexo-githubcalendar --save

然后打开 Hexo 的配置文件,注:不是主题的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
githubcalendar:
enable: true
enable_page: / # 表示只在根目录(首页)显示
user: zjwo # 替换成你 GitHub 的用户名
layout_id: recent-posts
githubcalendar_html: '<div class="recent-post-item" style="width:100%;height:auto;padding:10px;"><div id="github_loading" style="width:10%;height:100%;margin:0 auto;display: block"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50" xml:space="preserve"><path fill="#d0d0d0" d="M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z" transform="rotate(275.098 25 25)"><animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="0.6s" repeatCount="indefinite"></animateTransform></path></svg></div><div id="github_container"></div></div>'
pc_minheight: 280px
mobile_minheight: 0px
color: "['#ebedf0', '#fdcdec', '#fc9bd9', '#fa6ac5', '#f838b2', '#f5089f', '#c4067e', '#92055e', '#540336', '#48022f', '#30021f']"
api: https://python-github-calendar-api.vercel.app/api
# api: https://python-gitee-calendar-api.vercel.app/api
calendar_js: https://cdn.jsdelivr.net/gh/Zfour/hexo-github-calendar@1.16/hexo_githubcalendar.js

如果你觉得默认的浅紫色不好看,可以选择以下色调

1
2
3
4
5
6
# 橘黄色调
color: "['#e4dfd7', '#f9f4dc', '#f7e8aa', '#f7e8aa', '#f8df72', '#fcd217', '#fcc515', '#f28e16', '#fb8b05', '#d85916', '#f43e06']"
# 翠绿色调
color: "['#ebedf0', '#f0fff4', '#dcffe4', '#bef5cb', '#85e89d', '#34d058', '#28a745', '#22863a', '#176f2c', '#165c26', '#144620']"
# 天青色调
color: "['#ebedf0', '#f1f8ff', '#dbedff', '#c8e1ff', '#79b8ff', '#2188ff', '#0366d6', '#005cc5', '#044289', '#032f62', '#05264c']"

也可以自己自定义

最后 hexo cl 三连命令查看效果

说说配置

前置要求,参考 Artitalk 文档 - LeanCloud 的相关准备,必须要配置好 LeanCloud 再往下看

从 Butterfly@3.7.0 开始,移除了 artitalk,改为 npm 安装的方式

在你的博客目录下安装插件

1
npm install hexo-butterfly-artitalk

然后手动在 butterfly 主题下的配置文件添加如下配置

1
2
3
4
5
6
7
8
9
10
artitalk:
enable: true
appId:
appKey:
path:
js:
option:
front_matter:
aside: false # 关闭侧边栏
comments: false # 关闭评论
参数说明
appId【必须】LeanCloud 创建应用的 AppID
appKey【必须】LeanCloud 创建应用的 AppKEY
path【可选】Artitalk 的路径名称(默认为 artitalk,生成的页面为 artitalk/index.html)
js【可选】更換 Artitalk 的 js CDN(默认为 https://cdn.jsdelivr.net/npm/artitalk
option【可选】Artitalk 需要的额外配置
front_matter【可选】Artitalk 页面的 front_matter 配置

效果:

artitalk

另外说明下,如果使用了 artitalk,无需额外创建页面,主题会根据配置自动生成页面!

使用前请先确保参考林木木的教程成功配置好云函数之后再来使用

前端配置只需在你的哔哔页面的 index.md 复制如下代码并进行修改即可!

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
<div id='speak'></speak>
<!-- 使用markdown渲染 -->
<script type="text/javascript" src="https://npm.elemecdn.com/nanshen/js/blog/bb/ispeak-bber.min.js" charset="utf-8" ></script>
<!-- 不使用markdown渲染 -->
<!-- <script type="text/javascript" src="https://npm.elemecdn.com/ispeak-bber/ispeak-bber.min.js" charset="utf-8" ></script> -->
<!-- 解析微信表情(参考:https://github.com/buddys/qq-wechat-emotion-parser) -->
<!-- <script src="https://cdn.jsdelivr.net/gh/buddys/qq-wechat-emotion-parser@master/dist/qq-wechat-emotion-parser.min.js"></script> -->
<script>
ispeakBber
.init({
el: '#speak', // 容器选择器
name: 'garvey 🦄', // 显示的昵称
envId: '腾讯云开发环境id', // 环境id
region: 'ap-shanghai', // 腾讯云地址,默认为上海
limit: 10, // 每次加载的条数,默认为5
avatar: 'https://cdn.jsdelivr.net/gh/xxx/avatar.jpg', // 头像地址
fromColor:'rgb(245, 150, 170)', // 下方标签背景颜色 默认 rgb(245, 150, 170)
loadingImg: 'https://7.dusays.com/2021/03/04/d2d5e983e2961.gif', // 自定义loading的图片,示例值为默认值
dbName:'talks' // 数据的名称,默认talks,避免有人的命名不是这个,所以加入此配置字段。
})
.then(function() {
// 哔哔加载完成后的回调函数,你可以写你自己的功能
console.log('哔哔 加载完成')
})
</script>

其中,云数据库名称必须为 talks 才可以

效果:

bibi

仓库地址:【DreamyTZK / ispeak-bber】

网站统计

此统计功能来自于 Eurkon

  1. 创建统计页面

    1
    hexo new page charts
  2. 引入 ECharts.js,在 Butterfly 主题下的配置文件添加。(注意不是在 bottom

    1
    2
    3
    inject:
    head:
    - <script src="https://npm.elemecdn.com/echarts@4.7.0/dist/echarts.min.js"></script>
  3. butterfly\scripts\helpers\ 目录下新建 charts.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
    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
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    const cheerio = require('cheerio')
    const moment = require('moment')

    hexo.extend.filter.register('after_render:html', function (locals) {
    const $ = cheerio.load(locals)
    const post = $('#posts-chart')
    const tag = $('#tags-chart')
    const category = $('#categories-chart')
    let htmlEncode = false

    if (post.length > 0 || tag.length > 0 || category.length > 0) {
    if (post.length > 0 && $('#postsChart').length === 0) {
    if (post.attr('data-encode') === 'true') htmlEncode = true
    post.after(postsChart())
    }
    if (tag.length > 0 && $('#tagsChart').length === 0) {
    if (tag.attr('data-encode') === 'true') htmlEncode = true
    tag.after(tagsChart(tag.attr('data-length')))
    }
    if (category.length > 0 && $('#categoriesChart').length === 0) {
    if (category.attr('data-encode') === 'true') htmlEncode = true
    category.after(categoriesChart())
    }
    if (htmlEncode) {
    return $.root().html().replace(/&amp;#/g, '&#')
    } else {
    return $.root().html()
    }
    } else {
    return locals
    }
    }, 15)

    function postsChart () {
    const startDate = moment('2020-01') // 博客建站月份或自定义时间
    // const startDate = moment().subtract(1,'year').format('YYYY-MM'); // 一年前的今日,统计近一年的文章发布
    const endDate = moment()

    const monthMap = new Map()
    const dayTime = 3600 * 24 * 1000
    for (let time = startDate; time <= endDate; time += dayTime) {
    const month = moment(time).format('YYYY-MM')
    if (!monthMap.has(month)) {
    monthMap.set(month, 0)
    }
    }
    hexo.locals.get('posts').forEach(function (post) {
    const month = post.date.format('YYYY-MM')
    if (monthMap.has(month)) {
    monthMap.set(month, monthMap.get(month) + 1)
    }
    })
    const monthArr = JSON.stringify([...monthMap.keys()])
    const monthValueArr = JSON.stringify([...monthMap.values()])

    return `
    <script id="postsChart">
    var postsChart = echarts.init(document.getElementById('posts-chart'), 'light');
    var postsOption = {
    textStyle: {
    color: '#FFF'
    },
    title: {
    text: '文章发布统计图',
    x: 'center',
    textStyle: {
    color: '#FFF'
    }
    },
    tooltip: {
    trigger: 'axis'
    },
    xAxis: {
    name: '日期',
    type: 'category',
    axisTick: {
    show: false
    },
    axisLine: {
    show: true,
    lineStyle: {
    color: '#FFF'
    }
    },
    data: ${monthArr}
    },
    yAxis: {
    name: '文章篇数',
    type: 'value',
    splitLine: {
    show: false
    },
    axisTick: {
    show: false
    },
    axisLine: {
    show: true,
    lineStyle: {
    color: '#FFF'
    }
    }
    },
    series: [{
    name: '文章篇数',
    type: 'line',
    smooth: true,
    lineStyle: {
    width: 0
    },
    showSymbol: false,
    itemStyle: {
    opacity: 1,
    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
    offset: 0,
    color: 'rgba(128, 255, 165)'
    },
    {
    offset: 1,
    color: 'rgba(1, 191, 236)'
    }])
    },
    areaStyle: {
    opacity: 1,
    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
    offset: 0,
    color: 'rgba(128, 255, 165)'
    }, {
    offset: 1,
    color: 'rgba(1, 191, 236)'
    }])
    },
    data: ${monthValueArr},
    markLine: {
    data: [{
    name: '平均值',
    type: 'average'
    }]
    }
    }]
    };
    postsChart.setOption(postsOption);
    window.addEventListener("resize", () => {
    postsChart.resize();
    });
    </script>`
    }

    function tagsChart (len) {
    const tagArr = []
    hexo.locals.get('tags').map(function (tag) {
    tagArr.push({ name: tag.name, value: tag.length })
    })
    tagArr.sort((a, b) => { return b.value - a.value })

    let dataLength = Math.min(tagArr.length, len) || tagArr.length
    const tagNameArr = []
    const tagCountArr = []
    for (let i = 0; i < dataLength; i++) {
    tagNameArr.push(tagArr[i].name)
    tagCountArr.push(tagArr[i].value)
    }
    const tagNameArrJson = JSON.stringify(tagNameArr)
    const tagCountArrJson = JSON.stringify(tagCountArr)

    return `
    <script id="tagsChart">
    var tagsChart = echarts.init(document.getElementById('tags-chart'), 'light');
    var tagsOption = {
    textStyle: {
    color: '#FFF'
    },
    title: {
    text: 'Top ${dataLength} 标签统计图',
    x: 'center',
    textStyle: {
    color: '#FFF'
    }
    },
    tooltip: {},
    xAxis: [{
    name: '标签',
    type: 'category',
    axisTick: {
    show: false
    },
    axisLine: {
    show: true,
    lineStyle: {
    color: '#FFF'
    }
    },
    data: ${tagNameArrJson}
    }],
    yAxis: [{
    name: '文章篇数',
    type: 'value',
    splitLine: {
    show: false
    },
    axisTick: {
    show: false
    },
    axisLine: {
    show: true,
    lineStyle: {
    color: '#FFF'
    }
    }
    }],
    series: [{
    name: '文章篇数',
    type: 'bar',
    data: ${tagCountArrJson},
    itemStyle: {
    opacity: 1,
    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
    offset: 0,
    color: 'rgba(128, 255, 165)'
    },
    {
    offset: 1,
    color: 'rgba(1, 191, 236)'
    }])
    },
    emphasis: {
    itemStyle: {
    opacity: 1,
    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
    offset: 0,
    color: 'rgba(128, 255, 195)'
    },
    {
    offset: 1,
    color: 'rgba(1, 211, 255)'
    }])
    }
    },
    markLine: {
    data: [{
    name: '平均值',
    type: 'average'
    }]
    }
    }]
    };
    tagsChart.setOption(tagsOption);
    window.addEventListener("resize", () => {
    tagsChart.resize();
    });
    </script>`
    }

    function categoriesChart () {
    const categoryArr = []
    hexo.locals.get('categories').map(function (category) {
    categoryArr.push({ name: category.name, value: category.length })
    })
    categoryArr.sort((a, b) => { return b.value - a.value });
    const categoryArrJson = JSON.stringify(categoryArr)

    return `
    <script id="categoriesChart">
    var categoriesChart = echarts.init(document.getElementById('categories-chart'), 'light');
    var categoriesOption = {
    textStyle: {
    color: '#FFF'
    },
    title: {
    text: '文章分类统计图',
    x: 'center',
    textStyle: {
    color: '#FFF'
    }
    },
    legend: {
    top: 'bottom',
    textStyle: {
    color: '#FFF'
    }
    },
    tooltip: {
    trigger: 'item',
    formatter: "{a} <br/>{b} : {c} ({d}%)"
    },
    series: [{
    name: '文章篇数',
    type: 'pie',
    radius: [30, 80],
    center: ['50%', '50%'],
    roseType: 'area',
    label: {
    formatter: "{b} : {c} ({d}%)"
    },
    data: ${categoryArrJson},
    itemStyle: {
    emphasis: {
    shadowBlur: 10,
    shadowOffsetX: 0,
    shadowColor: 'rgba(255, 255, 255, 0.5)'
    }
    }
    }]
    };
    categoriesChart.setOption(categoriesOption);
    window.addEventListener("resize", () => {
    categoriesChart.resize();
    });
    </script>`
    }
  4. charts\index.md 添加如下代码

    1
    2
    3
    4
    5
    6
    <!-- 文章发布时间统计图 -->
    <div id="posts-chart" style="background-color: #20232a; border-radius: 8px; height: 300px; padding: 0.5rem;"></div>
    <!-- 文章标签统计图 -->
    <div id="tags-chart" data-length="10" style="background-color: #20232a; border-radius: 8px; height: 300px; padding: 0.5rem;"></div>
    <!-- 文章分类统计图 -->
    <div id="categories-chart" style="background-color: #20232a; border-radius: 8px; height: 300px; padding: 0.5rem;"></div>

这个只是文章的统计量,还有针对于网站的统计,请到原文中查阅【Hexo 博客访问统计图】

最后 hexo cl && hexo g && hexo s 查看效果!

首页及侧边栏展示 BiBi

首页

images

侧边栏

images

请确保你已经配置好哔哔再来使用,此功能来自小康博客!

这个其实是借助了 Butterfly 3.5.0 添加的自定义侧边栏功能,可以添加自己喜欢的 widget,参考 自定義側邊欄

source/_data(如果沒有 _data 文件夹,请自行创建),创建一个文件 widget.yml

自定义侧边栏在 Butterfly@3.8.0 中写法已更改

所以自然而然教程也得更新!

添加如下代码

3.8.0 及以上版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
top:
- class_name: latestBB
id_name:
name: 碎碎念
icon: fas fa-bolt
order: -1
html: |
<div class="swiper-container swiper-container-aside">
<div class="swiper-wrapper swiper-weapper-aside"></div>
</div>
<a class="bb-btn button--animated" href="/talking/" title="查看全部"><i class="far fa-hand-point-right fa-fw"></i> 查看更多 </a>
<script>
window.kkBBConfig = {
limit: 9,
blog:'/talking/',
api_url:
'https://xxx/json/bber.json' # 存储 bb json 的地址
}
</script>
<script src="https://npm.elemecdn.com/butterfly-bber-swiper/dist/index.min.js"></script>

3.5.0 - 3.8.0 版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- class_name: latestBB
id_name:
name: 自言自语
icon: fas fa-bolt
order: -1 # 排序
html: |
<div class="swiper-container swiper-container-aside">
<div class="swiper-wrapper swiper-weapper-aside"></div>
</div>
<a class="bb-btn button--animated" href="/talking/" title="查看全部"><i class="far fa-hand-point-right fa-fw"></i> 查看更多 </a>
<script>
window.kkBBConfig = {
limit: 9,
blog:'/talking/',
api_url:
'https://xxx/json/bber.json' # 存储 bb json 的地址
}
</script>
<script src="https://npm.elemecdn.com/butterfly-bber-swiper/dist/index.min.js"></script>

其中 latestBB 容器 class 名,不要更改

HTML 内容!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="swiper-container swiper-container-aside">
<div class="swiper-wrapper swiper-weapper-aside"></div>
</div>
<!--点击后跳转的链接,指你哔哔的页面 -->
<a class="bb-btn button--animated" href="/talking/" title="查看全部"><i class="far fa-hand-point-right fa-fw"></i> 查看更多 </a>
<script>
window.kkBBConfig = {
limit: 9,
// 点击后跳转的链接,指你哔哔的页面
blog:'/talking/',
// 可以是 json 文件地址,也可以是 api 地址
api_url:
'https://xxx/json/bber.json'
}
</script>
<script src="https://npm.elemecdn.com/butterfly-bber-swiper/dist/index.min.js"></script>

最后 Hexo 三连即可查看效果!

添加 WOW 动画效果

如需其它配置方案,可参考店长的 插件化配置方案外挂标签写法配置方案

butterfly\source\js\目录下新建 wow_init.js,配置特性动画的默认项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
wow = new WOW({
boxClass: 'wow',
// 当用户滚动时显示隐藏框的类名称
animateClass: 'animate__animated',
// 触发 CSS 动画的类名称(动画库默认为"animate.css"库)
offset: 0,
// 定义浏览器视口底部与隐藏框顶部之间的距离。
// 当用户滚动并到达此距离时,将显示隐藏的框。
mobile: false,
// 在移动设备上打开/关闭wow.js。
live: true
// 在页面上检查新的 wow.js元素。
})
wow.init();

在主题配置文件下找到 inject 配置项,引入 css 和 js

1
2
3
4
5
6
inject:
head:
- <link rel="stylesheet" href="https://npm.elemecdn.com/animate.css@4.1.1/animate.min.css" media="defer" onload="this.media='all'">
bottom:
- <script defer src="https://cdn.jsdelivr.net/gh/graingert/wow@1.3.0/dist/wow.min.js"></script>
- <script defer data-pjax src="/js/wow_init.js"></script>

使用

  • 页面内写法(指 page 页面或者 posts 页面)

    在需要添加动画效果的页面加上 <div class='example'><div>

    1
    2
    3
    <div class="example wow animate__bounceInUp">
    我是内容
    </div>
  • pug 写法

    例如给首页文章卡片套上动画

    1
    2
    3
    4
    5
    6
    mixin postUI(posts)
    each article , index in page.posts.data
    - .recent-post-item
    + .recent-post-item.wow.animate__zoomIn
    - let link = article.link || article.path
    - let title = article.title || _p('no_title')
  • js 批量添加写法(引入顺序需要在 wow_init.js 之前,而且需要 pjax 重载,每页重新添加一遍 class)

    通过在页面按 F12,使用控制台元素选择器找到对应元素并获取 class 类名

    修改 butterfly\source\js\wow_init.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
    // 首页文章卡片动画
    var arr = document.getElementsByClassName("recent-post-item");
    for (var i = 0; i < arr.length; i++) {
    arr[i].classList.add("wow"); // 必要项,添加wow.js标记
    arr[i].classList.add("animate__flipInX"); // 必要项,添加样式动画
    }

    // 友链动画
    var arr = document.getElementsByClassName("flink-list-item");
    for (var i = 0; i < arr.length; i++) {
    arr[i].classList.add("wow");
    arr[i].classList.add("animate__shakeY");
    }
    // 标签动画
    var arr = document.getElementsByClassName("tag-cloud-list is-center");
    for (var i = 0; i < arr.length; i++) {
    arr[i].classList.add("wow");
    arr[i].classList.add("animate__slideInUp");
    }

    // 初始化函数 动画效果预览: https://animate.style/
    wow = new WOW({
    // 当用户滚动时显示隐藏框的类名称
    boxClass: 'wow',
    // 触发 CSS 动画的类名称(动画库默认为"animate.css"库)
    animateClass: 'animate__animated',
    // 定义浏览器视口底部与隐藏框顶部之间的距离。
    // 当用户滚动并到达此距离时,将显示隐藏的框。
    offset: 0,
    // 在移动设备上打开/关闭wow.js。
    mobile: false,
    // 在页面上检查新的 wow.js元素。
    live: true
    })
    wow.init();

hexo 三连即可看到效果,更多动画样式可以查看 【animate.css 参考文档】

特别鸣谢