Hexo之Butterfly主题魔改
footer跳动的心
效果预览
查看步骤
编辑[blogroot]/themes/butterfly/layout/includes/footer.pug
文件
将以下内容
1 | ©${theme.footer.owner.since} - ${nowYear} By ${config.author} |
改为
1 | ©${theme.footer.owner.since} - ${nowYear + ' '} <i id="heartbeat" class="fa fas fa-heartbeat"></i> ${config.author} |
将以下内容
1 | ©${nowYear} By ${config.author} |
改为
1 | ©${nowYear + ' '} <i id="heartbeat" class="fa fas fa-heartbeat"></i> ${config.author} |
添加以下内容
1 | <link rel="stylesheet" href="https://fastly.jsdelivr.net/gh/HCLonely/images@master/others/heartbeat.min.css"> |
参考下图
鼠标样式
查看步骤
在 /themes/butterfly/source/css
路径下创建一个mouse.css
文件,在文件中添加如下代码:
1 | body { |
打开主题配置文件_config.yml
,找到inject
,在head
处直接引入该文件:
1 | inject: |
昼夜切换动画
效果预览
查看步骤
新建
[Blogroot]\themes\butterfly\layout\includes\custom\sun_moon.pug
,这部分其实实质上就是一个svg文件,通过js操作它的旋转显隐,淡入淡出实现动画效果。1
2
3
4
5
6
7
8
9svg(aria-hidden='true', style='position:absolute; overflow:hidden; width:0; height:0')
symbol#icon-sun(viewBox='0 0 1024 1024')
path(d='M960 512l-128 128v192h-192l-128 128-128-128H192v-192l-128-128 128-128V192h192l128-128 128 128h192v192z', fill='#FFD878', p-id='8420')
path(d='M736 512a224 224 0 1 0-448 0 224 224 0 1 0 448 0z', fill='#FFE4A9', p-id='8421')
path(d='M512 109.248L626.752 224H800v173.248L914.752 512 800 626.752V800h-173.248L512 914.752 397.248 800H224v-173.248L109.248 512 224 397.248V224h173.248L512 109.248M512 64l-128 128H192v192l-128 128 128 128v192h192l128 128 128-128h192v-192l128-128-128-128V192h-192l-128-128z', fill='#4D5152', p-id='8422')
path(d='M512 320c105.888 0 192 86.112 192 192s-86.112 192-192 192-192-86.112-192-192 86.112-192 192-192m0-32a224 224 0 1 0 0 448 224 224 0 0 0 0-448z', fill='#4D5152', p-id='8423')
symbol#icon-moon(viewBox='0 0 1024 1024')
path(d='M611.370667 167.082667a445.013333 445.013333 0 0 1-38.4 161.834666 477.824 477.824 0 0 1-244.736 244.394667 445.141333 445.141333 0 0 1-161.109334 38.058667 85.077333 85.077333 0 0 0-65.066666 135.722666A462.08 462.08 0 1 0 747.093333 102.058667a85.077333 85.077333 0 0 0-135.722666 65.024z', fill='#FFB531', p-id='11345')
path(d='M329.728 274.133333l35.157333-35.157333a21.333333 21.333333 0 1 0-30.165333-30.165333l-35.157333 35.157333-35.114667-35.157333a21.333333 21.333333 0 0 0-30.165333 30.165333l35.114666 35.157333-35.114666 35.157334a21.333333 21.333333 0 1 0 30.165333 30.165333l35.114667-35.157333 35.157333 35.157333a21.333333 21.333333 0 1 0 30.165333-30.165333z', fill='#030835', p-id='11346')新建
[Blogroot]\themes\butterfly\source\css\_layout\sun_moon.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.Cuteen_DarkSky,
.Cuteen_DarkSky:before
content ''
position fixed
left 0
right 0
top 0
bottom 0
z-index 88888888
.Cuteen_DarkSky
background linear-gradient(#feb8b0, #fef9db)
&:before
transition 2s ease all
opacity 0
background linear-gradient(#4c3f6d, #6c62bb, #93b1ed)
.DarkMode
.Cuteen_DarkSky
&:before
opacity 1
.Cuteen_DarkPlanet
z-index 99999999
position fixed
left -50%
top -50%
width 200%
height 200%
-webkit-animation CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1)
animation CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1)
transform-origin center bottom
@-webkit-keyframes CuteenPlanetMove {
0% {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@keyframes CuteenPlanetMove {
0% {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
.Cuteen_DarkPlanet
&:after
position absolute
left 35%
top 40%
width 9.375rem
height 9.375rem
border-radius 50%
content ''
background linear-gradient(#fefefe, #fffbe8)
.search
span
display none
.menus_item
a
text-decoration none!important
//按钮相关,对侧栏按钮做过魔改的可以调整这里的数值
.icon-V
padding 5px新建
[Blogroot]\themes\butterfly\source\js\sun_moon.js
,去除了冗余代码,去jquery1
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
28function switchNightMode() {
document.querySelector('body').insertAdjacentHTML('beforeend', '<div class="Cuteen_DarkSky"><div class="Cuteen_DarkPlanet"></div></div>'),
setTimeout(function() {
document.querySelector('body').classList.contains('DarkMode') ? (document.querySelector('body').classList.remove('DarkMode'), localStorage.setItem('isDark', '0'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-moon')) : (document.querySelector('body').classList.add('DarkMode'), localStorage.setItem('isDark', '1'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-sun')),
setTimeout(function() {
document.getElementsByClassName('Cuteen_DarkSky')[0].style.transition = 'opacity 3s';
document.getElementsByClassName('Cuteen_DarkSky')[0].style.opacity = '0';
setTimeout(function() {
document.getElementsByClassName('Cuteen_DarkSky')[0].remove();
}, 1e3);
}, 2e3)
})
const nowMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
if (nowMode === 'light') {
activateDarkMode()
saveToLocal.set('theme', 'dark', 2)
GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night)
document.getElementById('modeicon').setAttribute('xlink:href', '#icon-sun')
} else {
activateLightMode()
saveToLocal.set('theme', 'light', 2)
document.querySelector('body').classList.add('DarkMode'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-moon')
}
// handle some cases
typeof utterancesTheme === 'function' && utterancesTheme()
typeof FB === 'object' && window.loadFBComment()
window.DISQUS && document.getElementById('disqus_thread').children.length && setTimeout(() => window.disqusReset(), 200)
}修改
[Blogroot]\themes\butterfly\layout\includes\head.pug
,在文件末位加上一行:1
+ include ./custom/sun_moon.pug
修改
[Blogroot]\themes\butterfly\layout\includes\rightside.pug
,把原本的昼夜切换按钮替换掉1
2
3
4
5
6
7when 'darkmode'
if darkmode.enable && darkmode.button
- button#darkmode(type="button" title=_p('rightside.night_mode_title'))
- i.fas.fa-adjust
+ a.icon-V.hidden(onclick='switchNightMode()', title=_p('rightside.night_mode_title'))
+ svg(width='25', height='25', viewBox='0 0 1024 1024')
+ use#modeicon(xlink:href='#icon-moon')修改
[Blogroot]\themes\butterfly\_config.yml
,引入js1
2
3
4inject:
head:
bottom:
- <script src="/js/sun_moon.js" async></script>
时间轴添加生肖
效果预览
查看步骤
在
[Blogroot]\themes\butterfly\scripts\
目录下新建year.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18hexo.extend.helper.register('getAnimalIcon', function (year) {
var index = parseInt(year) % 12;
var icon = {
0: 'icon-monkey',
1: 'icon-rooster',
2: 'icon-dog',
3: 'icon-boar',
4: 'icon-rat',
5: 'icon-ox',
6: 'icon-tiger',
7: 'icon-rabbit',
8: 'icon-dragon',
9: 'icon-snake',
10: 'icon-horse',
11: 'icon-goat',
}
return icon[index]
});引入阿里矢量图标库图标,在
[Blogroot]\themes\butterfly\source\css\
目录下新建year.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@import url("//at.alicdn.com/t/font_2264842_3izu8i5eoc2.css");
/* 用的是别人的项目 */
.iconfont {
font-family: "iconfont" ;
font-size: 1.85em;
/* 可以定义图标大小 */
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* 生肖鼠 */
.icon-rat:before {
color: #85c3de;
/* 可以自定义图标颜色 */
}
/* 生肖牛 */
.icon-ox:before {
color: #ffaf6e;
}
/* 生肖虎 */
.icon-tiger:before {
color: #f7c768;
}
/* 生肖兔 */
.icon-rabbit:before {
color: #ffbdd8;
}
/* 生肖龙 */
.icon-dragon:before {
color: #ff8787;
}
/* 生肖蛇 */
.icon-snake:before {
color: #c3d686;
}
/* 生肖马 */
.icon-horse:before {
color: #ffaf6e;
}
/* 生肖羊 */
.icon-goat:before {
color: #f7c768;
}
/* 生肖猴 */
.icon-monkey:before {
color: #c3d686;
}
/* 生肖鸡 */
.icon-rooster:before {
color: #ff8787;
}
/* 生肖狗 */
.icon-dog:before {
color: #85c3de;
}
/* 生肖猪 */
.icon-boar:before {
color: #ffbdd8;
}修改
[Blogroot]\themes\butterfly\layout\includes\mixins\article-sort.pug
,第7行开始,注意缩进。1
2
3
4
5
6
7
8
9
10- let title = article.title || _p('no_title')
+ - let animalIcon = getAnimalIcon(tempYear)
if tempYear !== year
- year = tempYear
- .article-sort-item.year= year
+ .article-sort-item.year
+ span= year
+ i.iconfont(class=animalIcon)
.article-sort-item(class=no_cover)
if article.cover && theme.cover.archives_enable修改主题配置文件
_config.yml
的inject
配置项,引入year.css
1
2
3
4inject:
head:
- <link rel="stylesheet" href="/css/year.css" media="defer" onload="this.media='all'">
bottom:
自定义字体
效果预览
查看步骤
首先需要下载心仪的字体。推荐一个免费的字体库网站,支持在线转换预览和免费字体包下载。这里选择
甜甜圈海报字体
。根据页面按钮找到字体下载。得到相应的字体文件。为了方便起见,将其重命名为Candy.ttf
不一定是ttf后缀,其他后缀也是完全正常的,例如
eot、otf、fon、font、ttc、woff、woff2
等。将下载好的字体包放到本地文件夹下,这里推荐新建一个
fonts
文件夹。例如我是放在[Blogroot]\themes\butterfly\source\fonts\
目录下在自定义样式
\themes\butterfly\source\css\custom.css
中引入字体包:1
2
3
4
5
6
7
8
9@font-face{
font-family:'Candyhome' ; /* 字体名自定义即可 */
src:url('/fonts/Candy.ttf'); /* 字体文件路径 */
font-display : swap;
}
body {
font-family: 'Candyhome', sans-serif;
}关于
font-family
的写法,此处表示主字体用'Candyhome'
,若字体包内没有相应字体,则使用备用字体sans-serif
,备用字体可以写多个。形如:1
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Lato, Roboto, "PingFang SC", "STZhongsong", "Lantinghei SC", sans-serif
主题配置文件配置(照着配置就行,后面引入其它字体都不用改了好像):
1
2
3
4
5
6
7# Global font settings
# Don't modify the following settings unless you know how they work (非必要不要修改)
font:
global-font-size: "15px"
code-font-size: "15px"
font-family: ZhuZiAYuanJWD, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Lato, Roboto, "PingFang SC", "STZhongsong", "Lantinghei SC", sans-serif
code-font-family: consolas, Menlo, "PingFang SC", "Microsoft JhengHei", "Microsoft YaHei", sans-serif
公祭日自动变灰
效果预览
查看步骤
站点公祭日自动变灰判定是通过js监测当前日期是否为公祭日,从而调整html的filter属性使站点变灰。
在
[Blogroot]\themes\butterfly\source\js\
目录下新建grayscale.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
36if(PublicSacrificeDay()){
document.getElementsByTagName("html")[0].setAttribute("style","filter:gray !important;filter:grayscale(100%);-webkit-filter:grayscale(100%);-moz-filter:grayscale(100%);-ms-filter:grayscale(100%);-o-filter:grayscale(100%);");
}
function PublicSacrificeDay(){
var PSFarr=new Array("0403","0404","0405","0406","0414","0512","0707","0807","0814","0909","0918","0930","1025","1213");
//2020年4月4日 新冠肺炎哀悼日,清明节
//2010年4月14日,青海玉树地震
//2008年5月12日,四川汶川地震
//1937年7月7日,七七事变 又称卢沟桥事变
//2010年8月7日,甘肃舟曲特大泥石流
//8月14日,世界慰安妇纪念日
//1976年9月9日,毛主席逝世
//1931年9月18日,九一八事变
//烈士纪念日为每年9月30日
//1950年10月25日,抗美援朝纪念日
//1937年12月13日,南京大屠杀
var currentdate = new Date();
var str = "";
var mm = currentdate.getMonth()+1;
if(currentdate.getMonth()>9){
str += mm;
}else{
str += "0" + mm;
}
if(currentdate.getDate()>9){
str += currentdate.getDate();
}else{
str += "0" + currentdate.getDate();
}
if(PSFarr.indexOf(str)>-1){
return 1;
}else{
return 0;
}
}在主题配置文件
_config.yml
的inject
配置项添加引入,此处因为这是个独立的js,而且体量极小,所以可以添加async
异步加载标签1
2
3
4inject:
head:
bottom:
- <script async src="/js/grayscale.js"></script>
页脚计时器
效果预览
查看步骤
安装插件
1
npm install hexo-butterfly-footer-beautify --save
添加 js
在
butterfly\source\js
目录下添加runtime.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
59setInterval(() => {
let create_time = Math.round(
new Date("2022-07-01 00:00:00").getTime() / 1000
); //在此行修改建站时间
let timestamp = Math.round(new Date().getTime() / 1000);
let second = timestamp - create_time;
let time = new Array(0, 0, 0, 0, 0);
var nol = function (h) {
return h > 9 ? h : "0" + h;
};
if (second >= 365 * 24 * 3600) {
time[0] = parseInt(second / (365 * 24 * 3600));
second %= 365 * 24 * 3600;
}
if (second >= 24 * 3600) {
time[1] = parseInt(second / (24 * 3600));
second %= 24 * 3600;
}
if (second >= 3600) {
time[2] = nol(parseInt(second / 3600));
second %= 3600;
}
if (second >= 60) {
time[3] = nol(parseInt(second / 60));
second %= 60;
}
if (second > 0) {
time[4] = nol(second);
}
if (Number(time[2]) < 22 && Number(time[2]) > 7) {
currentTimeHtml =
"<div id='runtime'>" +
time[0] +
" YEAR " +
time[1] +
" DAYS " +
time[2] +
" : " +
time[3] +
" : " +
time[4] +
"</div>";
} else {
currentTimeHtml =
"<div id='runtime'>" +
time[0] +
" YEAR " +
time[1] +
" DAYS " +
time[2] +
" : " +
time[3] +
" : " +
time[4] +
"</div>";
}
document.getElementById("workboard").innerHTML = currentTimeHtml;
}, 1000);添加 css
在
butterfly\source\css
目录下添加runtime.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/*电子钟字体*/
@font-face {
font-family: 'UnidreamLED';
src: url("https://cdn.jsdelivr.net/npm/akilar-candyassets/fonts/UnidreamLED.ttf");
font-display: swap;
}
div#runtime {
width: 250px;
margin: auto;
color: #fff;
padding-inline: 5px;
border-radius: 10px;
background-color: rgba(0,0,0,0.7);
font-family: 'UnidreamLED';
}
[data-theme="dark"] div#runtime {
color: #28b4c8;
box-shadow: 0 0 5px rgba(28,69,218,0.71);
animation: flashlight 1s linear infinite alternate;
}
/*悬停显示徽标提示语*/
a.github-badge:hover:before {
position: fixed;
width: fit-content;
margin: auto;
left: 0;
right: 0;
top: 10%;
border-radius: 10px;
text-align: center;
z-index: 100;
content: attr(data-title);
font-size: 20px;
color: #fff;
padding: 10px;
background-color: var(--text-bg-hover);
}
[data-theme=dark] a.github-badge:hover:before {
background-color: rgba(18,18,18,0.8);
}
@-moz-keyframes flashlight {
from {
box-shadow: 0 0 5px #1478d2;
}
to {
box-shadow: 0 0 2px #1478d2;
}
}
@-webkit-keyframes flashlight {
from {
box-shadow: 0 0 5px #1478d2;
}
to {
box-shadow: 0 0 2px #1478d2;
}
}
@-o-keyframes flashlight {
from {
box-shadow: 0 0 5px #1478d2;
}
to {
box-shadow: 0 0 2px #1478d2;
}
}
@keyframes flashlight {
from {
box-shadow: 0 0 5px #1478d2;
}
to {
box-shadow: 0 0 2px #1478d2;
}
}添加配置信息
在
主题配置文件
中添加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# footer_beautify
footer_beautify:
enable:
timer: true # 计时器开关
bdage: false # 徽标开关
priority: 5 #过滤器优先权
enable_page: all # 应用页面
exclude: #屏蔽页面
# - /posts/
# - /about/
layout: # 挂载容器类型
type: id
name: footer-wrap
index: 0
# 计时器部分配置项
runtime_js: /js/runtime.js
runtime_css: /css/runtime.css
# 徽标部分配置项
swiperpara: 3 #若非0,则开启轮播功能,每行徽标个数
bdageitem:
- link: https://hexo.io/ #徽标指向网站链接
shields: https://img.shields.io/badge/Frame-Hexo-blue?style=flat&logo=hexo #徽标API
message: 博客框架为Hexo_v5.4.0 #徽标提示语
- link: https://butterfly.js.org/
shields: https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&logo=bitdefender
message: 主题版本Butterfly_v3.8.2
- link: https://www.jsdelivr.com/
shields: https://img.shields.io/badge/CDN-jsDelivr-orange?style=flat&logo=jsDelivr
message: 本站使用JsDelivr为静态资源提供CDN加速
- link: https://vercel.com/
shields: https://img.shields.io/badge/Hosted-Vercel-brightgreen?style=flat&logo=Vercel
message: 本站采用双线部署,默认线路托管于Vercel
- link: https://vercel.com/
shields: https://img.shields.io/badge/Hosted-Coding-0cedbe?style=flat&logo=Codio
message: 本站采用双线部署,联通线路托管于Coding
- link: https://github.com/
shields: https://img.shields.io/badge/Source-Github-d021d6?style=flat&logo=GitHub
message: 本站项目由Github托管
- link: http://creativecommons.org/licenses/by-nc-sa/4.0/
shields: https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&logo=Claris
message: 本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可
swiper_css: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.css
swiper_js: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.js
swiperbdage_init_js: https://npm.elemecdn.com/hexo-butterfly-footer-beautify/lib/swiperbdage_init.min.js参数释义
参数 | 备选值/类型 | 释义 |
---|---|---|
priority | number | 【可选】过滤器优先级,数值越小,执行越早,默认为10,选填 |
enable.timer | true/false | 【必选】计时器控制开关 |
enable.bdage | true/false | 【必选】徽标控制开关 |
enable_page | path | 【可选】填写想要应用的页面,如根目录就填’/‘,分类页面就填’/categories/‘。若要应用于所有页面,就填all ,默认为all |
exclude | path | 【可选】填写想要屏蔽的页面,可以多个。仅当enable_page为’all’时生效。写法见示例。原理是将屏蔽项的内容逐个放到当前路径去匹配,若当前路径包含任一屏蔽项,则不会挂载。 |
layout.type | id/class | 【可选】挂载容器类型,填写id或class,不填则默认为id |
layout.name | text | 【必选】挂载容器名称 |
layout.index | 0和正整数 | 【可选】前提是layout.type为class,因为同一页面可能有多个class,此项用来确认究竟排在第几个顺位 |
runtime_js | url | 【必选】页脚计时器脚本,可自行修改。 |
runtime_css | url | 【可选】自定义样式,可自行修改。 |
swiperpara | number | 【可选】若非零,则开启轮播功能,此项表示每行最多容纳徽标个数,用来应对徽标过多显得页脚拥挤的问题 |
bdageitem.link | url | 【可选】页脚徽标指向的网站链接 |
bdageitem.shields | url | 【必选】页脚徽标对应的API |
bdageitem.message | text | 【可选】页脚徽标悬停时显示的信息 |
swiper_css | url | 【可选】swiper的依赖 |
swiper_js | url | 【可选】swiper的依赖 |
swiperbdage_init_js | url | 【可选】swiper初始化方法 |
首页文章轮播
效果预览
查看步骤
1)安装插件,在博客根目录[Blogroot]
下打开终端,运行以下指令:
1 | npm install hexo-butterfly-swiper --save |
2)在站点配置文件或者主题配置文件中添加
1 | # hexo-butterfly-swiper |
3)参数释义
参数 | 备选值/类型 | 释义 |
---|---|---|
priority | number | 【可选】过滤器优先级,数值越小,执行越早,默认为10,选填 |
enable | true/false | 【必选】控制开关 |
enable_page | path/all | 【可选】填写想要应用的页面的相对路径(即路由地址),如根目录就填’/‘,分类页面就填’/categories/‘。若要应用于所有页面,就填’all’,默认为all |
timemode | date/updated | 【可选】时间显示,date为显示创建日期,updated为显示更新日期,默认为date |
layout.type | id/class | 【可选】挂载容器类型,填写id或class,不填则默认为id |
layout.name | text | 【必选】挂载容器名称 |
layout.index | 0和正整数 | 【可选】前提是layout.type为class,因为同一页面可能有多个class,此项用来确认究竟排在第几个顺位 |
default_descr | text | 默认文章描述 |
swiper_css | url | 【可选】自定义的swiper依赖项css链接 |
swiper_js | url | 【可选】自定义的swiper依赖项加js链接 |
custom_css | url | 【可选】适配主题样式补丁 |
custom_js | url | 【可选】swiper初始化方法 |
4)在文章的front_matter
中添加swiper_index
配置项即可:
1 | swiper_index: 1 # 置顶轮播图顺序,非负整数,数字越大越靠前 |
首页分类磁贴
效果预览
查看步骤
修改
\themes\butterfly\layout\index.pug
1
2
3
4
5
6
7
8
9
10extends includes/layout.pug
block content
include ./includes/mixins/post-ui.pug
#recent-posts.recent-posts
+ if theme.categoryBar.enable
+ .recent-post-item(style='height:auto;width:100%;padding:0px;')
+ #categoryBar!= list_categories(site.categories,{class: 'categoryBar',depth: 1})
+postUI
include includes/pagination.pug新建
\themes\butterfly\source\css\_layout\categoryBar.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
100if hexo-config('categoryBar.enable')
#categoryBar
width 100%
ul
&.categoryBar-list
margin 5px 5px 0 5px
padding 0
li
&.categoryBar-list-item
font-weight bold
display inline-block
height 180px
margin 5px .5% 0 .5%
background-image linear-gradient(rgba(0, 0, 0, 0.4) 25%, rgba(16, 16, 16, 0) 100%)
border-radius 10px
padding 25px 0 25px 25px
box-shadow rgba(50, 50, 50, 0.3) 50px 50px 50px 50px inset
overflow hidden
background-size 100%
background-position center
&:hover
background-size 110%
box-shadow inset 500px 50px 50px 50px rgba(50,50,50, 0.6)
span
&.categoryBar-list-count
&::after
transition all .5s
transform translate(-100%, 0)
a
&.categoryBar-list-link
color white
font-size 20px
&::before
content '|'
color white
font-size 20px
&:after
content ''
position relative
width 0
bottom 0
display block
height 3px
border-radius 3px
background-color white
&:hover
&:after
width 90%
left 1%
transition all 0.5s
span
&.categoryBar-list-count
display block
color white
font-size 20px
&::before
content '\f02d'
padding-right 15px
@extend .fontawesomeIcon
&::after
padding 5px
display block
color white
font-size 20px
position relative
right -100%
covers = hexo-config('categoryBar.cover')
for cover,i in covers
li.categoryBar-list-item:nth-child({i+1})
background unquote(cover)
descrs = hexo-config('categoryBar.descr')
for descr,i in descrs
li.categoryBar-list-item:nth-child({i+1})>span::after
content descr
if hexo-config('categoryBar.column') == 'odd'
li
&.categoryBar-list-item
width 32.3%
else if hexo-config('categoryBar.column') == 'even'
li
&.categoryBar-list-item
width 24%
@media screen and (max-width: 650px)
li
&.categoryBar-list-item
width 48%!important
height 150px!important
margin 5px 1% 0 1%!important
$caterow = hexo-config('categoryBar.row')?hexo-config('categoryBar.row'):2
.categoryBar-list
max-height 190px * $caterow
overflow auto
&::-webkit-scrollbar
width 0!important
@media screen and (max-width: 650px)
.categoryBar-list
max-height 160px * $caterow在
_config.butterfly.yml
添加配置项1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18categoryBar:
enable: true
column: odd # 显示列数,odd:3列 | even:4列
row: 1 #显示行数,默认两行,超过行数切换为滚动显示
descr:
- 长篇小说连载
- 杂谈教程
- 玩转Win10
- Ubuntu指南
- 个人日记
- 诗词歌赋
cover:
- url('https://cdn.jsdelivr.net/npm/akilar-candyassets/image/cover1.webp')
- '#abcdef' # HEX格式色值需要用''包裹,不然会被识别成注释
- rgba(45,67,89,0.7)
- linear-gradient(rgba(0, 0, 0, 0.4) 25%, rgba(200,16 , 16, 0) 100%)
- url('https://cdn.jsdelivr.net/npm/akilar-candyassets/image/cover5.webp')
- url('https://cdn.jsdelivr.net/npm/akilar-candyassets/image/cover6.webp')
天气时钟
效果预览
查看步骤
安装插件
1
npm install hexo-butterfly-clock --save
配置插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14# electric_clock
# see https://akilar.top/posts/4e39cf4a/
electric_clock:
enable: true # 开关
priority: 5 #过滤器优先权
enable_page: all # 应用页面
exclude:
# - /posts/
# - /about/
layout: # 挂载容器类型
type: class
name: sticky_layout
index: 0
loading: /img/loading.gif #加载动画自定义
Echarts 统计图表
由于得关闭 pjax 才能显示(暂不清楚原因),就不放了。还是舍不得关掉 pjax。
效果预览
查看步骤
1)在主题配置文件引进 Echarts
1 | inject: |
新建
[Blogroot]\themes\butterfly\scripts\helpers\hexo_echarts.js
(文件名称可以自定义), 添加tag_ranking_bar
函数: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// 标签统计柱状图
hexo.extend.helper.register('tag_ranking_bar', function (options) {
const { type, id, topNum, title, color, yAxisName, seriesName } = options
// id 和 type 必须指定
if (!id || !type) return
// 获取 tags 标签页信息
const tagArr = []
hexo.locals.get('tags').map(function (tag) {
tagArr.push([tag.name, tag.length])
})
// 对数组进行排序,然后取 top 10
tagArr.sort((x, y) => { return y[0] - x[0] })
const echarts_obj = {
tag: tagArr.slice(0, topNum)
}
return `
<script type="text/javascript" id="${id}">
var themeMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
var tagsChart = echarts.init(document.getElementById("${id}"),themeMode);
// 指定图表的配置项和数据
var tagsOption = {
color: "${color}",
backgroundColor: '',
title: {
text: "${title}",
x: 'center'
},
dataset: [
{
dimensions: ['name', 'count'],
source: ${JSON.stringify(echarts_obj[type])}
},
{
transform: {
type: 'sort',
config: { dimension: 'count', order: 'desc' }
}
}
],
tooltip: {},
xAxis: {
type: 'category'
},
yAxis: {
name: "${yAxisName}",
type: 'value',
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
show: true
}
},
series: {
name: "${seriesName}",
type: 'bar',
encode: { x: 'name', y: 'count' },
datasetIndex: 1,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#83bff6' },
{ offset: 0.5, color: '#188df0' },
{ offset: 1, color: '#188df0' }
])
},
emphasis: {
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#2378f7' },
{ offset: 0.7, color: '#2378f7' },
{ offset: 1, color: '#83bff6' }
])
}
},
markPoint: {
symbolSize: 45,
data: [
{
type: 'max',
itemStyle: { color: '#425aef' },
name: '最大值'
},
{
type: 'min',
itemStyle: { color: '#425aef' },
name: '最小值'
}
]
},
markLine: {
itemStyle: { color: '#425aef' },
data: [{ type: 'average', name: '平均值' }]
}
}
};
// 使用刚指定的配置项和数据显示图表。
tagsChart.setOption(tagsOption);
window.addEventListener("resize", () => {
tagsChart.resize();
});
</script>`
})在
[Blogroot]\themes\butterfly\layout\includes\page\tags.pug
中添加 :1
2#tag-echarts(style="height:320px")
!=tag_ranking_bar({type:'tag',id:'tag-echarts',topNum:10,title:'Top 10 标签统计图',color:theme.theme_color,yAxisName:'文章篇数',seriesName:'标签统计'})
在
[Blogroot]\themes\butterfly\scripts\helpers\hexo_echarts.js
添加categories_pic
函数: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
50hexo.extend.helper.register('categories_pic', function (options) {
const { id, title, seriesName } = options
// id 必须指定
if (!id) return
const categoryArr = []
hexo.locals.get('categories').map(function (category) {
categoryArr.push({ name: category.name, value: category.length })
})
return `
<script type="text/javascript" id="${id}">
var themeMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
var categoriesChart = echarts.init(document.getElementById("${id}"),themeMode);
// 指定图表的配置项和数据
var categoriesOption = {
backgroundColor:'',
title:{
text:'${title}',
x:'center'
},
tooltip:{
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
legend: {
icon: "circle",
top: 'bottom'
},
series: [
{
name: '${seriesName}',
type: 'pie',
radius: [40, 150],
center: ['50%', '48%'],
roseType: 'area',
itemStyle: {
borderRadius: 8
},
label: {
formatter: "{b} : {c} ({d}%)"
},
data: ${JSON.stringify(categoryArr)}
}
]
};
// 使用刚指定的配置项和数据显示图表。
categoriesChart.setOption(categoriesOption);
window.addEventListener("resize", () => {
categoriesChart.resize();
});
</script>`
})在
[Blogroot]\themes\butterfly\layout\includes\page\categories.pug
添加:1
2#categories-echarts(style="height:400px")
!=categories_pic({id:'categories-echarts',title:'文章分类统计图',seriesName:'分类统计'})
在
[Blogroot]\themes\butterfly\scripts\helpers\hexo_echarts.js
添加posts_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
79hexo.extend.helper.register('posts_echarts', function (options) {
let { title, id, seriesName } = options
var moment = require('moment');
const startDate = moment().subtract(1, 'years').startOf('month')
const endDate = moment().endOf('month')
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)
}
})
let postsArr = [...monthMap.entries()]
return `
<script type="text/javascript" id="${id}">
var themeMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
var postsChart = echarts.init(document.getElementById("${id}"),themeMode);
let postsOption = {
color: ['#425aef'],
title:{
text:'${title}',
x:'center'
},
tooltip:{
trigger: 'axis',
axisPointer: {
type: 'shadow',
shadowStyle:{
color:'rgba(66,90,239,0.3)'
}
},
},
xAxis: {
type: 'category',
boundaryGap: false
},
yAxis: {
name:'${seriesName}',
axisLine: {
show: true
}
},
series: [
{
name:'${seriesName}',
type: 'line',
smooth:true,
symbol: 'none',
lineStyle: {
color: '#425aef',
width: 1
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#425aef',
}, {
offset: 1,
color: '#FFFFFF'
}])
},
data: ${JSON.stringify(postsArr)}
}
]
};
postsChart.setOption(postsOption);
window.addEventListener("resize", () => {
postsChart.resize();
});
</script>`
})
2)执行 hexo new page echarts
,新增菜单
1 | hexo new page echarts |
3)主题配置文件:
1 | menu: |
4)在 [Blogroot]\source\echarts\index.md
添加 type: 'echarts'
:
5)在 [Blogroot]\themes\butterfly\layout\page.pug
大约 15
行处添加:
1 | case page.type |
6)新增文件 [Blogroot]\themes\butterfly\layout\includes\page\echarts.pug
:
1 | //- 文章发布统计图 |
7)主题配置文件关闭 Pjax
为了让页面刷新以显示图表,暂不清楚原因。当然也可以使用 exclude
去排除
1 | pjax: |
添加右键菜单
效果预览
查看步骤
在
[Blogroot]\themes\butterfly\layout\includes\third-party\
目录下新建galmenu.pug
文件1
2
3
4
5
6
7
8#rightMenu
each MenuItem,index in theme.GalMenu.MenuGuoup
.rightMenu-group
each item in MenuItem.MenuItem
a.rightMenu-item.faa-parent.animated-hover(href=url_for(item.link),title=item.name,id=item.id)
i.fa.faa-tada(class=item.icon)
if index != 0
span.rightMenu-name=item.name修改
[Blogroot]\themes\butterfly\layout\includes\additional-js.pug
文件,在末尾添加内容(注意缩进), 注意butterfly_v3.6.0
取消了缓存配置,转为完全默认,需要将{cache:theme.fragment_cache}
改为{cache: true}
1
2+ if theme.GalMenu.enable
+ !=partial('includes/third-party/galmenu', {}, {cache: true})在
[Blogroot]\themes\butterfly\source\css\_layout\
目录下新建galmenu.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/* rightMenu */
#rightMenu {
display: none;
position: fixed;
width: 160px;
height: fit-content;
top: 10%;
left: 10%;
background-color: var(--card-bg);
border: 1px solid var(--style-border);
border-radius: 8px;
z-index: 100;
box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.35);
}
#rightMenu .rightMenu-group {
padding: 7px 6px;
&:nth-child(1) {
display: flex;
align-items: center;
justify-content: space-around;
}
&:not(:nth-last-child(1)) {
border-bottom: 2px dashed #425aef;
}
&:not(:nth-child(1)) .rightMenu-item {
margin: 0.25rem 0;
}
.rightMenu-item {
height: 30px;
line-height: 30px;
border-radius: 8px;
transition: 0.3s;
color: var(--font-color);
display: flex;
&:hover {
background-color: var(--text-bg-hover);
color: var(--cyan-white);
}
i {
display: inline-block;
text-align: center;
line-height: 30px;
width: 30px;
height: 30px;
padding: 0 5px;
}
span.rightMenu-name {
line-height: 30px;
margin-left: 5px;
letter-spacing: 5px;
}
}
}
.rightMenu-group.hide {
display: none;
}新建
[Blogroot]\themes\butterfly\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
43let weijin = {};
weijin.showRightMenu = function (isTrue, x = 0, y = 0) {
let $rightMenu = document.getElementById('rightMenu');
$rightMenu.style.top = x + 'px';
$rightMenu.style.left = y + 'px';
if (isTrue) {
$rightMenu.style.display="block";
} else {
$rightMenu.style.display="none";
}
}
// 右键菜单事件
if (!(navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
window.oncontextmenu = function (event) {
var rightMenu_group_hide = document.getElementsByClassName('rightMenu-group.hide');
for (var i=0;i<rightMenu_group_hide.length;i++) {
rightMenu_group_hide[i].style.display="none";
}
if (document.getSelection().toString()) {
document.getElementById('menu-tools').style.display="block";
}
if (event.ctrlKey) return true;
if (localStorage.getItem("right_menu_switch") === 'off') return true
let pageX = event.clientX + 10;
let pageY = event.clientY;
let rmWidth = document.getElementById('rightMenu').style.width;
let rmHeight = document.getElementById('rightMenu').style.height;
if (pageX + rmWidth > window.innerWidth) {
pageX -= rmWidth + 10;
}
if (pageY + rmHeight > window.innerHeight) {
pageY -= pageY + rmHeight - window.innerHeight;
}
weijin.showRightMenu(true, pageY, pageX);
return false;
};
window.addEventListener('click', function () { weijin.showRightMenu(false); });
}在主题配置文件添加如下配置项
1
2
3inject:
bottom:
- <script async src="/js/custom.js"></script>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# 自定义右键菜单
GalMenu:
enable: true # true or false 是否开启右键
MenuGuoup:
- MenuItem: #菜单配置
- name: 后退
icon: fa fa-arrow-left
link: javascript:history.go(-1);
- name: 前进
icon: fa fa-arrow-right
link: javascript:history.go(1);
- name: 刷新
icon: fa fa-refresh
link: javascript:location.reload()
- name: 返回顶部
icon: fa fa-arrow-up
link: '#'
- MenuItem:
- name: 回到主页
icon: fas fa-home
link: '/'
- name: 博客统计
icon: fa fa-area-chart
link: '/echarts/'
- MenuItem:
- name: 昼夜模式
icon: fas fa-adjust
link: javascript:switchNightMode()
随机文章
查看步骤
在
主题根目录\scripts\
目录下新建random.js
文件1
2
3
4
5
6
7
8
9
10
11hexo.extend.generator.register('random', function (locals) {
const config = hexo.config.random || {}
const posts = []
for (const post of locals.posts.data) {
if (post.random !== false) posts.push(post.path)
}
return {
path: config.path || 'random/index.html',
data: `<html><head><script>var posts=${JSON.stringify(posts)};window.open('/'+posts[Math.floor(Math.random() * posts.length)],"_self")</script></head></html>`
}
})使用
/random/
即可访问随机文章
唯一文章链接
查看步骤
Hexo默认的静态URL格式是
:year/:month/:day/:title
,也就是按照年、月、日、标题来生成固定链接的。如http://xxx.yy.com/2020/07/06/hello-world
这种默认配置的缺点就是一般文件名是中文,导致
url
链接里有中文出现,这会造成很多问题,也不利于 `seo ,另外就是年月日都会有分隔符。知识点:
百度蜘蛛抓取网页的规则: 对于蜘蛛说网页权重越高、信用度越高抓取越频繁,例如网站的首页和内页。蜘蛛先抓取网站的首页,因为首页权重更高,并且大部分的链接都是指向首页。然后通过首页抓取网站的内页,并不是所有内页蜘蛛都会去抓取。
搜索引擎认为对于一般的中小型站点,3层足够承受所有的内容了,所以蜘蛛经常抓取的内容是前三层,而超过三层的内容蜘蛛认为那些内容并不重要,所以不经常爬取。出于这个原因所以permalink后面跟着的最好不要超过2个斜杠。
对于这个问题,使用 hexo-abbrlink 插件可以完美解决。
在博客根目录
[Blogroot]
下打开终端,运行以下指令安装 hexo-abbrlink 插件1
npm install hexo-abbrlink --save
修改文件
[Blogroot]\_config.yml
1
2
3
4
5#设置永久链接
permalink: posts/:abbrlink.html # 此处可以自己设置,也可以直接使用 :/abbrlink
abbrlink:
alg: crc16 #算法: crc16(default) and crc32
rep: dec #进制: dec(default) and hexAbbrlink
插件拥有两项设置选项:- alg: 算法(目前支持
crc16
和crc32
算法,默认值是crc16
) - rep: 形式(生成的链接可以是十六进制格式也可以是十进制格式,默认值是十进制格式)
生成的链接将会是这样的(官方样例):
1
2
3
4
5
6
7
8
9
10crc16 & hex
https://post.zz173.com/posts/66c8.html
crc16 & dec
https://post.zz173.com/posts/65535.html
crc32 & hex
https://post.zz173.com/posts/8ddf18fb.html
crc32 & dec
https://post.zz173.com/posts/1690090958.html生成完后,原
md
文件的Front-matter
内会增加abbrlink
字段,值为生成的ID
。这个字段确保了在修改了Front-matter
内的博客标题title
或创建日期date
字段之后而不会改变链接地址。- 注意在生成之前就要改好算法和形式,不然后面再改的话会导致链接不统一。
- 刚使用这个插件后,阅读人数和评论都会变为0,介意慎用!综上所述,这插件适合新站!
- alg: 算法(目前支持
最后执行
hexo
命令三连:hexo c
、hexo g
、hexo s
,即可看到效果
标签右上角添加章数
查看步骤
修改 [Blogroot]\themes\butterfly\scripts\helpers\page.js
,在约第 52
行处:
1 | source.forEach(tag => { |
修改滚动条样式
查看步骤
在主题根目录 source/css/custom.css
中添加如下代码
1 | /* 滚动条 */ |
首页文章卡片修改
效果预览
查看步骤
修改
[Blogroot]\themes\butterfly\layout\includes\mixins\post-ui.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
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
115mixin postUI(posts)
each article , index in page.posts.data
.recent-post-item
-
let link = article.link || article.path
let title = article.title || _p('no_title')
const position = theme.cover.position
let leftOrRight = position === 'both'
? index%2 == 0 ? 'left' : 'right'
: position === 'left' ? 'left' : 'right'
let post_cover = article.cover
let no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
-
.recent-post-content(class=leftOrRight)
a.article-content(href=url_for(link) title=subtitle)
//- Display the article introduction on homepage
case theme.index_post_content.method
when false
- break
when 1
.article-content-text!= article.description
when 2
if article.description
.article-content-text!= article.description
else
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert += ' ...' : ''
.article-content-text!= expert
default
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert += ' ...' : ''
.article-content-text!= expert
.recent-post-info
a.article-title(href=url_for(link) title=subtitle)
.article-title-link= title
.recent-post-meta
.article-meta-wrap
if (is_home() && (article.top || article.sticky > 0))
span.article-meta
i.fas.fa-thumbtack.sticky
span.sticky= _p('sticky')
span.article-meta-separator |
if (theme.post_meta.page.date_type)
span.post-meta-date
if (theme.post_meta.page.date_type === 'both')
i.far.fa-calendar-alt
span.article-meta-label=_p('post.created')
time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))=date(article.date, config.date_format)
span.article-meta-separator |
i.fas.fa-history
span.article-meta-label=_p('post.updated')
time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))=date(article.updated, config.date_format)
else
- let data_type_updated = theme.post_meta.page.date_type === 'updated'
- let date_type = data_type_updated ? 'updated' : 'date'
- let date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt'
- let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
i(class=date_icon)
span.article-meta-label=date_title
time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))=date(article[date_type], config.date_format)
if (theme.post_meta.page.categories && article.categories.data.length > 0)
span.article-meta
span.article-meta-separator |
i.fas.fa-inbox
each item, index in article.categories.data
a(href=url_for(item.path)).article-meta__categories #[=item.name]
if (index < article.categories.data.length - 1)
i.fas.fa-angle-right.article-meta-link
if (theme.post_meta.page.tags && article.tags.data.length > 0)
span.article-meta.tags
span.article-meta-separator |
i.fas.fa-tag
each item, index in article.tags.data
a(href=url_for(item.path)).article-meta__tags #[=item.name]
if (index < article.tags.data.length - 1)
span.article-meta-link #[='•']
mixin countBlockInIndex
- needLoadCountJs = true
span.article-meta
span.article-meta-separator |
i.fas.fa-comments
if block
block
span.article-meta-label= ' ' + _p('card_post_count')
if theme.comments.card_post_count
case theme.comments.use[0]
when 'Disqus'
when 'Disqusjs'
+countBlockInIndex
a(href=full_url_for(link) + '#disqus_thread')
when 'Valine'
+countBlockInIndex
a(href=url_for(link) + '#post-comment' itemprop="discussionUrl")
span.valine-comment-count(data-xid=url_for(link) itemprop="commentCount")
when 'Waline'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.waline-comment-count(id=url_for(link))
when 'Twikoo'
+countBlockInIndex
a.twikoo-count(href=url_for(link) + '#post-comment')
when 'Facebook Comments'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
.recent-post-cover
img.article-cover(src=url_for(post_cover) onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'` alt=subtitle)
if theme.ad && theme.ad.index
if (index + 1) % 3 == 0
.recent-post-item.ads-wrap!=theme.ad.index修改
[Blogroot]\themes\butterfly\source\css\_page\homepage.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
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//default color:
:root
--recent-post-bgcolor: rgba(255, 255, 255, 0.9)
--article-content-bgcolor: #49b1f5
--recent-post-triangle: #fff
--recent-post-cover-shadow: #ffffff
[data-theme="dark"]
--recent-post-bgcolor: rgba(35,35,35,0.5)
--article-content-bgcolor: #99999a
--recent-post-triangle: #37e2dd
--recent-post-cover-shadow: #232323
.recent-posts
padding 0 15px 0 15px
.recent-post-item
margin-bottom 15px
width 100%
background var(--recent-post-bgcolor)
overflow hidden
border-radius 15px
.recent-post-info
.article-title-link
display -webkit-box
-webkit-box-orient vertical
-webkit-line-clamp 2
overflow hidden
.article-content
background var(--article-content-bgcolor)
position relative
display flex
align-items: center;
justify-content: center;
.article-content-text
transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
display -webkit-box
-webkit-box-orient vertical
-webkit-line-clamp 4
text-overflow: ellipsis
overflow hidden
color #fff
text-shadow: 1px 2px 3px #000;
.recent-post-cover
position relative
background transparent
img
&.article-cover
height 100%
width 100%
object-fit cover
.recent-post-info
align-items center
flex-direction column
position relative
background var(--recent-post-bgcolor)
display flex
color #000000
.article-title
height 50%
font-size 24px
display: flex
align-items: center
justify-content: flex-end
flex-direction: column
.article-title-link
color: var(--text-highlight-color)
transition: all .2s ease-in-out
&:hover
color: $text-hover
.recent-post-meta
height 50%
display: flex
align-items: center
justify-content: flex-start
flex-direction: column
.article-meta-wrap
font-size 12px
color #969797
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
a
color: var(--text-highlight-color)
transition: all .2s ease-in-out
color #969797
&:hover
color: $text-hover
&.ads-wrap
display: block
height: auto
@media screen and (min-width:600px)
.recent-post-item
&:hover
.recent-post-content
&.both,
&.right
transform translateX(21%)
transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
&::before
transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
left: 50px;
.article-content-text
margin 20px 20px 20px 60px
&.left
transform translateX(-21%)
transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
&::before
transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
right: 50px;
.article-content-text
margin 20px 60px 20px 20px
.recent-post-content
background var(--recent-post-bgcolor)
position relative
height 200px
width 130%
z-index 0
display flex
overflow hidden
border 0px solid
&::before
content: "";
width: 0;
height: 0;
background: transparent;
position: absolute;
z-index: 3;
top: calc(50% - 10px);
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
transition: all .5s cubic-bezier(0.59, 0.01, 0.48, 1.17)
&.both,
&.right
flex-direction: row;
left calc(-23.07% - 41px)
transition: all .5s cubic-bezier(0.59, 0.01, 0.48, 1.17)
&::before
left: calc(23.07% + 40px);
border-left: 6px solid var(--recent-post-triangle);
.recent-post-info
&::before
background linear-gradient(to right, var(--recent-post-cover-shadow), transparent)
left calc(100% - 1px)
.article-content
&::before
right -59px
border-left 60px solid var(--article-content-bgcolor)
.article-content-text
margin 20px 20px 20px 0px
.article-title
padding 0px 30px 0px 70px
.recent-post-meta
padding 0px 20px 0px 70px
&.left
flex-direction: row-reverse;
right 9px
transition: all .5s cubic-bezier(0.59, 0.01, 0.48, 1.17)
&::before
right: calc(23.07% + 40px);
border-right: 6px solid var(--recent-post-triangle);
.recent-post-info
&::before
background linear-gradient(to left, var(--recent-post-cover-shadow), transparent)
right calc(100% - 1px)
.article-content
&::before
left -59px
border-right 60px solid var(--article-content-bgcolor)
.article-content-text
margin 20px 0px 20px 20px
.article-title
padding 0px 70px 0px 30px
.recent-post-meta
padding 0px 70px 0px 20px
.article-content
width 30%
height 200px
left 0
align-items center
&::before
content ""
width 0
height 0
background transparent
position absolute
z-index 2
top 0
border-top 100px solid transparent
border-bottom 100px solid transparent
.recent-post-info
width 60%
height 200px
&::before
content ""
width 200px
height 200px
position absolute
z-index 1
top 0
.recent-post-meta
& > .article-meta-wrap
margin: 6px 0
color: $theme-meta-color
font-size: 90%
& > .post-meta-date
cursor: default
.sticky
color: $sticky-color
i
margin: 0 4px 0 0
.article-meta-label
if hexo-config('post_meta.page.label')
padding-right: 4px
else
display: none
.article-meta-separator
margin: 0 6px
.article-meta-link
margin: 0 4px
if hexo-config('post_meta.page.date_format') == 'relative'
time
display: none
a
color: $theme-meta-color
&:hover
color: $text-hover
text-decoration: underline
.recent-post-cover
width 40%
height 200px
@media screen and (max-width:600px)
.recent-post-item
height 400px
.recent-post-content
display flex
flex-direction: column
height 400px
.article-content
pointer-events none
order: 1;
height: 200px;
position: absolute;
width: calc(100% - 40px);
z-index: 3;
background: rgba(22,22,22,0.5);
border-top-left-radius: 15px;
border-top-right-radius: 15px;
display: none
opacity: 0
.article-content-text
height 120px
color: white;
width: 80%
.recent-post-cover
order: 2
height 200px
transition: all .5s
.recent-post-info
order: 3
height 200px
&::before
content: '';
width: 0;
height: 0;
position: absolute;
z-index: 3;
bottom: calc(100% - 4px);
left: 0;
border-bottom: 50px solid var(--recent-post-bgcolor);
border-right: 300px solid transparent;
&::after
content: '';
width: 0;
height: 0;
position: absolute;
z-index: 3;
bottom: calc(100% + 150px);
right: 0;
border-top: 50px solid var(--recent-post-bgcolor);
border-left: 300px solid transparent;
.article-title
padding: 0px 35px 0px 35px
.recent-post-meta
padding: 0px 30px 0px 30px
&:hover
.article-content
display: flex ;
animation: shutter-effect-content 0.5s 2 forwards linear
.recent-post-info
&::before
animation: shutter-effect-left 0.5s 1 ease-in-out
&::after
animation: shutter-effect-right 0.5s 1 ease-in-out
.recent-post-cover
filter blur(2px)
@keyframes shutter-effect-right {
0%{
bottom: calc(100% + 150px);
border-top: 50px solid var(--recent-post-bgcolor);
border-left: 300px solid transparent;
}
50%{
bottom: 100%;
border-top: 200px solid var(--recent-post-bgcolor);
border-left: 600px solid transparent;
}
100%{
bottom: calc(100% + 150px);
border-top: 50px solid var(--recent-post-bgcolor);
border-left: 300px solid transparent;
}
}
@keyframes shutter-effect-left {
0%{
bottom: calc(100% - 4px);
border-bottom: 50px solid var(--recent-post-bgcolor);
border-right: 300px solid transparent;
}
50%{
bottom: calc(100% - 4px);
border-bottom: 200px solid var(--recent-post-bgcolor);
border-right: 600px solid transparent;
}
100%{
bottom: calc(100% - 4px);
border-bottom: 50px solid var(--recent-post-bgcolor);
border-right: 300px solid transparent;
}
}
@keyframes shutter-effect-content {
from {
opacity: 0
}
to {
opacity: 1
}
}
源代码
这里记录原来的代码,以便以后想换回去。
post-ui.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
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
128mixin postUI(posts)
each article , index in page.posts.data
.recent-post-item
-
let link = article.link || article.path
let title = article.title || _p('no_title')
const position = theme.cover.position
let leftOrRight = position === 'both'
? index%2 == 0 ? 'left' : 'right'
: position === 'left' ? 'left' : 'right'
let post_cover = article.cover
let no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
-
if post_cover && theme.cover.index_enable
.post_cover(class=leftOrRight)
a(href=url_for(link) title=title)
img.post_bg(src=url_for(post_cover) onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'` alt=title)
.recent-post-info(class=no_cover)
a.article-title(href=url_for(link) title=title)= title
.article-meta-wrap
if (is_home() && (article.top || article.sticky > 0))
span.article-meta
i.fas.fa-thumbtack.sticky
span.sticky= _p('sticky')
span.article-meta-separator |
if (theme.post_meta.page.date_type)
span.post-meta-date
if (theme.post_meta.page.date_type === 'both')
i.far.fa-calendar-alt
span.article-meta-label=_p('post.created')
time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))=date(article.date, config.date_format)
span.article-meta-separator |
i.fas.fa-history
span.article-meta-label=_p('post.updated')
time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))=date(article.updated, config.date_format)
else
- let data_type_updated = theme.post_meta.page.date_type === 'updated'
- let date_type = data_type_updated ? 'updated' : 'date'
- let date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt'
- let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
i(class=date_icon)
span.article-meta-label=date_title
time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))=date(article[date_type], config.date_format)
if (theme.post_meta.page.categories && article.categories.data.length > 0)
span.article-meta
span.article-meta-separator |
i.fas.fa-inbox
each item, index in article.categories.data
a(href=url_for(item.path)).article-meta__categories #[=item.name]
if (index < article.categories.data.length - 1)
i.fas.fa-angle-right.article-meta-link
if (theme.post_meta.page.tags && article.tags.data.length > 0)
span.article-meta.tags
span.article-meta-separator |
i.fas.fa-tag
each item, index in article.tags.data
a(href=url_for(item.path)).article-meta__tags #[=item.name]
if (index < article.tags.data.length - 1)
span.article-meta-link #[='•']
mixin countBlockInIndex
- needLoadCountJs = true
span.article-meta
span.article-meta-separator |
i.fas.fa-comments
if block
block
span.article-meta-label= ' ' + _p('card_post_count')
if theme.comments.card_post_count
case theme.comments.use[0]
when 'Disqus'
+countBlockInIndex
a(href=full_url_for(link) + '#disqus_thread')
i.fa-solid.fa-spinner.fa-spin
when 'Disqusjs'
+countBlockInIndex
a(href=full_url_for(link) + '#disqusjs')
span.disqus-comment-count(data-disqus-url=full_url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Valine'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.valine-comment-count(data-xid=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Waline'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.waline-comment-count(id=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Twikoo'
+countBlockInIndex
a.twikoo-count(href=url_for(link) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Facebook Comments'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
i.fa-solid.fa-spinner.fa-spin
when 'Remark42'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.remark42__counter(data-url=urlNoIndex(article.permalink))
i.fa-solid.fa-spinner.fa-spin
//- Display the article introduction on homepage
case theme.index_post_content.method
when false
- break
when 1
.content!= article.description
when 2
if article.description
.content!= article.description
else
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert += ' ...' : ''
.content!= expert
default
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert += ' ...' : ''
.content!= expert
if theme.ad && theme.ad.index
if (index + 1) % 3 == 0
.recent-post-item.ads-wrap!=theme.ad.indexhomepage.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#recent-posts
& > .recent-post-item:not(:first-child)
margin-top: 20px
& > .recent-post-item
@extend .cardHover
display: flex
flex-direction: row
align-items: center
overflow: hidden
height: 18em
+maxWidth768()
flex-direction: column
height: auto
&:hover
img.post_bg
transform: scale(1.1)
&.ads-wrap
display: block
height: auto
.post_cover
overflow: hidden
width: 44%
height: 100%
+maxWidth768()
width: 100%
height: 230px
img.post_bg
@extend .imgHover
&.right
order: 1
+maxWidth768()
order: 0
& >.recent-post-info
padding: 0 40px
width: 57%
+maxWidth768()
padding: 20px 20px 30px
width: 100%
&.no-cover
width: 100%
+maxWidth768()
padding: 30px 20px
& > .article-title
@extend .limit-more-line
color: var(--text-highlight-color)
font-size: 1.72em
line-height: 1.4
transition: all .2s ease-in-out
-webkit-line-clamp: 2
+maxWidth768()
font-size: 1.43em
&:hover
color: $text-hover
& > .article-meta-wrap
margin: 6px 0
color: $theme-meta-color
font-size: 90%
& > .post-meta-date
cursor: default
.sticky
color: $sticky-color
i
margin: 0 4px 0 0
.fa-spinner
margin: 0
.article-meta-label
if hexo-config('post_meta.page.label')
padding-right: 4px
else
display: none
.article-meta-separator
margin: 0 6px
.article-meta-link
margin: 0 4px
if hexo-config('post_meta.page.date_format') == 'relative'
time
display: none
a
color: $theme-meta-color
&:hover
color: $text-hover
text-decoration: underline
& > .content
@extend .limit-more-line
-webkit-line-clamp: 2
和风天气组件
效果预览
查看步骤
前往 和风天气,创建
天气简约插件
插件名称
随意,调整配置选项后生成代码
自定义颜色、背景颜色透明、其它默认即可。
在
Hexo\themes\butterfly\source\js\
路径下新建weather.js
文件,将生成的代码复制进去1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21WIDGET = {
"CONFIG": {
"modules": "012",
"background": "5",
"tmpColor": "000000",
"tmpSize": "16",
"cityColor": "000000",
"citySize": "16",
"aqiColor": "FFFFFF",
"aqiSize": "16",
"weatherIconSize": "24",
"alertIconSize": "18",
"padding": "10px 10px 10px 10px",
"shadow": "0",
"language": "auto",
"fixed": "false",
"vertical": "top",
"horizontal": "left",
"key": "646fc52deb604b34a9491cd6bab08e9c"
}
}在主题配置文件中找到
inject
的bottom
处引入以下两个js文件1
2- <script defer data-pjax src="/js/weather.js"></script>
- <script defer data-pjax src="https://widget.qweather.net/simple/static/js/he-simple-common.js?v=2.0"></script>在
\themes\butterfly\layout\includes\header
路径下找到nav.pug
文件,添加如下代码,注意位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18nav#nav
span#blog_name
a#site-name(href=url_for('/')) #[=config.title]
+ #he-plugin-simple
+ #none_space
#menus
if (theme.algolia_search.enable || theme.local_search.enable)
#search-button
a.site-page.social-icon.search
i.fas.fa-search.fa-fw
span=' '+_p('search.title')
!=partial('includes/header/menu_item', {}, {cache: true})
#toggle-menu
a.site-page
i.fas.fa-bars.fa-fw之后在
\themes\butterfly\source\css\_layout\head.styl
中将#blog_name
替换为#none_space
就完成了。