Hexo+Next搭建个人博客 (其他样式美化) | Leezhiy Blog

Hexo+Next搭建个人博客 (其他样式美化)

前言

最近将博客从 Jekyll 迁移到 Hexo,在迁移的过程中也遇到一些问题,下面就简单记录一下 Hexo+NexT+Github Pages 的搭建步骤。

在上一章,我们将为博客添加一个网页音乐播放器,在本章,我们将进行最后的博客样式调整,让他变得更好看一些。

实现点击出现桃心效果

实现效果图

点击桃心

具体实现方法

在网址输入如下:

1
http://7u2ss1.com1.z0.glb.clouddn.com/love.js

然后将里面的代码copy一下,新建love.js文件并且将代码复制进去,然后保存。将love.js文件放到路径/themes/next/source/js/src里面,然后打开\themes\next\layout\_layout.swig文件,在末尾(在前面引用会出现找不到的bug)添加以下代码:

1
2
<!-- 页面点击小红心 -->
<script type="text/javascript" src="/js/src/love.js"></script>

点击爆炸效果

创建 Hexo/themes/next/source/js/fireworks.js 文件,添加以下内容。

1
"use strict";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,180)*Math.PI/180,a=anime.random(25,90),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(8,16),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=0.1,a.alpha=0.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:0.1,duration:anime.random(600,900),easing:"easeOutExpo",update:renderParticule}).add({targets:a,radius:anime.random(40,80),lineWidth:0,alpha:{value:0,easing:"linear",duration:anime.random(300,400)},duration:anime.random(600,900),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)}"use strict";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,180)*Math.PI/90,a=anime.random(25,90),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(8,16),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=0.1,a.alpha=0.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:0.1,duration:anime.random(600,900),easing:"easeOutExpo",update:renderParticule}).add({targets:a,radius:anime.random(40,80),lineWidth:0,alpha:{value:0,easing:"linear",duration:anime.random(300,400)},duration:anime.random(600,900),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)};

接着打开 主题配置文件 ,在最底部添加

script
1
2
3
# Fireworks
fireworks:
enabled: true

打开 hexo/next/layout/_layout.swig, 在</body>上面写下如下代码:

1
2
3
4
5
{% if theme.fireworks.enabled %}
<canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas>
<script type="text/javascript" src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script>
<script type="text/javascript" src="/js/src/fireworks.js"></script>
{% endif %}

在每篇文章末尾统一添加“本文结束”标记

实现效果图

效果图

具体实现方法

在路径 \themes\next\layout\_macro 中新建 passage-end-tag.swig 文件,并添加以下内容:

1
2
3
4
5
<div>
{% if not is_index %}
<div style="text-align:center;color: #ccc;font-size:14px;">{{theme.passage_end_tag.content}}</div>
{% endif %}
</div>

接着打开 \themes\next\layout\_macro\post.swig 文件,在 post-body 之后, post-footer 之前添加如下代码:

1
2
3
{% if not is_index and theme.passage_end_tag.enabled %}
{% include 'passage-end-tag.swig' %}
{% endif %}

接着打开 主题配置文件 ,在末尾添加:

script
1
2
3
4
# 文章末尾添加“本文结束”标记
passage_end_tag:
enabled: true
content: ------------- 💖 🌞 本 文 结 束 😚 感 谢 您 的 阅 读 🌞 💖 -------------

完成以上设置之后,在每篇文章之后都会添加如上效果图的样子。

设置网站的图标 Favicon

实现效果图

效果

具体方法实现

EasyIcon 中找一张合适的 ico 图标,或者去别的网站下载或者制作,并将图标名称改为 favicon.ico,然后把图标放在 /themes/next/source/images 里,接着打开 主题配置文件 ,搜索关键字 iocn, 修改如下:

script
1
2
3
4
5
6
7
favicon:
small: /images/favicon-16x16-next.png
medium: /images/favicon-32x32-next.png
apple_touch_icon: /images/apple-touch-icon-next.png
safari_pinned_tab: /images/logo.svg
#android_manifest: /images/manifest.json
#ms_browserconfig: /images/browserconfig.xml

背景添加动态线条效果

打开 next/layout/_layout.swig
</body> 之前添加代码(注意不要放在 </head> 的后面)

1
2
3
4
{% if theme.canvas_nest %}
<script type="text/javascript" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script>
{% endif %}
`

打开 主题配置文件 ,在末尾添加如下代码:

script
1
2
3
4
5
6
# --------------------------------------------------------------
# background settings
# --------------------------------------------------------------
# add canvas-nest effect
# see detail from https://github.com/hustcc/canvas-nest.js
canvas_nest: true

如果你感觉默认的线条太多的话可以修改 ``next/layout/_layout.swig`:

1
2
3
4
{% if theme.canvas_nest %}
<script type="text/javascript"
color="0,0,255" opacity='0.7' zIndex="-2" count="99" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script>
{% endif %}

color: 线条颜色, 默认: '0,0,0';三个数字分别为(R,G,B)
opacity: 线条透明度(0~1), 默认: 0.5
count: 线条的总数量, 默认: 150
zIndex: 背景的 z-index 属性,css 属性用于控制所在层的位置, 默认: -1

背景添加动态彩带效果

在 Hexo 文件夹下打开 git bash ,并输入:

script
1
2
$ cd themes/next
$ git clone https://github.com/theme-next/theme-next-canvas-ribbon source/lib/canvas-ribbon

打开 主题配置文件 ,搜索 canvas_ribbon 关键字,设置如下:

script
1
2
canvas_ribbon:
enable: true

需要使用 CDN 的话继续设置:

script
1
2
3
vendors:
...
canvas_ribbon: //cdn.jsdelivr.net/gh/theme-next/theme-next-canvas-ribbon@1/canvas-ribbon.js

设置圆角

打开 hexo\themes\next\source\css\_variables\Gemini.styl, 修改变量:

1
2
$border-radius-inner     = 0.5rem;
$border-radius = 0.5rem;

设置背景图片

分享一个非常好用的背景图网站 https://www.toptal.com/designers/subtlepatterns

找一个你心仪的背景图,下载保存到 hexo\themes\next\images\

打开 hexo\themes\next\source\css\_variables\Gemini.styl, 找到 $body-bg-color, 设置如下:

1
2
3
$body-bg-color           = url(/images/background.png);
// 如果你希望 暗黑模式 也使用这个背景就加上下面这一句
$body-bg-color-dark = url(/images/background.png);

设置目录背景图

找一个你心仪的背景图,下载保存到 hexo\themes\next\images\

打开 hexo\themes\next\source\css\_variables\Gemini.styl, 添加变量:

1
$header-inner-bg-color   = url(/images/site-brand-background.jpg);

新建 hexo\themes\next\source\css\_schemes\Gemini\_header.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
.site-brand-container {
background: $header-inner-bg-color;
background-size: cover;

+tablet-mobile() {
box-shadow: 0 0 16px rgba(0, 0, 0, .5);
}
}

.site-meta {
padding: 20px 0;
}

.brand {
padding: 0;
}

.site-subtitle {
margin: 10px 10px 0;
}

.custom-logo-image {
margin-top: 20px;

+tablet-mobile() {
display: none;
}
}

打开 hexo\themes\next\source\css\_schemes\Gemini\index.styl, 搜索 @import '../Pisces/_header';, 修改为

1
@import '../Gemini/_header';

设置回到顶部彩带

打开 hexo\themes\next\source\css\_variables\Gemini.styl, 添加变量:

1
2
3
$b2c-bg-color            = linear-gradient(90deg,#6dba82 0,#07b39b 15%,#1098ad 30%,#5073b8 44%,#a166ab 58%,#ef4e7b 72%,#f37055 86%,#f79533 100%);
$b2t-opacity = .8;
$sidebar-color = black

新建 hexo\themes\next\source\css\_schemes\Gemini\_sidebar.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
.sidebar {
background: var(--body-bg-color);
box-shadow: none;
margin-top: 100%;
position: static;
width: $sidebar-desktop;

+tablet-mobile() {
display: none;
}
}

.sidebar-toggle {
display: none;
}

.sidebar-inner {
background: var(--content-bg-color);
border-radius: $border-radius;
box-shadow: $box-shadow;
box-sizing: border-box;
color: $sidebar-color;
width: $sidebar-desktop;

if (hexo-config('motion.enable') && hexo-config('motion.transition.sidebar')) {
opacity: 0;
}

&.affix {
position: fixed;
top: $sidebar-offset;
}

&.affix-bottom {
position: absolute;
}
}

.site-state-item {
padding: 0 10px;
}

.sidebar-button {
border-bottom: 1px dotted $grey-light;
border-top: 1px dotted $grey-light;
margin-top: 10px;
text-align: center;

a {
border: 0;
color: $orange;
display: block;

&:hover {
background: none;
border: 0;
color: darken($orange, 20%);

.fa, .fab, .far, .fas {
color: darken($orange, 20%);
}
}
}
}

.links-of-author {
display: flex;
flex-wrap: wrap;
margin-top: 10px;
justify-content: center;
}

.links-of-author-item {
sidebar-inline-links-item();

if (!hexo-config('social_icons.icons_only')) {
width: 50%;
}

a, span.exturl {
border-bottom: none;
display: block;
text-decoration: none;

&::before {
display: none;
}

&:hover {
background: var(--menu-item-bg-color);
border-radius: 4px;
}
}

.fa, .fab, .far, .fas {
margin-right: 2px;
}
}

.links-of-blogroll-item {
padding: 0;

if (hexo-config('links_settings.layout') == 'inline') {
display: inline-block;
sidebar-inline-links-item();

if (!hexo-config('social_icons.icons_only')) {
width: unset;
}
}
}

if (hexo-config('back2top.sidebar')) {
// Only when back2top.sidebar is true, apply the following styles
.back-to-top {
background: $b2c-bg-color;
margin: 8px - $sidebar-offset -10px -18px;

&.back-to-top-on {
margin-top: 16px;
border-bottom-left-radius: 0.5rem;
border-bottom-right-radius: 0.5rem;
}
}
}

打开 hexo\themes\next\source\css\_schemes\Gemini\index.styl, 搜索 @import '../Pisces/_sidebar';, 修改为

1
@import '../Gemini/_sidebar';

设置分页样式

打开 hexo\themes\next\source\css\_schemes\Gemini\index.styl, 搜索 // Pagination., 修改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Pagination.
.pagination {
.page-number {
background: var(--content-bg-color);
border-radius: 1rem;
border-top: initial;
}

.prev, .next, .page-number {
background: var(--content-bg-color);
border-radius: 1rem;
border-top: initial;
margin-bottom: initial;
top: initial;
}


border-radius: $border-radius;
border-top: initial;
box-shadow: $box-shadow;
margin: $sidebar-offset 0 0;
padding: 10px 0 10px;
}

设置 Valine 评论样式

新建 hexo\themes\next\source\css\_schemes\Gemini\valine.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
#valine-comments button {
padding: 0.3rem 1rem;
border-color: #fff;
background-color: #8e8cd8;
color: #fff;
font-size: 0.7rem;
}
#valine-comments button:hover {
background-color: #ff7242;
}
#valine-comments textarea {
background: url("/images/comment_bg.png") 100% 100% no-repeat; #背景图
}
#valine-comments .info {
display: none;
}
#valine-comments .vimg {
border: 0;
}
#valine-comments .vimg:hover {
-webkit-transform: rotate(540deg);
-moz-transform: rotate(540deg);
-o-transform: rotate(540deg);
-ms-transform: rotate(540deg);
transform: rotate(540deg);
}
#valine-comments .vat {
padding: 0 0.8rem;
border: 1px solid #8e8cd8;
border-radius: 5px;
color: #8e8cd8;
font-size: 0.7125rem;
}
#valine-comments .vat:hover {
background-color: #8e8cd8;
color: #fff;
}

打开 hexo\themes\next\source\css\_schemes\Gemini\index.styl, 引入刚才新加的样式

1
@import '../Gemini/valine.styl';
Buy me a cup of milkshake 🍨.
------------- 💖 🌞 本 文 结 束 😚 感 谢 您 的 阅 读 🌞 💖 -------------

欢迎关注我的其它发布渠道