Next 优化与使用技巧
Next主题设置及美化,打造自己的个性化主题。
一、主题美化
1、文章永久链接
Hexo 默认生成的文章地址路径是 【网站名称/年/月/日/文章名称】。
这种链接对搜索爬虫很不友好,它的 url 结构超过三层,太深。
安装 hexo-abbrlink
1 | npm install hexo-abbrlink --save |
然后配置站点配置文件 _config.yml :
1 | # URL |
2、鼠标点击特效
新建特效脚本文件,将其放在站点的 source 目录下(即 hexo/source/js/cursor)而不是主题目录下,如果没有 js 目录,则新建一个。
礼花特效(fireworks.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
154class 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() {
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()爆炸特效(explosion.js)
点击显/隐代码
1
;function updateCoords(e){pointerX=(e.clientX||e.touches[0].clientX)-canvasEl.getBoundingClientRect().left,pointerY=e.clientY||e.touches[0].clientY-canvasEl.getBoundingClientRect().top}function setParticuleDirection(e){var t=anime.random(0,360)*Math.PI/180,a=anime.random(50,180),n=[-1,1][anime.random(0,1)]*a;return{x:e.x+n*Math.cos(t),y:e.y+n*Math.sin(t)}}function createParticule(e,t){var a={};return a.x=e,a.y=t,a.color=colors[anime.random(0,colors.length-1)],a.radius=anime.random(16,32),a.endPos=setParticuleDirection(a),a.draw=function(){ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.fillStyle=a.color,ctx.fill()},a}function createCircle(e,t){var a={};return a.x=e,a.y=t,a.color="#F00",a.radius=.1,a.alpha=.5,a.lineWidth=6,a.draw=function(){ctx.globalAlpha=a.alpha,ctx.beginPath(),ctx.arc(a.x,a.y,a.radius,0,2*Math.PI,!0),ctx.lineWidth=a.lineWidth,ctx.strokeStyle=a.color,ctx.stroke(),ctx.globalAlpha=1},a}function renderParticule(e){for(var t=0;t<e.animatables.length;t++)e.animatables[t].target.draw()}function animateParticules(e,t){for(var a=createCircle(e,t),n=[],i=0;i<numberOfParticules;i++)n.push(createParticule(e,t));anime.timeline().add({targets:n,x:function(e){return e.endPos.x},y:function(e){return e.endPos.y},radius:.1,duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule}).add({targets:a,radius:anime.random(80,160),lineWidth:0,alpha:{value:0,easing:"linear",duration:anime.random(600,800)},duration:anime.random(1200,1800),easing:"easeOutExpo",update:renderParticule,offset:0})}function debounce(e,t){var a;return function(){var n=this,i=arguments;clearTimeout(a),a=setTimeout(function(){e.apply(n,i)},t)}}var canvasEl=document.querySelector(".fireworks");if(canvasEl){var ctx=canvasEl.getContext("2d"),numberOfParticules=30,pointerX=0,pointerY=0,tap="mousedown",colors=["#FF1461","#18FF92","#5A87FF","#FBF38C"],setCanvasSize=debounce(function(){canvasEl.width=2*window.innerWidth,canvasEl.height=2*window.innerHeight,canvasEl.style.width=window.innerWidth+"px",canvasEl.style.height=window.innerHeight+"px",canvasEl.getContext("2d").scale(2,2)},500),render=anime({duration:1/0,update:function(){ctx.clearRect(0,0,canvasEl.width,canvasEl.height)}});document.addEventListener(tap,function(e){"sidebar"!==e.target.id&&"toggle-sidebar"!==e.target.id&&"A"!==e.target.nodeName&&"IMG"!==e.target.nodeName&&(render.play(),updateCoords(e),animateParticules(pointerX,pointerY))},!1),setCanvasSize(),window.addEventListener("resize",setCanvasSize,!1)}
爱心(love.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!(function (e, t, a) {
function n() {
c(
".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"
),
o(),
r()
}
function r() {
for (var e = 0; e < d.length; e++)
d[e].alpha <= 0
? (t.body.removeChild(d[e].el), d.splice(e, 1))
: (d[e].y--,
(d[e].scale += 0.004),
(d[e].alpha -= 0.013),
(d[e].el.style.cssText =
'left:' +
d[e].x +
'px;top:' +
d[e].y +
'px;opacity:' +
d[e].alpha +
';transform:scale(' +
d[e].scale +
',' +
d[e].scale +
') rotate(45deg);background:' +
d[e].color +
';z-index:99999'))
requestAnimationFrame(r)
}
function o() {
var t = 'function' == typeof e.onclick && e.onclick
e.onclick = function (e) {
t && t(), i(e)
}
}
function i(e) {
var a = t.createElement('div')
;(a.className = 'heart'),
d.push({
el: a,
x: e.clientX - 5,
y: e.clientY - 5,
scale: 1,
alpha: 1,
color: s(),
}),
t.body.appendChild(a)
}
function c(e) {
var a = t.createElement('style')
a.type = 'text/css'
try {
a.appendChild(t.createTextNode(e))
} catch (t) {
a.styleSheet.cssText = e
}
t.getElementsByTagName('head')[0].appendChild(a)
}
function s() {
return (
'rgb(' +
~~(255 * Math.random()) +
',' +
~~(255 * Math.random()) +
',' +
~~(255 * Math.random()) +
')'
)
}
var d = []
;(e.requestAnimationFrame = (function () {
return (
e.requestAnimationFrame ||
e.webkitRequestAnimationFrame ||
e.mozRequestAnimationFrame ||
e.oRequestAnimationFrame ||
e.msRequestAnimationFrame ||
function (e) {
setTimeout(e, 1e3 / 60)
}
)
})()),
n()
})(window, document)浮现文字(text.js)
点击显/隐代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24var a_idx = 0;
jQuery(document).ready(function($) {
$("body").click(function(e) {
var a = new Array("喜欢我", "不喜欢我");
var $i = $("<span/>").text(a[a_idx]);
var x = e.pageX,
y = e.pageY;
$i.css({
"z-index": 99999,
"top": y - 28,
"left": x - a[a_idx].length * 8,
"position": "absolute",
"color": "#ff7a45"
});
$("body").append($i);
$i.animate({
"top": y - 180,
"opacity": 0
}, 1500, function() {
$i.remove();
});
a_idx = (a_idx + 1) % a.length;
});
});
在 hexo/source/_data/body-end.njk 文件中添加如下代码:
1 | {# 鼠标点击特效 #} |
然后在Next的配置文件 _config.next.yml 中取消 bodyEnd: source/_data/body-end.njk 的注释。
添加如下配置项:
1 | # 鼠标点击特效 |
3、近期文章
在 hexo/source/_data/sidebar.njk 文件中添加如下代码:
点击显/隐代码
1 | {% if theme.recent_posts %} |
然后在Next的配置文件 _config.next.yml 中取消 sidebar:source/_data/sidebar.njk 的注释。
添加如下配置项:
1 | recent_posts_title: 近期文章 |
4、Live2D模型
参考链接:Hexo添加Live2D看板娘+模型预览
5、文字背景色块
效果如下:
站点配置文件
主题配置文件
站点配置文件
主题配置文件
在 hexo/source/_data/styles.styl 文件中添加如下代码:
点击显/隐代码
1 | // 颜色块-黄 |
1 | <span id="inline-blue"> 站点配置文件 </span> |
6、点击头像跳转首页
打开 themes\next\layout\_partials\sidebar 目录下 site-overview.njk 文件
将第一个 div 替换为以下内容:
1 | <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person"> |
7、修改背景
打开 hexo/source/_data/styles.styl 文件
找到 body 块:
1 | body { |
8、设置置顶
先卸载 hexo-generator-index 插件:
1 | npm uninstall hexo-generator-index |
再安装hexo-generator-index-pin-top插件
1 | npm install hexo-generator-index-pin-top |
在hexo/source/_data/post-meta.njk添加如下代码:
1 | {% if post.top %} |
此时,文章标题下会显示置顶标识,但不在最前方,这是因为 Next 此部分注入代码位置不在最前方。
打开Hexo\themes\next\layout\_partials\post\post-meta.njk文件,找到以下代码:
1 | {{- next_inject('postMeta') }} |
将其移动至文件前部位置即可。
二、使用技巧
1、Note 标注功能
效果如下:
Welcome to Hexo!
2、居中引用
格式:
1 | {% cq %} |
效果:
故乡啊,挨着碰着,都是带刺的花。
——小林一茶
1、Next 主题美化
2、Hexo 搭建个人博客文章汇总(next 8.0)
3、Hexo框架(十三):关于博客主题持续更新的问题和我的新配置方式(next 8.0)
4、Hexo+NexT搭建博客笔记(较全)
5、hexo的next主题个性化教程:打造炫酷网站
6、为 Hexo 的 Next 主题添加 Gitalk 评论
7、Hexo添加Live2D看板娘+模型预览