关于我 Butterfly 主题的所有美化
前言
折腾 Butterfly 主题也有一年多了,也是时候写篇文章记录一下本站的所有美化,美化过的一点一滴都会记录在此篇文章里,后续也会在此篇文章更新!
PS:基本没修改过源码!本博主 Butterfly 版本 3.7.7
适用人群:Butterfly 主题使用者!
首页背景图
查看预览
配置
这个背景图其实很简单,在主题的配置文件(_config.yml
)里,CTRL + F 找到 index_img
配置项,修改它即可
首页字体
查看预览
配置
这个就需要你自己新建一个 css
文件,在主题文件里的 source \ css
文件夹里新建一个 css
文件,命名随意
往里写几行代码就完事了
1 | @font-face { |
这里推荐俩字体网站
挑选您心爱的字体,并把它下载下来,可以存在本地,也可以利用 jsdelivr
的方式加速,最后替换 css 文件中的 url 即可,arzhu
只是别名,可以任意修改,不过引用的时候,要确保名字相同
最后在主题的配置文件里找到 inject
配置项,引用刚刚新建的 css 文件即可
href 这里我是采用 CDN 的方式,如果你是存在本地的话,那么此时的 href 就应该是
1 | - <link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'"> |
media="defer" onload="this.media='all'"
这个只是 css 的异步加载,当然,你不写也可以!
全局背景透明渐变
查看预览
配置
同理,在刚刚新建的 css 文件里,添加如下代码
1 | #recent-posts>.recent-post-item,.layout_page>div:first-child:not(.recent-posts),.layout_post>#page,.layout_post>#post,.read-mode .layout_post>#post { |
页脚透明渐变
完成了如上全局背景透明渐变,那么你的部落格背景就应该会有所变化了,但是发现这个页脚和我们的背景完全不搭
那我们就进行美化页脚部分
查看预览
配置
一样在刚刚新建的 css
文件里,添加如下代码
1 | #footer { |
此时,页脚部分就和我们的背景很般配了
社交图标
查看预览
配置
社交图标我采用的是阿里巴巴矢量图标库
首先打开 阿里巴巴矢量图标库
在搜索框输入你想要的图标,比如 QQ
看中哪个就加入购物车
加购完毕之后点击右上角的购物车,添加至项目,选择其中一种快捷方式登录,项目名称随便填
然后在我的项目里选择 Font class
,点击查看在线链接并在浏览器中打开此链接,最后另存为本地
吧刚刚另存为的文件复制到主题文件下的 source \ css
里面
然后在主题的配置文件(_config.yml
)里的 inject
引入刚刚的图标 css 文件
接着不要关闭配置文件,继续在配置文件里 CTRL + F 找到 social
配置项
格式为:iconfont class 名: 链接 || 名称
其中
iconfont:是固定的
class 名:可在刚刚的阿里巴巴矢量图标库生成的 css 文件里找到
链接:点击图标之后跳转的链接
名称:对应你图标的含义,例如:Twitter、Facebook
如下图:
此时你高兴的回到首页查看效果,可是你发现这图标又小又丑又黑,心情都不好了
不慌,打开 icon.css
也就是刚刚在阿里巴巴矢量图标库中生成的 css 文件
给他们穿件衣裳
果然,穿上衣裳就好看多了
如果你还想加其他的,比如微博、GitHub、哔哩哔哩等,其方法大同小异
页脚徽标
查看预览
配置
这个挺简单的,可以直接通过 shields.io 在线生成
- label:标签,徽标左侧内容
- message:信息,徽标右侧内容
- color:色值,支持支持十六进制、rgb、rgba、hsl、hsla 和 css 命名颜色。十六进制记得删除前面的 # 号
输入相关信息后,点击 make badge
即可得到徽标的 URL。可以用 img 标签引用
接着打开主题的配置文件(_config.yml)找到 custom_text
配置项并修改它,最后建议把 footer 配置下的 copyright 设为 false
我这里只是简单的举了个例子,想要啥就在 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 | --- |
此时我们对应的页面就没有侧边栏了
留言板信封
首先最起码你得要有一个留言的页面
博客根目录右键 Git Bash
输入如下命令
1 | hexo new page "message" |
接着在博客根目录的 source
下就会发现刚刚新建的文件了
我们点进去打开 index.md
复制如下代码,即可完事
1 | <link rel="stylesheet" href="https://npm.elemecdn.com/nanshen/css/blog/messagebar.css"/> |
然后按照自己的需求,该改的改
注:如果你是用 Typora 写作的话,粘贴时请用 CTRL + SHIFT + V
新版使用的是 npm 插件的方式,作者:Akilar
在站点根目录执行
1 | npm install hexo-butterfly-envelope --save |
安装完成之后打开站点的配置文件或主题的配置文件,添加如下配置
1 | envelope_comment: |
最后 hexo 三连
gulp 压缩
查看预览
配置
一个可以自动压缩 HTML、JS、CSS 文件、图片,可以将 ES6 语法转换成 ES5,减少网络请求,同时降低网络负担
首先全局安装 gulp
1 | npm install --global gulp-cli |
安装压缩 HTML
1 | npm install gulp-htmlclean --save-dev |
安装压缩 CSS
1 | npm install gulp-clean-css --save-dev |
安装压缩 JS
这里我选择 gulp-uglify + gulp-babel,可以把 ES6 转换成 ES5,因为兼容所以选择
1 | npm install --save-dev gulp-uglify |
安装如上插件之后,在你的博客根目录创建一个 gulpfile.js
文件并把如下代码 CV
进去
1 | var gulp = require('gulp'); |
使用:
在 hexo g 之后运行 gulp 即可
例如:
1 | hexo cl && hexo g && gulp && hexo d |
不过要注意的是,gulp 在本地运行是没有效果的,请部署之后再看效果
图片压缩
图片压缩我用的是 Imagine
根据自己系统选择下载。
使用也很简单,下载安装之后,把想压缩的图片拖进去就好
外挂标签
关于外挂标签请移步至 Akilar 的 基于 Butterfly 的外挂标签引入
此时,您的部落格整体样貌就基本和我的差不多了
友链魔改
查看预览
配置
友链这块修改了主题源码,是否要修改自行斟酌
魔改适用 Butterfly@3.6.0 +
3.3.0-3.5.1
的请看 Akilar 的原帖:Friend Link Card Beautify
修改
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修改
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
258if 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)
+maxWidth600()
width: calc(100% - 15px)
&: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
.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);在
blog\source\_data\link.yml
根据自身是否添加siteshot
,因为 Volantis 的 site-card 比 Butterfly 的 flink-card 多了一个站点缩略图,所以需要再额外添加一条siteshot
配置项,不添加也可以,通过butterfly\layout\includes\page\flink.pug
源码可以看出,如果你配置了siteshot
的话,它就走siteshot
,没有配置的话,默认就调API
,其优先级siteshot
高于API
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: # 站点缩略图在
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... # 文章图失效替换图hexo cl && hexo g && hexo s
本地调式查看效果
已知问题
相册样式错乱
解决:
在你的自定义 css
文件中,添加如下代码
1 | a > img, .justified-gallery > div > img, |
其它问题
参考:可能遇到的 Bug
友链朋友圈
GitHub 贡献度
查看预览
配置
项目地址:hexo-github-calendar
先安装插件
1 | npm i hexo-githubcalendar --save |
然后打开 Hexo 的配置文件,注:不是主题的配置文件
1 | githubcalendar: |
如果你觉得默认的浅紫色不好看,可以选择以下色调
1 | # 橘黄色调 |
也可以自己自定义
最后 hexo cl
三连命令查看效果
说说配置
前置要求,参考 Artitalk 文档 - LeanCloud 的相关准备,必须要配置好 LeanCloud 再往下看
从 Butterfly@3.7.0 开始,移除了 artitalk,改为 npm 安装的方式
在你的博客目录下安装插件
1 | npm install hexo-butterfly-artitalk |
然后手动在 butterfly 主题下的配置文件添加如下配置
1 | artitalk: |
参数 | 说明 |
---|---|
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,无需额外创建页面,主题会根据配置自动生成页面!
使用前请先确保参考林木木的教程成功配置好云函数之后再来使用
前端配置只需在你的哔哔页面的 index.md
复制如下代码并进行修改即可!
1 | <div id='speak'></speak> |
其中,云数据库名称必须为 talks
才可以
效果:
网站统计
此统计功能来自于 Eurkon
创建统计页面
1
hexo new page charts
引入
ECharts.js
,在 Butterfly 主题下的配置文件添加。(注意不是在bottom
)1
2
3inject:
head:
- <script src="https://npm.elemecdn.com/echarts@4.7.0/dist/echarts.min.js"></script>在
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
309const 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(/&#/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>`
}在
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
首页
侧边栏
请确保你已经配置好哔哔再来使用,此功能来自小康博客!
这个其实是借助了 Butterfly 3.5.0 添加的自定义侧边栏功能,可以添加自己喜欢的 widget
,参考 自定義側邊欄
在 source/_data
(如果沒有 _data 文件夹,请自行创建),创建一个文件 widget.yml
自定义侧边栏在 Butterfly@3.8.0 中写法已更改
所以自然而然教程也得更新!
添加如下代码
3.8.0 及以上版本
1 | top: |
3.5.0 - 3.8.0 版本
1 | - class_name: latestBB |
其中 latestBB
容器 class 名,不要更改
HTML 内容!
1 | <div class="swiper-container swiper-container-aside"> |
最后 Hexo 三连即可查看效果!
添加 WOW 动画效果
如需其它配置方案,可参考店长的 插件化配置方案 、外挂标签写法配置方案
在 butterfly\source\js\目录下新建 wow_init.js
,配置特性动画的默认项。
1 | wow = new WOW({ |
在主题配置文件下找到 inject
配置项,引入 css 和 js
1 | inject: |
使用
页面内写法(指 page 页面或者 posts 页面)
在需要添加动画效果的页面加上
<div class='example'><div>
1
2
3<div class="example wow animate__bounceInUp">
我是内容
</div>pug 写法
例如给首页文章卡片套上动画
1
2
3
4
5
6mixin 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 参考文档】