最近看了zhheo大佬的博客首页,发现大佬的布局还是那么的好看,于是果断COPY,再加上我一直想要在我的博客首页加一个大画幅的轮播图插件,于是又参考了Hassan的文章轮播图…经过一番折腾,效果如下:

1. 创建首页顶部模块

1.1 创建hometop.pug

themes/butterfly/layout/includes路径下创建hometop.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
29
30
31
32
33
if is_home()
#home_top
include bbTimeList.pug
.home_top_group
#homeTopGroup.homeTopGroup
#banner_group
#banners
include sticky.pug //轮播图
.category_group
.category_item
a.category_button(href=<左下角标签1路径>,style="background:linear-gradient(to right,#364f6b,#3fc1c9)")
span.category_button_text <标签1名称>
i.fas.fa-laptop-code
.category_item
a.category_button(href=<左下角标签2路径>,style="background:linear-gradient(to right,#6639a6,#3490de)")
span.category_button_text <标签2名称>
i.fas.fa-lightbulb
.category_item
a.category_button(href=<左下角标签3路径>,style="background:linear-gradient(to right,#f65,#ffbf37)")
span.category_button_text <标签3名称>
i.fas.fa-book
.top_post_group // 右侧文章推荐卡片
if site.data.slider
each i in site.data.slider
.top_post_item
.post_cover
a(href=url_for(i.link) title=i.title)
img.post_bg.entered.loaded(src=url_for(i.cover))
.post_cover_info
p.post_cover_text= i.description

.post_info(onclick=`"window.open(`+url_for(i.link)+`,"_self")"`)
a.article-title(href=url_for(i.link) title=i.title)= i.title

其中第一行的is_home()Hexo自带的辅助函数,用于判断是否为首页,但是其在justlovesmile.top/以及justlovesmile.top/page/2/等页面都返回True,因此如果你只想在首页的第一页显示该模块,可以使用is_current('/')

1.2 添加css样式

在自己的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
:root{
--mj-white: #fff;
--mj-card-bg: #fff;
--mj-theme: #425AEF;
--mj-main: #425AEF;
--mj-secondbg: #ededed;
--mj-card-border: #e3e8f7;
--style-border: 1px solid var(--mj-card-border);
--style-hover-border: 1px solid var(--mj-theme);
}
/* home top */
#home_top {
max-width: 1500px;
width: 100%;
margin-top: .5rem;
padding: 0 15px;
margin: 0 auto;
}
.home_top_group {
border-radius: 12px;
overflow: auto;
width: 100%;
margin-bottom: 0;
}
.homeTopGroup {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
width: 100%;
margin-top: 1rem;
overflow: auto;
overflow-x: score;
border-radius: 12px;
}
.homeTopGroup::-webkit-scrollbar {
display: none;
}
.homeTopGroup #banner_group {display: flex;}
div#banners {display: none;}
@media screen and (min-width: 1300px){
.homeTopGroup #banner_group {
width: calc(100% - 600px - 1.5rem);
display: flex;
flex-direction: column;
justify-content: space-between;
}
div#banners {
display: flex;
width: 100%;
height: 100%;
background: var(--mj-main);
margin-bottom: .5rem;
margin-right: .5rem;
border: var(--style-border);
border-radius: 12px;
overflow: hidden;
position: relative;
}
div#banners:hover{
border: var(--style-hover-border);
}
.homeTopGroup .category_group {
flex-direction: row !important;
}
.homeTopGroup .category_item {
width: calc(100% / 3 - .33rem);
height: 100% !important;
margin-right: .5rem;
}
.homeTopGroup .category_item:nth-child(3) {
margin-right: 0;
display: flex !important;
}
#banner-page {
width: 100%;
height: 100%;
}
.top_post_group {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-end;
height: calc(328px + .5rem);
align-content: space-between;
width: calc(600px + 1.5rem);
}
}

.homeTopGroup .category_group{
display: flex;
flex-direction: column;
justify-content: space-between;
min-width: 200px;
}
.homeTopGroup .category_item {
overflow: hidden;
transform: scale(1);
transition: .3s;
height: 48%;
border-radius: 12px;
}
.homeTopGroup .category_item:nth-child(3) {
display: none;
}
.homeTopGroup .category_item a.category_button {
height: 100%;
width: 100%;
background: var(--mj-card-bg);
border-radius: 12px;
display: inline-block;
text-align: left;
line-height: 4em;
font-weight: 700;
font-size: .9rem;
color: var(--mj-white);
transition: all .4s cubic-bezier(.39,.575,.565,1);
transform: scale(1);
overflow: hidden;
font-family: PingFang SC,Hiragino Sans GB,Microsoft YaHei;
}
.category_button_text {
padding-left: 25px;
}
a.category_button i {
font-size: 3rem;
opacity: .3;
position: absolute;
right: 15px;
top: 10%;
transition: .3s;
transform: rotate(-10deg);
/*width: 100px;
text-align: center;*/
}
a.category_button:hover i {
opacity: .8;
transition: .8s;
transition-delay: .15s;
transform: scale(1.1)
}
a.category_button:hover:after{
width: 3rem;
transition: .8s;
}
a.category_button:after {
top: 40px;
width: 1rem;
left: 25px;
height: 2px;
background: var(--mj-white);
content: "";
border-radius: 1px;
position: absolute;
transition: .8s;
}
@media screen and (max-width: 768px){
#home_top{
padding: 0 5px;
}
.homeTopGroup .category_group {
min-width: 130px!important;
}
.top_post_group .top_post_item{
border-radius: 0;
}
}
.top_post_group{
display: flex;
position: relative;
}
.top_post_group .top_post_item {
display: flex;
width: 200px;
min-width: 200px;
height: 164px;
max-height: 164px;
flex-direction: column;
align-items: flex-start;
margin-left: .5rem;
background: var(--mj-card-bg);
border-radius: 12px;
overflow: hidden;
border: var(--style-border);
}
.top_post_group .top_post_item:hover {border: var(--style-hover-border);}
.top_post_group .top_post_item .post_cover {
width: 100%;
height: 110px;
position: relative;
}
.top_post_group .top_post_item .post_cover img {
object-fit: cover;
width: 100%;
height: 110px;
background: var(--mj-secondbg);
}
.top_post_group .top_post_item .post_cover .post_cover_info {
position: absolute;
top: 0;
width: 101%;
height: 100%;
opacity: 0;
background-color: rgba(0,0,0,0.7) !important;
transition: all 0.3s ease;
display: flex;
}
.top_post_group .top_post_item:hover .post_cover .post_cover_info{
opacity: 1;
}
.top_post_group .top_post_item .post_cover .post_cover_info .post_cover_text{
color: #fff;
padding: 12px 14px;
font-size: 15px;
font-weight: 400;
margin: 20px 0;
-webkit-line-clamp: 2;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
}
.top_post_group .top_post_item:hover .post_info,
.top_post_group .top_post_item:focus .post_info{
/*background: var(--mj-theme);*/
box-shadow: inset 0 -60px 0 0 var(--mj-theme);
}
.top_post_group .top_post_item .post_info a{
color: var(--mj-fontcolor) !important;
transition: 0;
}
.top_post_group .top_post_item:hover .post_info a{
color: var(--mj-white) !important;
}
.top_post_group .top_post_item .post_info {
padding: .2rem .5rem .3rem .5rem!important;
transition: .3s;
width: 100%;
height: 100%;
}
.top_post_group .top_post_item .post_info .article-title {
-webkit-line-clamp: 2;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
line-height: 1.4;
justify-content: center;
align-items: flex-end;
align-content: center;
font-weight: 600;
font-size: .8rem!important;
padding: 0!important;
}

2. 创建顶部轮播图

2.1 创建sticky.pug

themes/butterfly/layout/includes路径下创建sticky.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
29
link(rel='stylesheet' href='https://unpkg.com/swiper/swiper-bundle.min.css')
#sticky
#stickyList.swiper-container
#stickyWrapper.swiper-wrapper
.swiper-slide(onclick=`window.open('/random/','_self')`)
.grid-img
iframe#banner-page(src="<这里放iframe地址>" frameborder="0" loading="eager") // 可以放iframe
.grid-title
span 随便逛逛
i.fas.fa-arrow-right
.swiper-slide(onclick=`window.open('/video/','_self')`)
.grid-img
img.cover.entered.loaded(alt='VLOG' src='https://npm.elemecdn.com/justlovesmile-photo/myvlog.gif') // 可以放GIF
.grid-title
span 看看VLOG
i.fas.fa-arrow-right
.swiper-slide(onclick=`window.open('/music/','_self')`)
.grid-img
img.cover.entered.loaded(alt='歌单' src='https://npm.elemecdn.com/justlovesmile-img/gitar.jpg') // 可以放图片
.grid-title
span 听听音乐
i.fas.fa-arrow-right
//- 分页器
.swiper-pagination

.js-pjax
script(src='https://unpkg.com/swiper/swiper-bundle.min.js')
script(src='/js/sticky.js')
link(rel='stylesheet' href='/css/sticky.css')

2.2 创建sticky.js

themes/butterfly/source/js路径下创建sticky.js文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var mySwiper = new Swiper('#stickyList', {
direction: 'horizontal',
speed: 600,
loop: true,
effect : 'fade',
loopPreventsSlide: false,
autoplay: {
delay: 20000,
},
mousewheel: false,
pagination: {
el: ".swiper-pagination",
dynamicBullets: true,
},
})

2.3 创建sticky.css

themes/butterfly/source/css路径下创建sticky.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
:root{
--mj-white: #fff;
--mj-card-bg: #fff;
--mj-theme: #425AEF;
}
#sticky,
#stickyList,
#stickyWrapper{
width: 100%;
height: 100%;
}
.swiper-container#stickyList {
overflow: hidden;
}
#stickyList .swiper-slide {
background: var(--mj-card-bg);
position: relative;
border-radius: 12px;
transition: 0.3s;
width: 100%;
height: 100%;
}
#stickyList .swiper-slide .grid-img {
overflow: hidden;
height: 16.2rem;
}
#stickyList .swiper-slide .grid-img img {
transition: 0.3s;
object-fit: cover;
display: block;
width: 100%;
height: 100%;
}
#stickyList .swiper-slide:hover .grid-title{
opacity: .8;
cursor: pointer !important;
}
#stickyList .swiper-slide:hover .grid-img{
filter: blur(5px);
}
#stickyList .swiper-slide:hover .grid-title span,
#stickyList .swiper-slide:hover .grid-title i{
transform: translateX(0px);
transition: .5s;
}
#stickyList .swiper-slide .grid-title span,
#stickyList .swiper-slide .grid-title i{
transform: translateX(-100px);
transition: .5s;
}
#stickyList .swiper-slide .grid-title {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
background: var(--mj-theme);
color: var(--mj-white);
padding-left: 1.5rem;
display: flex;
flex-direction: column;
justify-content: center;
opacity: 0;
transition: .5s;
}
#stickyList .swiper-slide .grid-title span {
font-size: 5rem;
font-weight: 700;
line-height: 5rem;
}
#stickyList .swiper-slide .grid-title i {
font-size: 4rem;
opacity: .6;
}
@media screen and (max-width: 768px) {
#sticky {
display: none;
}
}

3. 创建文章推荐卡片

3.1 创建slider.yml

hexo\source\_data\路径下创建slider.yml文件,最好准备6个推荐文章,例如:

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
#- cover: 封面图片链接
# timeline: '2020-10-01' # 日期,需要用''包裹
# link: 置顶文章链接,站内文章建议填相对链接
# title: 置顶文章标题
# description: 置顶文章描述
- cover: https://npm.elemecdn.com/justlovesmile-img/20200715201402.png
timeline: '2020-07-15'
link: /posts/c8972b63.html
title: 必看 | Hexo博客搭建超级指南
description: Hexo博客搭建全过程,环境部署,博客魔改等等...
- cover: https://npm.elemecdn.com/justlovesmile-img/090412-1557363852af44.jpg
timeline: '2020-04-09'
link: /posts/56163.html
title: Hexo博客 | 博客中能用到的代码(一)
description: 这篇文章介绍了如何使用font awesome图标字体库,使用动态图标,添加网页运行时间,全站变黑白,鼠标点击特效,网页标题的动态效果,网页樱花特效,鼠标触动音乐特效
- cover: https://npm.elemecdn.com/justlovesmile-img/095658-1562983018e455.jpg
timeline: '2020-04-09'
link: /posts/15391.html
title: Hexo博客 | 博客中能用到的代码(二)
description: 这篇文章介绍了如何添加旋转小人和每日诗句
- cover: https://npm.elemecdn.com/justlovesmile-img/20220331192754.png
timeline: '2022-03-31'
link: /posts/a806bebe.html
title: 推荐 | 计算机专业,大学课程「笔记归档」
description: 本文是博主本科期间的专业课程学习笔记的整理和归档,适合计算机专业的同学阅读。
- cover: https://npm.elemecdn.com/justlovesmile-img/20220318183107.png
timeline: '2022-03-18'
link: /posts/589ec011.html
title: 深度学习 | Detectron2使用指南
description: Detectron2是Facebook AI Research的检测和分割框架,其主要基于PyTorch实现,但具有更模块化设计,因此它是灵活且便于扩展的。
- cover: https://npm.elemecdn.com/justlovesmile-img/202109111517311.jpg
timeline: '2021-09-11'
link: /posts/865c56ba.html
title: 目标检测 | 常用数据集标注格式及生成脚本
description: 目标检测是计算机视觉任务中的一个重要研究方向,是计算机视觉的根本性问题之一,是其他诸多计算机视觉任务的基础以及前提。本文主要介绍了目标检测数据集的几种标注格式和转换代码。

3.2 css样式

1.2.top_post_group等样式类,不再赘述…

4. 补充:zhheo大佬首页人来人往特效

4.1 创建people页面

hexo\source\路径下创建people文件夹,其中创建index.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
---
layout: false
---

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MJ's People Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, maximum-scale=1.0, minimal-ui" /><!--禁止缩放-->
<link rel="stylesheet" href="/people/style.css">
</head>
<body>
<canvas id="canvas" width="808" height="244"></canvas>
<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/gsap/3.9.1/gsap.min.js"></script>
<script src="/people/script.js"></script></body>
</html>

4.2 创建css样式

hexo\source\people路径下,创建style.css:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
body,
html{
height:100%;
background-color:#fff;
}
body{
margin:0;
}
#canvas{
width:100%;
height:100%;
}
body::-webkit-scrollbar{
display:none;
}

4.3 创建js文件

hexo\source\people路径下,创建script.js:

1
"use strict";function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,r){if(e){if("string"==typeof e)return _arrayLikeToArray(e,r);var t=Object.prototype.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(e,r):void 0}}function _iterableToArray(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}function _arrayLikeToArray(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,a=new Array(r);t<r;t++)a[t]=e[t];return a}function _classCallCheck(e,r){if(!(e instanceof r))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var a=r[t];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),e}var config={src:"https://npm.elemecdn.com/guli-heo/others/open-peeps-sheet.png",rows:15,cols:7},randomRange=function(e,r){return e+Math.random()*(r-e)},randomIndex=function(e){return 0|randomRange(0,e.length)},removeFromArray=function(e,r){return e.splice(r,1)[0]},removeItemFromArray=function(e,r){return removeFromArray(e,e.indexOf(r))},removeRandomFromArray=function(e){return removeFromArray(e,randomIndex(e))},getRandomFromArray=function(e){return e[0|randomIndex(e)]},resetPeep=function(e){var r,t,a=e.stage,n=e.peep,o=.5<Math.random()?1:-1,i=100-250*gsap.parseEase("power2.in")(Math.random()),s=a.height-n.height+i;return 1==o?(r=-n.width,t=a.width,n.scaleX=1):(r=a.width+n.width,t=0,n.scaleX=-1),n.x=r,n.y=s,{startX:r,startY:n.anchorY=s,endX:t}},normalWalk=function(e){var r=e.peep,t=e.props,a=(t.startX,t.startY),n=t.endX,o=gsap.timeline();return o.timeScale(randomRange(.5,1.5)),o.to(r,{duration:10,x:n,ease:"none"},0),o.to(r,{duration:.25,repeat:40,yoyo:!0,y:a-10},0),o},walks=[normalWalk],Peep=function(){function a(e){var r=e.image,t=e.rect;_classCallCheck(this,a),this.image=r,this.setRect(t),this.x=0,this.y=0,this.anchorY=0,this.scaleX=1,this.walk=null}return _createClass(a,[{key:"setRect",value:function(e){this.rect=e,this.width=e[2],this.height=e[3],this.drawArgs=[this.image].concat(_toConsumableArray(e),[0,0,this.width,this.height])}},{key:"render",value:function(e){e.save(),e.translate(this.x,this.y),e.scale(this.scaleX,1),e.drawImage.apply(e,_toConsumableArray(this.drawArgs)),e.restore()}}]),a}(),img=document.createElement("img");img.onload=init,img.src=config.src;var canvas=document.querySelector("#canvas"),ctx=canvas.getContext("2d"),stage={width:0,height:0},allPeeps=[],availablePeeps=[],crowd=[];function init(){createPeeps(),resize(),gsap.ticker.add(render),window.addEventListener("resize",resize)}function createPeeps(){for(var e=config.rows,r=config.cols,t=e*r,a=img.naturalWidth/e,n=img.naturalHeight/r,o=0;o<t;o++)allPeeps.push(new Peep({image:img,rect:[o%e*a,(o/e|0)*n,a,n]}))}function resize(){stage.width=canvas.clientWidth,stage.height=canvas.clientHeight,canvas.width=stage.width*devicePixelRatio,canvas.height=stage.height*devicePixelRatio,crowd.forEach(function(e){e.walk.kill()}),crowd.length=0,availablePeeps.length=0,availablePeeps.push.apply(availablePeeps,allPeeps),initCrowd()}function initCrowd(){for(;availablePeeps.length;)addPeepToCrowd().walk.progress(Math.random())}function addPeepToCrowd(){var e=removeRandomFromArray(availablePeeps),r=getRandomFromArray(walks)({peep:e,props:resetPeep({peep:e,stage:stage})}).eventCallback("onComplete",function(){removePeepFromCrowd(e),addPeepToCrowd()});return e.walk=r,crowd.push(e),crowd.sort(function(e,r){return e.anchorY-r.anchorY}),e}function removePeepFromCrowd(e){removeItemFromArray(crowd,e),availablePeeps.push(e)}function render(){canvas.width=canvas.width,ctx.save(),ctx.scale(devicePixelRatio,devicePixelRatio),crowd.forEach(function(e){e.render(ctx)}),ctx.restore()}

5. 参考文章

张洪Heo - 分享设计与科技生活
Butterfly主题美化魔改集锦 | Hassan’s Blog