Butterfly魔改
butterfly 主题很好看,也是本站使用的主题🖼️
相信刚开始搭建博客的同学都喜欢把博客弄有个性一点✨✨✨
接下来的魔改都是基于butterfly主题。
魔改组件肯定会影响网页速度🚀~
但在魔改教程里谈性能就有点煞风景了,让我们马上开始把😘
Butterfly主题
查看教程
安装Butterfly主题
任选一种安装方式即可
在你的 Hexo 根目录里点开Git BASH
窗口1
git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly
升级方法:在主题目录下,运行git pull
在你的 Hexo 根目录里1
git clone -b master https://gitee.com/immyw/hexo-theme-butterfly.git themes/butterfly
升级方法:在主题目录下,运行git pull
此方法只支持 Hexo 5.0.0 以上版本
查看版本hexo version
通过 npm 安装并不会在 themes 里生成主题文件夹,而是在 node_modules
里生成主题文件夹
1 | npm install hexo-theme-butterfly |
升级方法:在博客根目录下,运行 npm update hexo-theme-butterfly
。
升级前请将hexo-theme-butterfly
文件夹备份,npm更新会直接覆盖成新的包。
应用butterfly主题
修改 Hexo 根目录下的 _config.yml,把主题改为 butterfly1
theme: butterfly
安装主题需要的 pug 以及 stylus 的渲染器,请下载安装:1
npm install hexo-renderer-pug hexo-renderer-stylus --save
在 hexo 的根目录创建一个文件_config.butterfly.yml
,并把主题目录
的 _config.yml 内容复制到 _config.butterfly.yml 去。( 注意: 复制的是主题的 _config.yml ,而不是 hexo 的 _config.yml)
原来的主题配置文件_config.landscape.yml
就可以删掉了
注意: 不要把主题目录的 _config.yml 删掉
以后只需要在 _config.butterfly.yml 进行配置就行。
如果使用了 _config.butterfly.yml, 配置主题的 _config.yml 将不会有效果。
hexo根目录执行hexo cl;hexo g;hexo s
然后访问:https://localhost:4000
就可以看到效果了。
查看图片
注:图片取自网络,仅用于演示
VSCode配置
查看配置
为了能在VScode的终端里启动项目,需要修改权限:https://www.xusir.fun/posts/2410032030.html
vscode终端执行get-executionpolicy
:显示RemoteSigned
说明配置成功。
标签页分类页设置和友情链接
Site配置
查看教程
在你的博客根目录中的_config.yml
文件中,找到# Site
这里将配置你的博客属性
1 | # Site |
属性 | 内容 |
---|---|
title | 博客标题 如:’小明的博客’ |
subtitle | 博客副标题 如:’万事如意-天天开心’ |
description | 描述信息,在右侧个人卡片能看到 如:’博客,小明’ |
keywords | 博客关键词,用于搜索时关联到 如:’博客,小明,小明的博客’ |
author | 博客作者 如: 小明 或 xiaoming |
language | 博客语言 如中文:zh-CN |
执行
hexo cl;hexo g;hexo s
看看效果吧
SEO优化
查看教程
配置文章链接转数字或字母
参考:https://github.com/rozbo/hexo-abbrlink1
npm install hexo-abbrlink --save
在博客根目录_config.yml
文件中找到# URL
这一栏进行修改1
2
3permalink: posts/:abbrlink/
# or
permalink: posts/:abbrlink.html
再在_config.yml
下添加如下配置1
2
3
4# abbrlink config
abbrlink:
alg: crc32 #support crc16(default) and crc32
rep: hex #support dec(default) and hex
本地搜索
查看教程
本地搜索指的是你的导航栏将有一个搜索按钮
,可以搜索你的本地博客内容
预期效果
参考:https://github.com/wzpan/hexo-generator-search
- 安装依赖
1
npm install hexo-generator-search --save
- 在
_config.yml
下添加如下配置1
2
3
4
5# 本地搜索
search:
path: search.xml
field: all
content: true - 在
_config.butterfly.yml
文件中搜索local_search
把它的enable
的值改为true
</ol>
执行
hexo cl;hexo g;hexo s
看看效果吧
Live2D
查看教程
这个插件将会在你的网站生成一个看板娘
参考:https://github.com/EYHN/hexo-helper-live2d
预期效果
安装依赖
1
2安装live2d
npm install --save hexo-helper-live2d安装模型
1
2安装模型
npm install --save live2d-widget-model-koharu在
_config.yml
添加如下配置1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# Live2D
live2d:
enable: false #开关插件版看板娘
scriptFrom: local # 默认
# scriptFrom: https://cdn.cbd.int/live2d-widget@3.x/lib/L2Dwidget.min.js # 你的自定义 url
tagMode: false # 标签模式, 是否仅替换 live2d tag标签而非插入到所有页面中
debug: false # 调试, 是否在控制台输出日志
model:
use: live2d-widget-model-koharu # npm-module package name
# use: https://unpkg.com/live2d-widget-model-koharu@1.0.5/assets/koharu.model.json # 你的自定义 url
display:
position: left #控制看板娘位置
width: 150 #控制看板娘大小
height: 300 #控制看板娘大小
mobile:
show: false # 手机中是否展示
</ol>
执行
hexo cl;hexo g;hexo s
看看效果吧
Sitemap
查看教程
参考:https://github.com/hexojs/hexo-generator-sitemap
安装依赖
1
2npm install hexo-generator-sitemap --save
npm install hexo-generator-baidu-sitemap --save-dev在
_config.yml
添加如下配置1
2
3
4
5sitemap:
path: sitemap.xml
rel: false
tags: true
categories: true
追番插件
查看教程
这个插件将会展示你bilibli追番列表的展示页
参考:https://github.com/HCLonely/hexo-bilibili-bangumi
预期效果
安装插件
1
npm install hexo-bilibili-bangumi --save
在
_config.yml
添加如下配置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# 追番插件
bangumi: # 追番设置
enable: true
path:
vmid: #必填,打开你bilibil个人主页,看浏览器上的链接https://space.bilibili.com/XXX 复制XXX的内容即可
title: '追番列表'
quote: '生命不息,追番不止!'
show: 1
lazyload: false #在`_config.butterfly.yml`中,图片懒加载`lazyload`的`enable`设为`true`
loading:
metaColor:
color:
webp:
progress:
extra_options:
key: value
cinema: # 追剧设置
enable: false
path:
vmid: #必填,同上方vmid
title: '追剧列表'
quote: '生命不息,追剧不止!'
show: 1
lazyload: true
loading:
metaColor:
color:
webp:
progress:
extra_options:
key: value在
_config.butterfly.yml
配置文件中,
找到menue
添加追番: /bangumis/index.html || fas fa-home
1
2
3
4# Menu 目錄
menu:
Home: / || fas-home
追番: /bangumis/index.html || icon-Bzhan || faa-tada
</ol>
需要执行
hexo banggumi -u
更新追番数据
执行hexo cl;hexo g;hexo banggumi -u;hexo s
看看效果吧
APlayer音乐插件
查看教程
一个全局吸底的音乐插件
参考:https://github.com/MoePlayer/hexo-tag-aplayer/blob/master/docs/README-zh_cn.md
预期效果
安装插件
1
npm install hexo-tag-aplayer --save
在
_config.yml
添加如下配置1
2
3
4# APlayer
aplayer:
meting: true
asset_inject: false在
_config.butterfly.yml
找到如下配置
把enable
的值改为true
1
2
3
4# Inject the css and script (aplayer/meting)
aplayerInject:
enable: true
per_page: true再找到
Inject
的位置,在buttom
位置添加如下代码1
2
3
4
5
6
7
8
9# Inject
inject:
head:
bottom:
# aplayer音乐 `date-id`和`date-server`配置自己的歌单id和服务商
#音乐平台: netease, tencent, kugou, xiami, baidu
#歌曲 id / 播放列表 id / 相册 id / 搜索关键字
- <div class="aplayer no-destroy" data-id="" data-server="" data-type="playlist"
data-order="list" data-fixed="true" data-preload="auto" data-autoplay="false" data-mutex="true" ></div>
hexo自定义CSS,一图流方案(安知鱼)
查看教程
一图流就是博客使用一张图片作为背景,本站即一图流效果
新建文件[Blogroot]/source/css/custom.css,在 custom.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
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365@font-face {
font-family: ZhuZiAYuanJWD;
src: url(https://npm.elemecdn.com/anzhiyu-blog@1.1.6/fonts/ZhuZiAWan.woff2);
font-display: swap;
font-weight: lighter;
}
div#menus {
font-family: "ZhuZiAYuanJWD";
}
h1#site-title {
font-family: ZhuZiAYuanJWD;
font-size: 3em ;
}
a.article-title,
a.blog-slider__title,
a.categoryBar-list-link,
h1.post-title {
font-family: ZhuZiAYuanJWD;
}
.iconfont {
font-family: "iconfont" ;
font-size: 3em;
/* 可以定义图标大小 */
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* 时间轴生肖icon */
svg.icon {
/* 这里定义svg.icon,避免和Butterfly自带的note标签冲突 */
width: 1em;
height: 1em;
/* width和height定义图标的默认宽度和高度*/
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.icon-zhongbiao::before {
color: #f7c768;
}
/* bilibli番剧插件 */
#article-container .bangumi-tab.bangumi-active {
background: var(--anzhiyu-theme);
color: var(--anzhiyu-ahoverbg);
border-radius: 10px;
}
a.bangumi-tab:hover {
text-decoration: none ;
}
.bangumi-button:hover {
background: var(--anzhiyu-theme) ;
border-radius: 10px ;
color: var(--anzhiyu-ahoverbg) ;
}
a.bangumi-button.bangumi-nextpage:hover {
text-decoration: none ;
}
.bangumi-button {
padding: 5px 10px ;
}
a.bangumi-tab {
padding: 5px 10px ;
}
svg.icon.faa-tada {
font-size: 1.1em;
}
.bangumi-info-item {
border-right: 1px solid #f2b94b;
}
.bangumi-info-item span {
color: #f2b94b;
}
.bangumi-info-item em {
color: #f2b94b;
}
/* 解决artitalk的图标问题 */
#uploadSource > svg {
width: 1.19em;
height: 1.5em;
}
/*top-img黑色透明玻璃效果移除,不建议加,除非你执着于完全一图流或者背景图对比色明显 */
#page-header:not(.not-top-img):before {
background-color: transparent ;
}
/* 首页文章卡片 */
#recent-posts > .recent-post-item {
background: rgba(255, 255, 255, 0.9);
}
/* 首页侧栏卡片 */
#aside-content .card-widget {
background: rgba(255, 255, 255, 0.9);
}
/* 文章页面正文背景 */
div#post {
background: rgba(255, 255, 255, 0.9);
}
/* 分页页面 */
div#page {
background: rgba(255, 255, 255, 0.9);
}
/* 归档页面 */
div#archive {
background: rgba(255, 255, 255, 0.9);
}
/* 标签页面 */
div#tag {
background: rgba(255, 255, 255, 0.9);
}
/* 分类页面 */
div#category {
background: rgba(255, 255, 255, 0.9);
}
/*夜间模式伪类遮罩层透明*/
[data-theme="dark"] #recent-posts > .recent-post-item {
background: #121212;
}
[data-theme="dark"] .card-widget {
background: #121212 ;
}
[data-theme="dark"] div#post {
background: #121212 ;
}
[data-theme="dark"] div#tag {
background: #121212 ;
}
[data-theme="dark"] div#archive {
background: #121212 ;
}
[data-theme="dark"] div#page {
background: #121212 ;
}
[data-theme="dark"] div#category {
background: #121212 ;
}
[data-theme="dark"] div#category {
background: transparent ;
}
/* 页脚透明 */
#footer {
background: transparent ;
}
/* 头图透明 */
#page-header {
background: transparent ;
}
#rightside > div > button {
border-radius: 5px;
}
/* 滚动条 */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-thumb {
background-color: #3b70fc;
border-radius: 2em;
}
::-webkit-scrollbar-corner {
background-color: transparent;
}
::-moz-selection {
color: #fff;
background-color: #3b70fc;
}
/* 音乐播放器 */
/* .aplayer .aplayer-lrc {
display: none !important;
} */
.aplayer.aplayer-fixed.aplayer-narrow .aplayer-body {
left: -66px ;
transition: all 0.3s;
/* 默认情况下缩进左侧66px,只留一点箭头部分 */
}
.aplayer.aplayer-fixed.aplayer-narrow .aplayer-body:hover {
left: 0 ;
transition: all 0.3s;
/* 鼠标悬停是左侧缩进归零,完全显示按钮 */
}
.aplayer.aplayer-fixed {
z-index: 999999 ;
}
/* 评论框 */
.vwrap {
box-shadow: 2px 2px 5px #bbb;
background: rgba(255, 255, 255, 0.3);
border-radius: 8px;
padding: 30px;
margin: 30px 0px 30px 0px;
}
/* 设置评论框 */
.vcard {
box-shadow: 2px 2px 5px #bbb;
background: rgba(255, 255, 255, 0.3);
border-radius: 8px;
padding: 30px;
margin: 30px 0px 0px 0px;
}
/* md网站下划线 */
#article-container a:hover {
text-decoration: none ;
}
#article-container #hpp_talk p img {
display: inline;
}
/* 404页面 */
#error-wrap {
position: absolute;
top: 40%;
right: 0;
left: 0;
margin: 0 auto;
padding: 0 1rem;
max-width: 1000px;
transform: translate(0, -50%);
}
#error-wrap .error-content {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin: 0 1rem;
height: 18rem;
border-radius: 8px;
background: var(--card-bg);
box-shadow: var(--card-box-shadow);
transition: all 0.3s;
}
#error-wrap .error-content .error-img {
box-flex: 1;
flex: 1;
height: 100%;
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
background-color: #3b70fc;
background-position: center;
background-size: cover;
}
#error-wrap .error-content .error-info {
box-flex: 1;
flex: 1;
padding: 0.5rem;
text-align: center;
font-size: 14px;
font-family: Titillium Web, "PingFang SC", "Hiragino Sans GB", "Microsoft JhengHei", "Microsoft YaHei", sans-serif;
}
#error-wrap .error-content .error-info .error_title {
margin-top: -4rem;
font-size: 9em;
}
#error-wrap .error-content .error-info .error_subtitle {
margin-top: -3.5rem;
word-break: break-word;
font-size: 1.6em;
}
#error-wrap .error-content .error-info a {
display: inline-block;
margin-top: 0.5rem;
padding: 0.3rem 1.5rem;
background: var(--btn-bg);
color: var(--btn-color);
}
#body-wrap.error .aside-list {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
bottom: 0px;
position: absolute;
padding: 1rem;
width: 100%;
overflow: scroll;
}
#body-wrap.error .aside-list .aside-list-group {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
max-width: 1200px;
margin: 0 auto;
}
#body-wrap.error .aside-list .aside-list-item {
padding: 0.5rem;
}
#body-wrap.error .aside-list .aside-list-item img {
width: 100%;
object-fit: cover;
border-radius: 12px;
}
#body-wrap.error .aside-list .aside-list-item .thumbnail {
overflow: hidden;
width: 230px;
height: 143px;
background: var(--anzhiyu-card-bg);
display: flex;
}
#body-wrap.error .aside-list .aside-list-item .content .title {
-webkit-line-clamp: 2;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
line-height: 1.5;
justify-content: center;
align-items: flex-end;
align-content: center;
padding-top: 0.5rem;
color: white;
}
#body-wrap.error .aside-list .aside-list-item .content time {
display: none;
}
/* 代码框主题 */
#article-container figure.highlight {
border-radius: 10px;
}
如果不需要一图流,请删除161行这一部分代码
1 | /* 页脚透明 */ |
在_config.butterfly.yml中搜索 Inject 添加以下代码,将自定义 csscustom.css引入1
2
3inject:
head:
- <link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'">
hexo cl;hexo g;hexo s
验证一下
现在背景变空白了是因为没有设背景
在_config.butterfly.yml
找到如下位置设置背景
1
2
3
4 # Website Background (設置网站背景)
# can set it to color or image (可設置圖片 或者 顔色)
# The formal of image: url(http://xxxxxx.com/xxx.jpg)
background: url(http://xxxxxx.com/xxx.jpg)
这个时候再hexo cl;hexo g;hexo s
就没问题了。
外挂标签
查看教程
外挂标签就是能让我们文章达到更好的浏览效果的标签
具体效果可以看我以下文章
👉外挂标签1
👉外挂标签2
参考:https://www.npmjs.com/package/hexo-butterfly-tag-plugins-plus
下载依赖
1
2
3npm install hexo-butterfly-tag-plugins-plus --save
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save添加配置项到
_config.butterfly.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# tag-plugins-plus
# see https://akilar.top/posts/615e2dec/
tag_plugins:
enable: true # 开关
priority: 5 #过滤器优先权
issues: false #issues标签开关
link:
placeholder: /img/siteicon/64.png #link_card标签默认的图标图片
CDN:
anima: https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/assets/font-awesome-animation.min.css #动画标签anima的依赖
jquery: https://cdn.cbd.int/jquery@latest/dist/jquery.min.js #issues标签依赖
issues: https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/assets/issues.js #issues标签依赖
iconfont: /js/ali_font.js #参看https://akilar.top/posts/d2ebecef/
carousel: https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/assets/carousel-touch.js
tag_plugins_css: https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/tag_plugins.css
添加wowjs特效
查看教程
wowjs就是主页各文章等元素有弹出的动画
参考:https://akilar.top/posts/abab51cf/
安装依赖
1
npm install hexo-butterfly-wowjs --save
添加配置项至
_config.butterfly.yml
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# wowjs
# see https://www.npmjs.com/package/hexo-butterfly-wowjs
wowjs:
enable: true #控制动画开关。true是打开,false是关闭
priority: 10 #过滤器优先级
mobile: false #移动端是否启用,默认移动端禁用
animateitem:
- class: recent-post-item #必填项,需要添加动画的元素的class
style: animate__zoomIn #必填项,需要添加的动画
duration: 1.5s #选填项,动画持续时间,单位可以是ms也可以是s。例如3s,700ms。
delay: 200ms #选填项,动画开始的延迟时间,单位可以是ms也可以是s。例如3s,700ms。
offset: 30 #选填项,开始动画的距离(相对浏览器底部)
iteration: 1 #选填项,动画重复的次数
- class: card-widget
style: animate__zoomIn
delay: 200ms
# - class: flink-list-card
# style: wowpanels
- class: flink-list-card
style: animate__flipInY
duration: 3s
- class: flink-list-card
style: animate__animated
duration: 3s
- class: article-sort-item
style: animate__slideInRight
duration: 1.5s
- class: site-card
style: animate__flipInY
duration: 3s
- class: site-card
style: animate__animated
duration: 3s
animate_css: https://cdn.cbd.int/hexo-butterfly-wowjs/lib/animate.min.css
wow_js: https://cdn.cbd.int/hexo-butterfly-wowjs/lib/wow.min.js
wow_init_js: https://cdn.cbd.int/hexo-butterfly-wowjs/lib/wow_init.jshexo cl;hexo g;hexo s
查看效果
留言板:薇尔莉特信封
查看教程
预期效果
- 安装插件
1
npm install hexo-butterfly-envelope --save
添加配置项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# envelope_comment
# see https://akilar.top/posts/e2d3c450/
# envelope_comment
# see https://akilar.top/posts/e2d3c450/
envelope_comment:
enable: true #控制开关
custom_pic:
cover: https://cdn.cbd.int//hexo-butterfly-envelope/lib/violet.jpg #信笺头部图片
line: https://cdn.cbd.int/hexo-butterfly-envelope/lib/line.png #信笺底部图片
beforeimg: https://cdn.cbd.int/hexo-butterfly-envelope/lib/before.png # 信封前半部分
afterimg: https://cdn.cbd.int/hexo-butterfly-envelope/lib/after.png # 信封后半部分
message: #信笺正文,多行文本,写法如下
- 有什么想问的?
- 有什么想说的?
- 有什么想吐槽的?
- 哪怕是有什么想吃的,都可以告诉我哦~
bottom: 自动书记人偶竭诚为您服务! #仅支持单行文本
height: #1050px,信封划出的高度
path: #【可选】comments 的路径名称。默认为 comments,生成的页面为 comments/index.html
front_matter: #【可选】comments页面的 front_matter 配置
title: 留言板
comments: true在
_config.butterfly.yml
的menu:
处添加目录1
2
3# Menu 目录
menu:
留言板: /comments/ || fas fa-envelope
侧边栏电子时钟(安知鱼)
查看教程
预期效果
- 安装插件,在博客根目录下打开终端,运行以下指令
1
npm install hexo-butterfly-clock-anzhiyu --save
- 添加配置信息到
_config.butterfly.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21# electric_clock
# see https://blog.anheyu.com/posts/fc18.html
electric_clock:
enable: true # 开关
priority: 5 #过滤器优先权
enable_page: all # 应用页面
exclude:
# - /posts/
# - /about/
layout: # 挂载容器类型
type: class
name: sticky_layout
index: 0
loading: https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu@1.1.6/lib/loading.gif #加载动画自定义
clock_css: https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu@1.1.6/lib/clock.min.css
clock_js: https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu@1.1.6/lib/clock.min.js
ip_api: https://widget.qweather.net/simple/static/js/he-simple-common.js?v=2.0
qweather_key: # 和风天气key
gaud_map_key: # 高得地图web服务key
default_rectangle: true # 开启后将一直显示rectangle位置的天气,否则将获取访问者的地理位置与天气
rectangle: 112.6534116,27.96920845 # 获取访问者位置失败时会显示该位置的天气,同时该位置为开启default_rectangle后的位置
添加fps帧率显示
查看教程
预期效果
新建文件[BlogRoot]\source\js\fps.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
51if (window.localStorage.getItem("fpson") == undefined || window.localStorage.getItem("fpson") == "1") {
var rAF = function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
}
);
}();
var frame = 0;
var allFrameCount = 0;
var lastTime = Date.now();
var lastFameTime = Date.now();
var loop = function () {
var now = Date.now();
var fs = (now - lastFameTime);
var fps = Math.round(1000 / fs);
lastFameTime = now;
// 不置 0,在动画的开头及结尾记录此值的差值算出 FPS
allFrameCount++;
frame++;
if (now > 1000 + lastTime) {
var fps = Math.round((frame * 1000) / (now - lastTime));
if (fps <= 5) {
var kd = `<span style="color:#bd0000">卡成ppt🤢</span>`
} else if (fps <= 15) {
var kd = `<span style="color:red">电竞级帧率😖</span>`
} else if (fps <= 25) {
var kd = `<span style="color:orange">有点难受😨</span>`
} else if (fps < 35) {
var kd = `<span style="color:#9338e6">不太流畅🙄</span>`
} else if (fps <= 45) {
var kd = `<span style="color:#08b7e4">还不错哦😁</span>`
} else {
var kd = `<span style="color:#39c5bb">十分流畅🤣</span>`
}
document.getElementById("fps").innerHTML = `FPS:${fps} ${kd}`;
frame = 0;
lastTime = now;
};
rAF(loop);
}
loop();
} else {
document.getElementById("fps").style = "display:none!important"
}
在自定义样式文件custom.css
中加入如下代码,我这里让这块东西在左下角,你可以自己指定位置,其中backdrop-filter
过滤器也可以自己指定,也可以不要:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20/* 帧率检测 */
#fps {
position: fixed;
/* 指定位置 */
left: 10px;
bottom: 10px;
z-index: 1919810;
}
[data-theme="light"] #fps {
background-color: rgba(255, 255, 255, 0.85);
backdrop-filter: var(--backdrop-filter);
padding: 4px;
border-radius: 4px;
}
[data-theme="dark"] #fps {
background-color: rgba(0, 0, 0, 0.72);
backdrop-filter: var(--backdrop-filter);
padding: 4px;
border-radius: 4px;
}
在主题配置文件_config.butterfly.yml
文件中加入以下代码:1
2
3
4
5inject:
head:
+ - <span id="fps"></span> # 帧率检测
bottom:
+ - <script async src="/js/fps.js"></script> # 帧率检测
重启项目看看角落有没有出现帧率块1
hexo cl; hexo s
打赏按钮投币彩蛋效果
查看教程
预期效果
修改[Blogroot]\themes\butterfly\languages\zh-CN.yml
1
2
3
4
5
6
7
8
9
10date_suffix:
just: 刚刚
min: 分钟前
hour: 小时前
day: 天前
month: 个月前
- donate: 打赏
+ donate: 不给糖果就捣蛋
share: 分享
修改[Blogroot]\themes\butterfly\layout\includes\post\reward.pug
,整体替换为以下内容:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21link(rel='stylesheet' href=url_for(theme.CDN.option.coin_css) media="defer" onload="this.media='all'")
.post-reward
button.tip-button.reward-button
span.tip-button__text= _p('donate')
.coin-wrapper
.coin
.coin__middle
.coin__back
.coin__front
.reward-main
ul.reward-all
each item in theme.reward.QR_code
- var clickTo = (item.itemlist||item).link ? (item.itemlist||item).link : (item.itemlist||item).img
li.reward-item
a(href=clickTo target='_blank')
img.post-qr-code-img(src=url_for((item.itemlist||item).img) alt=(item.itemlist||item).text)
.post-qr-code-desc=(item.itemlist||item).text
if theme.reward.coinAudio
- var coinAudio = theme.reward.coinAudio ? url_for(theme.reward.coinAudio) : 'https://cdn.cbd.int/akilar-candyassets@1.0.36/audio/coin.mp3'
audio#coinAudio(src=coinAudio)
script(defer src=url_for(theme.CDN.option.coin_js))
新建[Blogroot]source\css\coin\coin.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.tip-button {
border: 0;
border-radius: 0.25rem;
cursor: pointer;
font-size: 20px;
font-weight: 600;
height: 2.6rem;
margin-bottom: -4rem;
outline: 0;
position: relative;
top: 0;
transform-origin: 0% 100%;
transition: transform 50ms ease-in-out;
width: auto;
-webkit-tap-highlight-color: transparent;
}
.tip-button:active {
transform: rotate(4deg);
}
.tip-button.clicked {
animation: 150ms ease-in-out 1 shake;
pointer-events: none;
}
.tip-button.clicked .tip-button__text {
opacity: 0;
transition: opacity 100ms linear 200ms;
}
.tip-button.clicked::before {
height: 0.5rem;
width: 60%;
background: $button-hover-color;
}
.tip-button.clicked .coin {
transition: margin-bottom 1s linear 200ms;
margin-bottom: 0;
}
.tip-button.shrink-landing::before {
transition: width 200ms ease-in;
width: 0;
}
.tip-button.coin-landed::after {
opacity: 1;
transform: scale(1);
transform-origin: 50% 100%;
}
.tip-button.coin-landed .coin-wrapper {
background: radial-gradient(circle at 35% 97%, rgba(3, 16, 50, 0.4) 0.04rem, transparent 0.04rem), radial-gradient(
circle at 45% 92%,
rgba(3, 16, 50, 0.4) 0.04rem,
transparent 0.02rem
), radial-gradient(circle at 55% 98%, rgba(3, 16, 50, 0.4) 0.04rem, transparent 0.04rem), radial-gradient(circle at
65% 96%, rgba(3, 16, 50, 0.4) 0.06rem, transparent 0.06rem);
background-position: center bottom;
background-size: 100%;
bottom: -1rem;
opacity: 0;
transform: scale(2) translateY(-10px);
}
.tip-button__text {
color: #fff;
margin-right: 1.8rem;
opacity: 1;
position: relative;
transition: opacity 100ms linear 500ms;
z-index: 3;
}
.tip-button::before {
border-radius: 0.25rem;
bottom: 0;
content: "";
display: block;
height: 100%;
left: 50%;
position: absolute;
transform: translateX(-50%);
transition: height 250ms ease-in-out 400ms, width 250ms ease-in-out 300ms;
width: 100%;
z-index: 2;
}
.tip-button::after {
bottom: -1rem;
color: white;
content: "ヾ(≧O≦)〃嗷~"; /*点击后显示的内容*/
height: 110%;
left: 0;
opacity: 0;
position: absolute;
pointer-events: none;
text-align: center;
transform: scale(0);
transform-origin: 50% 20%;
transition: transform 200ms cubic-bezier(0, 0, 0.35, 1.43);
width: 100%;
z-index: 1;
}
.coin-wrapper {
background: none;
bottom: 0;
height: 18rem;
left: 0;
opacity: 1;
overflow: hidden;
pointer-events: none;
position: absolute;
transform: none;
transform-origin: 50% 100%;
transition: opacity 200ms linear 100ms, transform 300ms ease-out;
width: 100%;
}
.coin {
--front-y-multiplier: 0;
--back-y-multiplier: 0;
--coin-y-multiplier: 0;
--coin-x-multiplier: 0;
--coin-scale-multiplier: 0;
--coin-rotation-multiplier: 0;
--shine-opacity-multiplier: 0.4;
--shine-bg-multiplier: 50%;
bottom: calc(var(--coin-y-multiplier) * 1rem - 3.5rem);
height: 3.5rem;
margin-bottom: 3.05rem;
position: absolute;
right: calc(var(--coin-x-multiplier) * 34% + 16%);
transform: translateX(50%) scale(calc(0.4 + var(--coin-scale-multiplier))) rotate(calc(var(
--coin-rotation-multiplier
) * -1deg));
transition: opacity 100ms linear 200ms;
width: 3.5rem;
z-index: 3;
}
.coin__front,
.coin__middle,
.coin__back,
.coin::before,
.coin__front::after,
.coin__back::after {
border-radius: 50%;
box-sizing: border-box;
height: 100%;
left: 0;
position: absolute;
width: 100%;
z-index: 3;
}
.coin__front {
background: radial-gradient(circle at 50% 50%, transparent 50%, rgba(115, 124, 153, 0.4) 54%, #c2cadf 54%),
linear-gradient(210deg, #8590b3 32%, transparent 32%), linear-gradient(150deg, #8590b3 32%, transparent 32%),
linear-gradient(to right, #8590b3 22%, transparent 22%, transparent 78%, #8590b3 78%), linear-gradient(
to bottom,
#fcfaf9 44%,
transparent 44%,
transparent 65%,
#fcfaf9 65%,
#fcfaf9 71%,
#8590b3 71%
), linear-gradient(to right, transparent 28%, #fcfaf9 28%, #fcfaf9 34%, #8590b3 34%, #8590b3 40%, #fcfaf9 40%, #fcfaf9
47%, #8590b3 47%, #8590b3 53%, #fcfaf9 53%, #fcfaf9 60%, #8590b3 60%, #8590b3 66%, #fcfaf9 66%, #fcfaf9 72%, transparent
72%);
background-color: #8590b3;
background-size: 100% 100%;
transform: translateY(calc(var(--front-y-multiplier) * 0.3181818182rem / 2)) scaleY(var(--front-scale-multiplier));
}
.coin__front::after {
background: rgba(0, 0, 0, 0.2);
content: "";
opacity: var(--front-y-multiplier);
}
.coin__middle {
background: #737c99;
transform: translateY(calc(var(--middle-y-multiplier) * 0.3181818182rem / 2)) scaleY(var(--middle-scale-multiplier));
}
.coin__back {
background: radial-gradient(circle at 50% 50%, transparent 50%, rgba(115, 124, 153, 0.4) 54%, #c2cadf 54%),
radial-gradient(circle at 50% 40%, #fcfaf9 23%, transparent 23%), radial-gradient(circle at 50% 100%, #fcfaf9 35%, transparent
35%);
background-color: #8590b3;
background-size: 100% 100%;
transform: translateY(calc(var(--back-y-multiplier) * 0.3181818182rem / 2)) scaleY(var(--back-scale-multiplier));
}
.coin__back::after {
background: rgba(0, 0, 0, 0.2);
content: "";
opacity: var(--back-y-multiplier);
}
.coin::before {
background: radial-gradient(circle at 25% 65%, transparent 50%, rgba(255, 255, 255, 0.9) 90%), linear-gradient(55deg, transparent
calc(var(--shine-bg-multiplier) + 0%), #e9f4ff calc(var(--shine-bg-multiplier) + 0%), transparent calc(var(
--shine-bg-multiplier
) + 50%));
content: "";
opacity: var(--shine-opacity-multiplier);
transform: translateY(calc(var(--middle-y-multiplier) * 0.3181818182rem / -2)) scaleY(var(--middle-scale-multiplier))
rotate(calc(var(--coin-rotation-multiplier) * 1deg));
z-index: 10;
}
.coin::after {
background: #737c99;
content: "";
height: 0.3181818182rem;
left: 0;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%;
z-index: 2;
}
@keyframes shake {
0% {
transform: rotate(4deg);
}
66% {
transform: rotate(-4deg);
}
100% {
transform: rotate();
}
}
新建[Blogroot]\source\js\coin\coin.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
90var tipButtons = document.querySelectorAll(".tip-button");
function coinAudio() {
var coinAudio = document.getElementById("coinAudio");
if (coinAudio) {
coinAudio.play(); //有音频时播放
}
}
// Loop through all buttons (allows for multiple buttons on page)
tipButtons.forEach(button => {
var coin = button.querySelector(".coin");
// The larger the number, the slower the animation
coin.maxMoveLoopCount = 90;
button.addEventListener("click", () => {
if (/Android|webOS|BlackBerry/i.test(navigator.userAgent)) return true; //媒体选择
if (button.clicked) return;
button.classList.add("clicked");
// Wait to start flipping th coin because of the button tilt animation
setTimeout(() => {
// Randomize the flipping speeds just for fun
coin.sideRotationCount = Math.floor(Math.random() * 5) * 90;
coin.maxFlipAngle = (Math.floor(Math.random() * 4) + 3) * Math.PI;
button.clicked = true;
flipCoin();
coinAudio();
}, 50);
});
var flipCoin = () => {
coin.moveLoopCount = 0;
flipCoinLoop();
};
var resetCoin = () => {
coin.style.setProperty("--coin-x-multiplier", 0);
coin.style.setProperty("--coin-scale-multiplier", 0);
coin.style.setProperty("--coin-rotation-multiplier", 0);
coin.style.setProperty("--shine-opacity-multiplier", 0.4);
coin.style.setProperty("--shine-bg-multiplier", "50%");
coin.style.setProperty("opacity", 1);
// Delay to give the reset animation some time before you can click again
setTimeout(() => {
button.clicked = false;
}, 300);
};
var flipCoinLoop = () => {
coin.moveLoopCount++;
var percentageCompleted = coin.moveLoopCount / coin.maxMoveLoopCount;
coin.angle = -coin.maxFlipAngle * Math.pow(percentageCompleted - 1, 2) + coin.maxFlipAngle;
// Calculate the scale and position of the coin moving through the air
coin.style.setProperty("--coin-y-multiplier", -11 * Math.pow(percentageCompleted * 2 - 1, 4) + 11);
coin.style.setProperty("--coin-x-multiplier", percentageCompleted);
coin.style.setProperty("--coin-scale-multiplier", percentageCompleted * 0.6);
coin.style.setProperty("--coin-rotation-multiplier", percentageCompleted * coin.sideRotationCount);
// Calculate the scale and position values for the different coin faces
// The math uses sin/cos wave functions to similate the circular motion of 3D spin
coin.style.setProperty("--front-scale-multiplier", Math.max(Math.cos(coin.angle), 0));
coin.style.setProperty("--front-y-multiplier", Math.sin(coin.angle));
coin.style.setProperty("--middle-scale-multiplier", Math.abs(Math.cos(coin.angle), 0));
coin.style.setProperty("--middle-y-multiplier", Math.cos((coin.angle + Math.PI / 2) % Math.PI));
coin.style.setProperty("--back-scale-multiplier", Math.max(Math.cos(coin.angle - Math.PI), 0));
coin.style.setProperty("--back-y-multiplier", Math.sin(coin.angle - Math.PI));
coin.style.setProperty("--shine-opacity-multiplier", 4 * Math.sin((coin.angle + Math.PI / 2) % Math.PI) - 3.2);
coin.style.setProperty("--shine-bg-multiplier", -40 * (Math.cos((coin.angle + Math.PI / 2) % Math.PI) - 0.5) + "%");
// Repeat animation loop
if (coin.moveLoopCount < coin.maxMoveLoopCount) {
if (coin.moveLoopCount === coin.maxMoveLoopCount - 6) button.classList.add("shrink-landing");
window.requestAnimationFrame(flipCoinLoop);
} else {
button.classList.add("coin-landed");
coin.style.setProperty("opacity", 0);
setTimeout(() => {
button.classList.remove("clicked", "shrink-landing", "coin-landed");
setTimeout(() => {
resetCoin();
}, 300);
}, 1500);
}
};
});
修改_config.butterfly.yml
,添加音频文件配置项,添加 CDN 配置项:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 # Sponsor/reward
reward:
enable: true
+ coinAudio: https://cdn.cbd.int/akilar-candyassets@1.0.36/audio/aowu.m4a
QR_code:
- img: https://npm.elemecdn.com/anzhiyu-blog@1.1.6/img/post/common/qrcode-weichat.png
link:
text: wechat
- img: https://npm.elemecdn.com/anzhiyu-blog@1.1.6/img/post/common/qrcode-alipay.png
link:
text: alipay
# CDN
CDN:
internal_provider: local
third_party_provider: jsdelivr
version: true
custom_format:
option:
+ # 打赏按钮投币效果
+ coin_js: /js/coin/coin.js
+ coin_css: /css/coin/coin.css
现在的打赏按钮样式需要稍作适配,当前若提示语太长,悬停时会无法显示完全。需要微调一下,修改[Blogroot]\themes\butterfly\source\css\_layout\reward.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.post-reward
position: relative
margin-top: 4rem
width: 100%
text-align: center
.reward-button
display: inline-block
padding: .2rem 1.2rem
background: var(--btn-bg)
color: var(--btn-color)
cursor: pointer
transition: all .4s
&:hover
box-shadow: inset 15em 0 0 0 var(--btn-hover-color)
.reward-main
display: block
.reward-main
position: absolute
bottom: 40px
left: -25%
z-index: 100
display: none
padding: 0 0 15px
width: 150%
.reward-all
display: inline-block
margin: 0
padding: 1rem .5rem
border-radius: 4px
background: var(--reward-pop)
&:before
position: absolute
bottom: -10px
left: 0
width: 100%
height: 20px
content: ''
&:after
position: absolute
right: 0
bottom: 2px
left: 0
margin: 0 auto
width: 0
height: 0
border-top: 13px solid var(--reward-pop)
border-right: 13px solid transparent
border-left: 13px solid transparent
content: ''
.reward-item
display: inline-block
padding: 0 8px
list-style-type: none
vertical-align: top
img
width: 130px
height: 130px
.post-qr-code-desc
padding-top: .4rem
width: 130px
color: $reward-pop-up-color
首页分类磁贴(小冰)
打开教程
这个插件主要实现了以下功能:
- 自定义 tags 或 categories 的排列和展示
- 自定义 tags 或 categories 的展示图标,名称
- 自定义排列的行数,默认 2 行
效果预览
在博客根目录[BlogRoot]
下打开终端,运行以下指令:1
npm i hexo-magnet --save
在网站配置文件_config.yml
新增以下项 (注意不是主题配置文件),这里的分类名字必须和你文章的分类名字一一对应: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
36magnet:
enable: true
priority: 1
enable_page: /
type: categories
devide: 2
display:
- name: 教程
display_name: 小冰の魔改教程
icon: 📚
- name: 游戏评测
display_name: 小冰の游戏评测
icon: 🎮
- name: 生活趣闻
display_name: 小冰の生活趣闻
icon: 🐱👓
- name: vue
display_name: 小冰の编程学习
icon: 👩💻
- name: 学习
display_name: 小冰の读书笔记
icon: 📒
- name: 随想
display_name: 小冰の胡思乱想
icon: 💡
color_setting:
text_color: black
text_hover_color: white
background_color: "#f2f2f2"
background_hover_color: "#b30070"
layout:
type: id
name: recent-posts
index: 0
temple_html: '<div class="recent-post-item" style="width:100%;height: auto"><div id="catalog_magnet">${temple_html_item}</div></div>'
plus_style: ""
黑夜模式的颜色适配,在custom.css
文件中添加以下代码适配黑夜模式(具体颜色可以自己调节):1
2
3
4
5
6
7
8
9
10
11/* 小冰分类分类磁铁黑夜模式适配 */
/* 一般状态 */
[data-theme="dark"] .magnet_link_context {
background: #1e1e1e;
color: antiquewhite;
}
/* 鼠标悬浮状态 */
[data-theme="dark"] .magnet_link_context:hover {
background: #3ecdf1;
color: #f2f2f2;
}
名字 | 参数 | 含义 |
---|---|---|
enable | true/false | 是否开启插件 |
enable_page | / | 路由地址,如 / 代表主页。/me/ 代表自我介绍页等等 |
priority | 1 | 插件的叠放顺序,数字越大,叠放约靠前。 |
type | categories/tags | 选择筛选分类还是标签 |
devide | 2 | 表示分隔的列数,2 表示分为两列展示 |
display
项 含义:配置项,可自行设置,按照设置的顺序展示
参数名字 | 参数 | 含义 |
---|---|---|
name | text | tags或者categories的名称 |
display_name | XXの魔改教程 | 替换的名称 |
icon | 📚/🎮/🐱👓/👩💻 | 展示的图标 |
color_setting
项 含义:颜色配置项,可自行设置
参数名字 | 参数 | 含义 |
---|---|---|
text_color | black | 文字默认颜色 |
text_hover_color | white | 文字鼠标悬浮颜色 |
background_color | “#f2f2f2” | 文字背景默认颜色 |
background_hover_color | “#b30070” | 文字背景悬浮颜色 |
layout
项 含义:如果说 magnet 是一幅画,那么这个 layout 就是指定了哪面墙来挂画
而在 HTML 的是世界里有两种墙分别 type 为 id 和 class。
其中在定义 class 的时候会出现多个 class 的情况,这时就需要使用 index,确定是哪一个。
最后墙的名字即是 name;
参数名字 | 参数 | 含义 |
---|---|---|
type; | (class&id) | |
name; | ||
index | (数字) |
1 | <div name="我是墙" id="recent-posts"> |
temple_html
参数:html 模板字段
含义:包含挂载容器1
2
3
4
5<div class="recent-post-item" style="width:100%;height: auto"> <!--文章容器-->
<div id="catalog_magnet"> <!--挂载容器-->
${temple_html_item}
</div>
</div>
plus_style
参数:“”
含义:提供可自定义的 style,如加入黑夜模式。
星空背景和流星特效
打开教程
图片中的星光和流星 效果预览
在[BlogRoot]/source/js
目录下新建universe.js
,输入以下代码:1
2function dark() {window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame;var n,e,i,h,t=.05,s=document.getElementById("universe"),o=!0,a="180,184,240",r="226,225,142",d="226,225,224",c=[];function f(){n=window.innerWidth,e=window.innerHeight,i=.216*n,s.setAttribute("width",n),s.setAttribute("height",e)}function u(){h.clearRect(0,0,n,e);for(var t=c.length,i=0;i<t;i++){var s=c[i];s.move(),s.fadeIn(),s.fadeOut(),s.draw()}}function y(){this.reset=function(){this.giant=m(3),this.comet=!this.giant&&!o&&m(10),this.x=l(0,n-10),this.y=l(0,e),this.r=l(1.1,2.6),this.dx=l(t,6*t)+(this.comet+1-1)*t*l(50,120)+2*t,this.dy=-l(t,6*t)-(this.comet+1-1)*t*l(50,120),this.fadingOut=null,this.fadingIn=!0,this.opacity=0,this.opacityTresh=l(.2,1-.4*(this.comet+1-1)),this.do=l(5e-4,.002)+.001*(this.comet+1-1)},this.fadeIn=function(){this.fadingIn&&(this.fadingIn=!(this.opacity>this.opacityTresh),this.opacity+=this.do)},this.fadeOut=function(){this.fadingOut&&(this.fadingOut=!(this.opacity<0),this.opacity-=this.do/2,(this.x>n||this.y<0)&&(this.fadingOut=!1,this.reset()))},this.draw=function(){if(h.beginPath(),this.giant)h.fillStyle="rgba("+a+","+this.opacity+")",h.arc(this.x,this.y,2,0,2*Math.PI,!1);else if(this.comet){h.fillStyle="rgba("+d+","+this.opacity+")",h.arc(this.x,this.y,1.5,0,2*Math.PI,!1);for(var t=0;t<30;t++)h.fillStyle="rgba("+d+","+(this.opacity-this.opacity/20*t)+")",h.rect(this.x-this.dx/4*t,this.y-this.dy/4*t-2,2,2),h.fill()}else h.fillStyle="rgba("+r+","+this.opacity+")",h.rect(this.x,this.y,this.r,this.r);h.closePath(),h.fill()},this.move=function(){this.x+=this.dx,this.y+=this.dy,!1===this.fadingOut&&this.reset(),(this.x>n-n/4||this.y<0)&&(this.fadingOut=!0)},setTimeout(function(){o=!1},50)}function m(t){return Math.floor(1e3*Math.random())+1<10*t}function l(t,i){return Math.random()*(i-t)+t}f(),window.addEventListener("resize",f,!1),function(){h=s.getContext("2d");for(var t=0;t<i;t++)c[t]=new y,c[t].reset();u()}(),function t(){document.getElementsByTagName('html')[0].getAttribute('data-theme')=='dark'&&u(),window.requestAnimationFrame(t)}()};
dark()
在[BlogRoot]/source/css
目录下新建universe.css
,输入以下代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/* 背景宇宙星光 */
#universe{
display: block;
position: fixed;
margin: 0;
padding: 0;
border: 0;
outline: 0;
left: 0;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
/* 这个是调置顶的优先级的,-1在文章页下面,背景上面,个人推荐这种 */
z-index: -1;
}
在主题配置文件_config.butterfly.yml
的inject
配置项中bottom
下填入:1
2
3
4inject:
bottom:
- <canvas id="universe"></canvas>
- <script defer src="/js/universe.js"></script>
在主题配置文件_config.butterfly.yml
的inject
配置项中head
下填入:1
2
3inject:
head:
- <link rel="stylesheet" href="/css/universe.css">
重新编译即可看到效果。