NexT 8.20 升级日志

博客的升级日志,这次的调整比较少,只有简简单单的刷新了一下版本号,然后提升了一丢丢的阅读体验。

升级内容

  • 升级Hexo版本:6.3.0 → 7.3.0
  • 升级NexT版本:8.18.2 → 8.20.0
  • 更换网站图标
  • 更换字体
  • 根据浏览器主题自动切换背景图片
  • 调整归档、目录、标签页的分页设置
  • 重定向部分URL
  • 移除移动端点击特效
  • 加入图片轮播功能

NPM包升级

这次升级发现了一个挺好用的包npm-check-updates,它可以检测有哪些包可以升级。

安装命令:

1
npm i -g npm-check-updates

检测可升级的包:

1
ncu -u

我的输出如下:

1
2
3
4
5
6
7
8
9
hexo                   ^6.3.0  →   ^7.3.0
hexo-blog-encrypt ^3.1.6 → ^3.1.9
hexo-deployer-git ^3.0.0 → ^4.0.0
hexo-generator-index ^3.0.0 → ^4.0.0
hexo-hide-posts ^0.2.0 → ^0.4.3
hexo-renderer-marked ^6.0.0 → ^6.3.0
hexo-renderer-stylus ^2.1.0 → ^3.0.1
hexo-theme-next ^8.18.2 → ^8.20.0
hexo-word-counter ^0.1.0 → ^0.2.0

直接升级所有组件:

1
sudo npm install

更新配置文件

已经好几年没有更新过NexT的配置文件了,虽然不怎么影响使用,但是强迫症有些难受。

  1. ./_config.next.yml重命名为./_old_next_config.yml
  2. ./node_modules/hexo-theme-next/_config.yml复制到博客根目录,然后重命名为_config.next.yml
  3. 在vscode中打开两个文件,按住shift选择两个文件,右键单击文件标签,选择将已选项进行比较,然后复制粘贴。

更换网站图标

单纯的审美疲劳了,想换一个图片.

  1. 去PS里瞎画一个,然后导出一个分辨率高一点的图片。
  2. 将它上传到 Favicon Generator就可以生成所有需要的图标。
  3. 将生成的图片放到./source/images/路径下,替换原有图片。
  4. 注意将./_config.next.yml中的android_manifest改成/images/site.webmanifest,因为网站自动生成的文件名不同。

更换网站字体

将网站的全局字体换成了无衬线的思源黑体,博客正文部分还是更加适合阅读的思源宋体。在./_config.next.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
# Font options:
# `external: true` will load this font family from `host` above.
# `family: Times New Roman`. Without any quotes.
# `size: x.x`. Use `em` as unit. Default: 1 (16px)

# Global font settings used for all elements inside <body>.
global:
external: true
family: Noto Sans
size:

# Font settings for site title (.site-title).
title:
external: true
family:
size:

# Font settings for headlines (<h1> to <h6>).
headings:
external: true
family:
size:

# Font settings for posts (.post-body).
posts:
external: true
family: Noto Serif SC

# Font settings for <code> and code blocks.
codes:
external: true
family: Fira Code, Noto Serif SC

背景图片调整

更换原因同上,审美疲劳了。调整如下:

  1. 原有的背景图片太亮了,在深色模式下不太协调,特别是深夜看时有些刺眼,索性就为浅色/深色两种模式设置了不同的背景图片。
  2. 取消了背景图片的半透明显示,让文字更加易读。
  3. 取消了移动端的渐变背景。

D:\Project\Blog\cn_Siriusq\source\_data\styles.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
// 背景图片
/* 桌面端背景图片设置 */
@media screen and (min-width: 768px) {
/* 亮模式背景 */
@media (prefers-color-scheme: light) {
body {
background-image: url('https://s2.loli.net/2024/09/11/ZyWBVcA5F2bodgw.webp');
background-repeat: no-repeat;//是否重复平铺
background-attachment: fixed;//是否随着网页上下滚动而滚动,fixed为固定
background-size: cover;//图片展示大小
background-position: center;//图片位置
-webkit-background-size: cover;
-o-background-size: cover;
-moz-background-size: cover;
-ms-background-size: cover;
footer > div > div {
color:#ffffff;//底部文字颜色
}
}
}

/* 暗模式背景 */
@media (prefers-color-scheme: dark) {
body {
background-image: url('https://s2.loli.net/2024/09/11/YHxg9RsTUDKvBPr.webp');
background-repeat: no-repeat;//是否重复平铺
background-attachment: fixed;//是否随着网页上下滚动而滚动,fixed为固定
background-size: cover;//图片展示大小
background-position: center;//图片位置
-webkit-background-size: cover;
-o-background-size: cover;
-moz-background-size: cover;
-ms-background-size: cover;
footer > div > div {
color:#dddddd;//底部文字颜色
}
}
}
}

/* 移动端不显示背景图片 */
@media screen and (max-width: 767px) {
body {
background-image: none;
}
}

页面分页调整

开启动画时,NexT主题会通过类似瀑布的动画来渐显页面中的元素,也包括归档等页中的博文标题,这样就会导致一个问题:如果一页中显示的标题太多,靠后的标题就需要等待动画播放完成后才能显示,我原来设置的一页显示50个标题,等待动画播放完成需要花费数秒,不太方便,这次就统一设置成一页只显示20个标题。

在Hexo的配置文件_config.yml中调整以下设置:

1
2
3
4
5
6
7
8
9
10
11
# Archive Pagination
archive_generator:
per_page: 20

# Tag Pagination
tag_generator:
per_page: 20

# Category Pagination
category_generator:
per_page: 20

URL重定向

目前博客的URL是根据markdown文件的文件名生成的,有几个文件的名字我很久之前就想改了,但是直接改的话会造成原有的URL变成死链,于是安装了hexo-generator-alias插件来解决这个问题。

安装命令:

1
npm install hexo-generator-alias --save

使用方法:

  1. 重命名相关的markdown文件。
  2. 打开文件,在front-matter部分添加alias: [markdown文件旧名字的相对路径].html

示例:
我的老文件名为Win10重装指北.md,先将它重命名为Windows重装指北.md,然后打开文件并修改:

1
2
3
4
5
6
7
8
---
title: Windows重装指北
date: 2020-07-13 12:28:34
lang: zh-CN
tags: [Win10,Office,重装]
categories: Windows
+ alias: Win10重装指北.html
---

移除移动端点击特效

目前的点击特效在移动端上比较卡顿,就先移除它,等过几年移动端设备性能涨一涨再加回来。在原有的./source/js/firework.js中找到CursorSpecialEffects类,向其中的init方法添加一个条件语句if (window.innerWidth > 768){}然后将原有内容移入其中即可。

完整文件

./source/js/firework.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
class Circle {
constructor({ origin, speed, color, angle, context }) {
this.origin = origin
this.position = { ...this.origin }
this.color = color
this.speed = speed
this.angle = angle
this.context = context
this.renderCount = 0
}

draw() {
this.context.fillStyle = this.color
this.context.beginPath()
this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2)
this.context.fill()
}

move() {
this.position.x = (Math.sin(this.angle) * this.speed) + this.position.x
this.position.y = (Math.cos(this.angle) * this.speed) + this.position.y + (this.renderCount * 0.3)
this.renderCount++
}
}

class Boom {
constructor ({ origin, context, circleCount = 16, area }) {
this.origin = origin
this.context = context
this.circleCount = circleCount
this.area = area
this.stop = false
this.circles = []
}

randomArray(range) {
const length = range.length
const randomIndex = Math.floor(length * Math.random())
return range[randomIndex]
}

randomColor() {
const range = ['8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
return '#' + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range)
}

randomRange(start, end) {
return (end - start) * Math.random() + start
}

init() {
for(let i = 0; i < this.circleCount; i++) {
const circle = new Circle({
context: this.context,
origin: this.origin,
color: this.randomColor(),
angle: this.randomRange(Math.PI - 1, Math.PI + 1),
speed: this.randomRange(1, 6)
})
this.circles.push(circle)
}
}

move() {
this.circles.forEach((circle, index) => {
if (circle.position.x > this.area.width || circle.position.y > this.area.height) {
return this.circles.splice(index, 1)
}
circle.move()
})
if (this.circles.length == 0) {
this.stop = true
}
}

draw() {
this.circles.forEach(circle => circle.draw())
}
}

class CursorSpecialEffects {
constructor() {
this.computerCanvas = document.createElement('canvas')
this.renderCanvas = document.createElement('canvas')

this.computerContext = this.computerCanvas.getContext('2d')
this.renderContext = this.renderCanvas.getContext('2d')

this.globalWidth = window.innerWidth
this.globalHeight = window.innerHeight

this.booms = []
this.running = false
}

handleMouseDown(e) {
const boom = new Boom({
origin: { x: e.clientX, y: e.clientY },
context: this.computerContext,
area: {
width: this.globalWidth,
height: this.globalHeight
}
})
boom.init()
this.booms.push(boom)
this.running || this.run()
}

handlePageHide() {
this.booms = []
this.running = false
}

init() {
// 只在桌面端生效,判断屏幕宽度是否大于 768px
if (window.innerWidth > 768) {
const style = this.renderCanvas.style
style.position = 'fixed'
style.top = style.left = 0
style.zIndex = '999999999999999999999999999999999999999999'
style.pointerEvents = 'none'

style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth
style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight

document.body.append(this.renderCanvas)

window.addEventListener('mousedown', this.handleMouseDown.bind(this))
window.addEventListener('pagehide', this.handlePageHide.bind(this))
}
}

run() {
this.running = true
if (this.booms.length == 0) {
return this.running = false
}

requestAnimationFrame(this.run.bind(this))

this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight)

this.booms.forEach((boom, index) => {
if (boom.stop) {
return this.booms.splice(index, 1)
}
boom.move()
boom.draw()
})
this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight)
}
}

const cursorSpecialEffects = new CursorSpecialEffects()
cursorSpecialEffects.init()

然后在./source/_data/body-end.njk中引入它:

1
2
{# 鼠标点击特效 #}
<script async src="/js/fireworks.js"></script>

加入图片轮播功能

基于 Splide 自己写了个插件hexo-splide-carousel,详见