博客魔改内容(一)
除参考butterfly主题文档进行正常配置之外,本博客还参照一些教程进行了魔改(复制)。记录一下,以便后期搞不清时查阅。
添加fps显示
来源:博客魔改日记(3)
参考:博客魔改教程总结(四)
在主题配置文件
_config.butterfly.yml中找到inject项,插入代码。1
2
3
4
5
6head:
- <link rel="stylesheet" href="/css/fps.css?1">
# 在.css后面添加 ?1 ,在修改此文件后改成 ?2 ,用户访问网站时,不会使用本地的缓存,而是请求新的内容。没修改的话就不用动
- <span id="fps"></span> # 帧率检测
bottom:
- <script async src="/js/fps.js"></script> # 帧率检测在
/source/css文件夹下新建fps.css,插入代码。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;
}在
/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"
}
文章统计功能
来源:Hexo博客文章统计图
新建
charts页面(已删除,改到about页面去了)1
hexo new page charts
引入
ECharts.js有两种引入方式。一种是全局引用,即在
_config.butterfly.yml的inject中引入echarts.js文件。1
2
3
4inject:
head:
- <script src="https://npm.elemecdn.com/echarts@4.9.0/dist/echarts.min.js"></script>
#文章统计另一种为页面引入,即在需要引入文章统计图的页面中插入
echarts.js文件。例如,可在/source/charts/index.md中添加以下内容。1
<script src="https://npm.elemecdn.com/echarts@4.9.0/dist/echarts.min.js"></script>
本博客采用第一种方法。
文章统计代码
在
/themes/butterfly/scripts/helpers目录下新建charts.js文件,然后添加下述内容:更多属性见官方文档,可根据自行喜好对 ECharts 统计图进行修改。但不好意思,看不懂。只粘贴了现有的。
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
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397const 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')
const 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(post.attr('data-start')))
}
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(category.attr('data-parent')))
}
if (htmlEncode) {
return $.root().html().replace(/&#/g, '&#')
} else {
return $.root().html()
}
} else {
return locals
}
}, 15)
function postsChart (startMonth) {
const startDate = moment(startMonth || '2020-01')
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 color = document.documentElement.getAttribute('data-theme') === 'light' ? '#4c4948' : 'rgba(255,255,255,0.7)'
var postsChart = echarts.init(document.getElementById('posts-chart'), 'light');
var postsOption = {
title: {
text: '文章发布统计图',
x: 'center',
textStyle: {
color: color
}
},
tooltip: {
trigger: 'axis'
},
xAxis: {
name: '日期',
type: 'category',
boundaryGap: false,
nameTextStyle: {
color: color
},
axisTick: {
show: false
},
axisLabel: {
show: true,
color: color
},
axisLine: {
show: true,
lineStyle: {
color: color
}
},
data: ${monthArr}
},
yAxis: {
name: '文章篇数',
type: 'value',
nameTextStyle: {
color: color
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: true,
color: color
},
axisLine: {
show: true,
lineStyle: {
color: color
}
}
},
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',
label: {
color: color
}
}]
}
}]
};
postsChart.setOption(postsOption);
window.addEventListener('resize', () => {
postsChart.resize();
});
postsChart.on('click', 'series', (event) => {
if (event.componentType === 'series') window.location.href = '/archives/' + event.name.replace('-', '/');
});
</script>`
}
function tagsChart (len) {
const tagArr = []
hexo.locals.get('tags').map(function (tag) {
tagArr.push({ name: tag.name, value: tag.length, path: tag.path })
})
tagArr.sort((a, b) => { return b.value - a.value })
const dataLength = Math.min(tagArr.length, len) || tagArr.length
const tagNameArr = []
for (let i = 0; i < dataLength; i++) {
tagNameArr.push(tagArr[i].name)
}
const tagNameArrJson = JSON.stringify(tagNameArr)
const tagArrJson = JSON.stringify(tagArr)
return `
<script id="tagsChart">
var color = document.documentElement.getAttribute('data-theme') === 'light' ? '#4c4948' : 'rgba(255,255,255,0.7)'
var tagsChart = echarts.init(document.getElementById('tags-chart'), 'light');
var tagsOption = {
title: {
text: 'Top ${dataLength} 标签统计图',
x: 'center',
textStyle: {
color: color
}
},
tooltip: {},
xAxis: {
name: '标签',
type: 'category',
nameTextStyle: {
color: color
},
axisTick: {
show: false
},
axisLabel: {
show: true,
color: color,
interval: 0
},
axisLine: {
show: true,
lineStyle: {
color: color
}
},
data: ${tagNameArrJson}
},
yAxis: {
name: '文章篇数',
type: 'value',
splitLine: {
show: false
},
nameTextStyle: {
color: color
},
axisTick: {
show: false
},
axisLabel: {
show: true,
color: color
},
axisLine: {
show: true,
lineStyle: {
color: color
}
}
},
series: [{
name: '文章篇数',
type: 'bar',
data: ${tagArrJson},
itemStyle: {
borderRadius: [5, 5, 0, 0],
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: {
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',
label: {
color: color
}
}]
}
}]
};
tagsChart.setOption(tagsOption);
window.addEventListener('resize', () => {
tagsChart.resize();
});
tagsChart.on('click', 'series', (event) => {
if(event.data.path) window.location.href = '/' + event.data.path;
});
</script>`
}
function categoriesChart (dataParent) {
const categoryArr = []
let categoryParentFlag = false
hexo.locals.get('categories').map(function (category) {
if (category.parent) categoryParentFlag = true
categoryArr.push({
name: category.name,
value: category.length,
path: category.path,
id: category._id,
parentId: category.parent || '0'
})
})
categoryParentFlag = categoryParentFlag && dataParent === 'true'
categoryArr.sort((a, b) => { return b.value - a.value })
function translateListToTree (data, parent) {
let tree = []
let temp
data.forEach((item, index) => {
if (data[index].parentId == parent) {
let obj = data[index];
temp = translateListToTree(data, data[index].id);
if (temp.length > 0) {
obj.children = temp
}
if (tree.indexOf())
tree.push(obj)
}
})
return tree
}
const categoryNameJson = JSON.stringify(categoryArr.map(function (category) { return category.name }))
const categoryArrJson = JSON.stringify(categoryArr)
const categoryArrParentJson = JSON.stringify(translateListToTree(categoryArr, '0'))
return `
<script id="categoriesChart">
var color = document.documentElement.getAttribute('data-theme') === 'light' ? '#4c4948' : 'rgba(255,255,255,0.7)'
var categoriesChart = echarts.init(document.getElementById('categories-chart'), 'light');
var categoryParentFlag = ${categoryParentFlag}
var categoriesOption = {
title: {
text: '文章分类统计图',
x: 'center',
textStyle: {
color: color
}
},
legend: {
top: 'bottom',
data: ${categoryNameJson},
textStyle: {
color: color
}
},
tooltip: {
trigger: 'item'
},
series: []
};
categoriesOption.series.push(
categoryParentFlag ?
{
nodeClick :false,
name: '文章篇数',
type: 'sunburst',
radius: ['15%', '90%'],
center: ['50%', '55%'],
sort: 'desc',
data: ${categoryArrParentJson},
itemStyle: {
borderColor: '#fff',
borderWidth: 2,
emphasis: {
focus: 'ancestor',
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(255, 255, 255, 0.5)'
}
}
}
:
{
name: '文章篇数',
type: 'pie',
radius: [30, 80],
roseType: 'area',
label: {
color: color,
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();
});
categoriesChart.on('click', 'series', (event) => {
if(event.data.path) window.location.href = '/' + event.data.path;
});
</script>`
}在建立的charts页面使用统计图(已改到about页面)
1
2
3
4
5
6<!-- 文章发布时间统计图 -->
<div id="posts-chart" data-start="2023-01" style="border-radius: 8px; height: 300px; padding: 10px;"></div>
<!-- 文章标签统计图 -->
<div id="tags-chart" data-length="10" style="border-radius: 8px; height: 300px; padding: 10px;"></div>
<!-- 文章分类统计图 -->
<div id="categories-chart" data-parent="true" style="border-radius: 8px; height: 300px; padding: 10px;"></div>其中:
posts-chart的data-start="2023-01"属性表示文章发布时间统计图仅显示2023年1月及以后的文章数据。tags-chart的data-length="10"属性表示仅显示排名前10的标签。categories-chart的data-parent="true"属性表示有子分类时以旭日图显示分类,其他无子分类或设置为false或不设置该属性或设置为其他非true属性情况都以饼状图显示分类。
在其他页面使用统计图
本博客暂未引用,详见Hexo博客文章统计图。
随机访问一篇文章
来源:随机访问一篇文章的实现
功能主要基于baidusitemap插件实现。
在主题配置文件
_config.butterfly.yml中找到inject项,插入代码。1
2
3inject:
bottom:
- <script src="/js/randompost.js"></script> # 随机访问一篇文章在
/source/js文件夹下新建randompost.js,插入代码。1
2
3
4
5
6
7
8
9
10
11function randomPost() {
fetch('/baidusitemap.xml').then(res => res.text()).then(str => (new window.DOMParser()).parseFromString(str, "text/xml")).then(data => {
let ls = data.querySelectorAll('url loc');
while (true) {
let url = ls[Math.floor(Math.random() * ls.length)].innerHTML;
if (location.href == url) continue;
location.href = url;
return;
}
})
}在主题配置文件
_config.butterfly.yml中增加导航按钮即可。1
2menu:
随机访问: javascript:randomPost(); || fa-solid fa-shuffle
网站标题提示
来源:博客魔改教程总结(五)
在主题配置文件
_config.butterfly.yml中找到inject项,插入代码。1
2
3inject:
bottom:
- <script async src="/js/title.js"></script> #网站标题提示在
/source/js文件夹下新建title.js,插入代码。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17//动态标题
var OriginTitile = document.title;
var titleTime;
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
//离开当前页面时标签显示内容
document.title = '爱你😘~别走';
clearTimeout(titleTime);
} else {
//返回当前页面时标签显示内容
document.title = '终于等到你/(ㄒoㄒ)/~~~';
//四秒后变回正常标题
titleTime = setTimeout(function () {
document.title = OriginTitile;
}, 4000);
}
});
加载动画
打开
/themes/butterfly/layout/includes/loading/fullpage-loading.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#loading-box
.loading-left-bg
.loading-right-bg
.spinner-box
.configure-border-1
.configure-core
.configure-border-2
.configure-core
.loading-word= _p('loading')
script.
const preloader = {
endLoading: () => {
document.body.style.overflow = 'auto';
document.getElementById('loading-box').classList.add("loaded")
},
initLoading: () => {
document.body.style.overflow = '';
document.getElementById('loading-box').classList.remove("loaded")
}
}
window.addEventListener('load',()=> { preloader.endLoading() })
if (!{theme.pjax && theme.pjax.enable}) {
document.addEventListener('pjax:send', () => { preloader.initLoading() })
document.addEventListener('pjax:complete', () => { preloader.endLoading() })
}删去,改为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#loading-box(onclick='document.getElementById("loading-box").classList.add("loaded")')
.loading-bg
div.loading-img
.loading-image-dot
script.
const preloader = {
endLoading: () => {
document.body.style.overflow = 'auto';
document.getElementById('loading-box').classList.add("loaded")
},
initLoading: () => {
document.body.style.overflow = '';
document.getElementById('loading-box').classList.remove("loaded")
}
}
window.addEventListener('load',()=> { preloader.endLoading() })
if (!{theme.pjax && theme.pjax.enable}) {
document.addEventListener('pjax:send', () => { preloader.initLoading() })
document.addEventListener('pjax:complete', () => { preloader.endLoading() })
}打开
/themes/butterfly/layout/includes/loading/index.pug文件。原代码为:
1
2
3
4if theme.preloader.source === 1
include ./fullpage-loading.pug
else
include ./pace.pug删去,改为:
1
2
3
4
5
6
7if theme.preloader.source === 1
include ./fullpage-loading.pug
else if theme.preloader.source === 2
include ./pace.pug
else
include ./fullpage-loading.pug
include ./pace.pug在
/source/css中新建progress_bar.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.pace {
-webkit-pointer-events: none;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
z-index: 2000;
position: fixed;
margin: auto;
top: 10px;
left: 0;
right: 0;
height: 8px;
border-radius: 8px;
width: 4rem;
background: #eaecf2;
border: 1px #e3e8f7;
overflow: hidden;
}
.pace-inactive .pace-progress {
opacity: 0;
transition: 0.3s ease-in;
}
.pace .pace-progress {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
max-width: 200px;
position: absolute;
z-index: 2000;
display: block;
top: 0;
right: 100%;
height: 100%;
width: 100%;
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
animation: gradient 1.5s ease infinite;
background-size: 200%;
}
.pace.pace-inactive {
opacity: 0;
transition: 0.3s;
top: -8px;
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}打开
/themes/butterfly/source/css/_layout/loading.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
96if hexo-config('preloader.enable') && hexo-config('preloader.source') == 1
.loading-bg
position: fixed
z-index: 1000
width: 50%
height: 100%
background-color: var(--preloader-bg)
#loading-box
.loading-left-bg
@extend .loading-bg
.loading-right-bg
@extend .loading-bg
right: 0
.spinner-box
position: fixed
z-index: 1001
display: flex
justify-content: center
align-items: center
width: 100%
height: 100vh
.configure-border-1
position: absolute
padding: 3px
width: 115px
height: 115px
background: #ffab91
animation: configure-clockwise 3s ease-in-out 0s infinite alternate
.configure-border-2
left: -115px
padding: 3px
width: 115px
height: 115px
background: rgb(63, 249, 220)
transform: rotate(45deg)
animation: configure-xclockwise 3s ease-in-out 0s infinite alternate
.loading-word
position: absolute
color: var(--preloader-color)
font-size: 16px
.configure-core
width: 100%
height: 100%
background-color: var(--preloader-bg)
&.loaded
.loading-left-bg
transition: all .5s
transform: translate(-100%, 0)
.loading-right-bg
transition: all .5s
transform: translate(100%, 0)
.spinner-box
display: none
@keyframes configure-clockwise
0%
transform: rotate(0)
25%
transform: rotate(90deg)
50%
transform: rotate(180deg)
75%
transform: rotate(270deg)
100%
transform: rotate(360deg)
@keyframes configure-xclockwise
0%
transform: rotate(45deg)
25%
transform: rotate(-45deg)
50%
transform: rotate(-135deg)
75%
transform: rotate(-225deg)
100%
transform: rotate(-315deg)删去,改为以下代码。代码中背景颜色修改。
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
46if hexo-config('preloader')
.loading-bg
display: flex;
width: 100%;
height: 100%;
position: fixed;
background: #f5f5f5;
z-index: 1001;
opacity: 1;
transition: .3s;
#loading-box
.loading-img
width: 100px;
height: 100px;
border-radius: 50%;
margin: auto;
border: 4px solid #f0f0f2;
animation-duration: .3s;
animation-name: loadingAction;
animation-iteration-count: infinite;
animation-direction: alternate;
.loading-image-dot
width: 30px;
height: 30px;
background: #39ce42;
position: absolute;
border-radius: 50%;
border: 6px solid #fff;
top: 50%;
left: 50%;
transform: translate(18px, 24px);
&.loaded
.loading-bg
opacity: 0;
z-index: -1000;
@keyframes loadingAction
0% {
opacity: 1;
}
100% {
opacity: .4;
}在
/source/css/custom.css中新增代码,其中background中的url用于设置加载图片。1
2
3
4
5/*加载动画*/
.loading-img {
background: url(https://img.heyjian.cn/1.jpg) no-repeat center center;
background-size: cover;
}在主题配置文件
_config.butterfly.yml中找到inject项,插入代码。1
2
3inject:
head:
- <link rel="stylesheet" href="/css/custom.css?1">在主题配置文件
_config.butterfly.yml中找到preloader项。1
2
3
4
5
6
7
8preloader:
enable: true
# source
# 1. fullpage-loading
# 2. pace (progress bar)
source: 3
# pace theme (see https://codebyzach.github.io/pace/)
pace_css_url: /css/progress_bar.css其中
source: 1为满屏加载但加载图片上方无胶囊动画,source: 2为有胶囊但无满屏动画,source: 3为两者皆有。
首页文章置顶滚动轮播
来源:Swiper Bar
在本地站点根目录执行下述指令,安装插件。
1
npm install hexo-butterfly-swiper --save
在站点配置文件
_config.yml中添加下述代码。1
2
3
4
5
6
7
8
9
10
11
12
13
14swiper:
enable: true # 开关
priority: 5 #过滤器优先权,数值越小,执行越早,默认为10
enable_page: / # 填写想要应用的页面的相对路径(即路由地址),如根目录就填’/‘,分类页面就填’/categories/‘。若要应用于所有页面,就填’all’,默认为all
timemode: date #date/updated时间显示,date为显示创建日期,updated为显示更新日期,默认为date
layout: # 挂载容器类型
type: id #挂载容器类型,填写id或class,不填则默认为id
name: recent-posts #挂载容器名称
index: 0 #填0或正整数,前提是layout.type为class,因为同一页面可能有多个class,此项用来确认究竟排在第几个顺位
default_descr: 怎么可能没有描述呢!!! #默认文章描述
swiper_css: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.css #swiper css依赖
swiper_js: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.js #swiper js依赖
custom_css: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiperstyle.css # 适配主题样式补丁
custom_js: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper_init.js # swiper初始化方法使用方法
在文章
front_matter中添加swiper_index: 1即可,其中swiper_index:后的数字为非负整数,代表置顶轮播图顺序,数字越大越靠前。
右下角增加分享分页按钮以及直达底部按钮
打开
/themes/butterfly/layout/includes/rightside.pug文件,在一众when下面添加一个when。1
2
3when 'share'
button.share(type="button" title='分享链接' onclick="share()")
i.fas.fa-share-nodes在此文档下面的·#rightside·数组中添加
share函数。原代码:
1
2
3
4#rightside
- const { enable, hide, show } = theme.rightside_item_order
- const hideArray = enable ? hide && hide.split(',') : ['readmode','translate','darkmode','hideAside']
- const showArray = enable ? show && show.split(',') : ['toc','chat','comment']添加
share函数后的代码:1
2
3
4#rightside
- const { enable, hide, show } = theme.rightside_item_order
- const hideArray = enable ? hide && hide.split(',') : ['readmode','translate','darkmode','hideAside']
- const showArray = enable ? show && show.split(',') : ['toc','share','chat','comment']其中:在
hideArray里面添加会在点击齿轮按钮之后显示,在showArray里面添加按钮会直接显示。虽然,在主题配置文档
rightside_item_order中可对右下角按钮进行排序,但由于添加了自定义按钮,为了方便,直接更改此处顺序就可以对其进行排序。在主题配置文档的
inject中的bottom项里引入下述代码,其中,该处代码必须要放在自定义分享功能js文件的前面。1
2
3bottom:
- <script src="https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.11/clipboard.min.js"></script> #分享本页引入外部js,一定要在该自定义功能js的上面
- <script src="/js/custom.js"></script> #自定义分享功能js存放处在
/source/js/custom.js中插入自定义分享本页js。1
2
3
4
5
6// 分享本页
function share() {
let url = window.location.origin + window.location.pathname
new ClipboardJS(".share", { text: function() { return '标题:' + document.title + '\n链接:' + url } }); #此处可以更改,例如只复制链接,但不想改。
btf.snackbarShow("本页面信息已成功复制至剪贴板!小伙子,尽情分享去吧o(* ̄▽ ̄*)ブ")
}直达底部功能在
/themes/butterfly/layout/includes/rightside.pug文件最后添加代码。1
2button#go-down(type="button" title="直达底部" onclick="btf.scrollToDest(document.body.scrollHeight, 500)")
i.fas.fa-arrow-down
复制、粘贴、F12弹窗提醒
用f12从Butterfly右下角悬浮菜单栏魔改指南那扒来的。
由于之前已经引用了/source/js/custom.js,因此,只需要在/source/js/custom.js中插入下述代码。
1 | //f12提醒、复制提醒、粘贴提醒 |
控制台样式自定义
来源:博客魔改教程总结(四)
在已经建立并在主题配置文件中引用的
/source/js/custom.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//控制台样式自定义
var now1 = new Date();
function createtime1() {
var grt = new Date("01/14/2023 22:00:00"); //此处修改你的建站时间或者网站上线时间
now1.setTime(now1.getTime() + 250);
var days = (now1 - grt) / 1000 / 60 / 60 / 24;
var dnum = Math.floor(days);
var ascll = [
`欢迎来到jianerssr的个人小屋`,
`---便是仙禁春深,御炉香袅,临轩亲试。对天颜咫尺,定然魁甲登高第。`,
`
██╗██╗ █████╗ ███╗ ██╗███████╗██████╗ ███████╗███████╗██████╗
██║██║██╔══██╗████╗ ██║██╔════╝██╔══██╗██╔════╝██╔════╝██╔══██╗
██║██║███████║██╔██╗ ██║█████╗ ██████╔╝███████╗███████╗██████╔╝
██ ██║██║██╔══██║██║╚██╗██║██╔══╝ ██╔══██╗╚════██║╚════██║██╔══██╗
╚█████╔╝██║██║ ██║██║ ╚████║███████╗██║ ██║███████║███████║██║ ██║
╚════╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝
`,
"jianerssr的个人小屋已经运行",
dnum,
"天啦!",
"©2023 By jianerssr",
];
setTimeout(
console.log.bind(
console,
`\n%c${ascll[0]} %c ${ascll[1]} %c ${ascll[2]} %c${ascll[3]}%c ${ascll[4]}%c ${ascll[5]}\n\n%c ${ascll[6]}\n`,
"color:#3366ff",
"",
"color:#3366ff",
"color:#3366ff",
"",
"color:#3366ff",
""
)
);
}
createtime1();
// 重写console方法
console.log = function () { };
console.error = function () { };
console.warn = function () { };F12控制台处可看到效果。
文章顶部添加波浪效果
打开
/themes/butterfly/layout/includes/header/index.pug文件。找到
35行include ./post-info.pug,在其下添加下述代码。1
2
3
4
5
6
7
8
9
10
11
12if is_post() #原有
include ./post-info.pug #原有
section.main-hero-waves-area.waves-area
svg.waves-svg(xmlns='http://www.w3.org/2000/svg', xlink='http://www.w3.org/1999/xlink', viewBox='0 24 150 28', preserveAspectRatio='none', shape-rendering='auto')
defs
path#gentle-wave(d='M -160 44 c 30 0 58 -18 88 -18 s 58 18 88 18 s 58 -18 88 -18 s 58 18 88 18 v 44 h -352 Z')
g.parallax
use(href='#gentle-wave', x='48', y='0')
use(href='#gentle-wave', x='48', y='3')
use(href='#gentle-wave', x='48', y='5')
use(href='#gentle-wave', x='48', y='7')
else if is_home() #原有在
/source/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/* 波浪css */
.main-hero-waves-area {
width: 100%;
position: absolute;
left: 0;
bottom: -11px;
z-index: 5;
}
.waves-area .waves-svg {
width: 100%;
height: 5rem;
}
/* Animation */
.parallax > use {
animation: move-forever 25s cubic-bezier(0.55, 0.5, 0.45, 0.5) infinite;
}
.parallax > use:nth-child(1) {
animation-delay: -2s;
animation-duration: 7s;
fill: #f7f9febd;
}
.parallax > use:nth-child(2) {
animation-delay: -3s;
animation-duration: 10s;
fill: #f7f9fe82;
}
.parallax > use:nth-child(3) {
animation-delay: -4s;
animation-duration: 13s;
fill: #f7f9fe36;
}
.parallax > use:nth-child(4) {
animation-delay: -5s;
animation-duration: 20s;
fill: #f7f9fe;
}
/* 黑色模式背景 */
[data-theme="dark"] .parallax > use:nth-child(1) {
animation-delay: -2s;
animation-duration: 7s;
fill: #18171dc8;
}
[data-theme="dark"] .parallax > use:nth-child(2) {
animation-delay: -3s;
animation-duration: 10s;
fill: #18171d80;
}
[data-theme="dark"] .parallax > use:nth-child(3) {
animation-delay: -4s;
animation-duration: 13s;
fill: #18171d3e;
}
[data-theme="dark"] .parallax > use:nth-child(4) {
animation-delay: -5s;
animation-duration: 20s;
fill: #18171d;
}
@keyframes move-forever {
0% {
transform: translate3d(-90px, 0, 0);
}
100% {
transform: translate3d(85px, 0, 0);
}
}
/*Shrinking for mobile*/
@media (max-width: 768px) {
.waves-area .waves-svg {
height: 40px;
min-height: 40px;
}
}








