Hexo matery 功能个性优化

声明:本文是参考会飞的小戈和·Sky03’s Blog
这俩位位大佬的进行优化

一、访问速度优化

1、页面加载动画

主目录下新建一个文件夹(也就是你的blog目录下),名为scripts,紧接着在新建的文件夹下新建一个名为loading-pages的js文件,然后再这个js文件填入下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/* global hexo */
"use strict";
hexo.extend.filter.register('after_render:html', function (htmlContent) {
const injectHead =
`<style type="text/css" lang="css">
#loading-container{
position: fixed;
top: 0;
left: 0;
min-height: 100vh;
width: 100vw;
z-index: 9999;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: #FFF;
text-align: center;
/* loader页面消失采用渐隐的方式*/
-webkit-transition: opacity 1s ease;
-moz-transition: opacity 1s ease;
-o-transition: opacity 1s ease;
transition: opacity 1s ease;
}
.loading-image{
width: 120px;
height: 50px;
transform: translate(-50%);
}

.loading-image div:nth-child(2) {
-webkit-animation: pacman-balls 1s linear 0s infinite;
animation: pacman-balls 1s linear 0s infinite
}

.loading-image div:nth-child(3) {
-webkit-animation: pacman-balls 1s linear .33s infinite;
animation: pacman-balls 1s linear .33s infinite
}

.loading-image div:nth-child(4) {
-webkit-animation: pacman-balls 1s linear .66s infinite;
animation: pacman-balls 1s linear .66s infinite
}

.loading-image div:nth-child(5) {
-webkit-animation: pacman-balls 1s linear .99s infinite;
animation: pacman-balls 1s linear .99s infinite
}

.loading-image div:first-of-type {
width: 0;
height: 0;
border: 25px solid #49b1f5;
border-right-color: transparent;
border-radius: 25px;
-webkit-animation: rotate_pacman_half_up .5s 0s infinite;
animation: rotate_pacman_half_up .5s 0s infinite;
}
.loading-image div:nth-child(2) {
width: 0;
height: 0;
border: 25px solid #49b1f5;
border-right-color: transparent;
border-radius: 25px;
-webkit-animation: rotate_pacman_half_down .5s 0s infinite;
animation: rotate_pacman_half_down .5s 0s infinite;
margin-top: -50px;
}
@-webkit-keyframes rotate_pacman_half_up {0% {transform: rotate(270deg)}50% {transform: rotate(1turn)}to {transform: rotate(270deg)}}

@keyframes rotate_pacman_half_up {0% {transform: rotate(270deg)}50% {transform: rotate(1turn)}to {transform: rotate(270deg)}}

@-webkit-keyframes rotate_pacman_half_down {0% {transform: rotate(90deg)}50% {transform: rotate(0deg)}to {transform: rotate(90deg)}}

@keyframes rotate_pacman_half_down {0% {transform: rotate(90deg)}50% {transform: rotate(0deg)}to {transform: rotate(90deg)}}

@-webkit-keyframes pacman-balls {75% {opacity: .7}to {transform: translate(-100px, -6.25px)}}

@keyframes pacman-balls {75% {opacity: .7}to {transform: translate(-100px, -6.25px)}}


.loading-image div:nth-child(3),
.loading-image div:nth-child(4),
.loading-image div:nth-child(5),
.loading-image div:nth-child(6){
background-color: #49b1f5;
width: 15px;
height: 15px;
border-radius: 100%;
margin: 2px;
width: 10px;
height: 10px;
position: absolute;
transform: translateY(-6.25px);
top: 25px;
left: 100px;
}
.loading-text{
margin-bottom: 20vh;
text-align: center;
color: #2c3e50;
font-size: 2rem;
box-sizing: border-box;
padding: 0 10px;
text-shadow: 0 2px 10px rgba(0,0,0,0.2);
}
@media only screen and (max-width: 500px) {
.loading-text{
font-size: 1.5rem;
}
}
.fadeout {
opacity: 0;
filter: alpha(opacity=0);
}
/* logo出现动画 */
@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}
@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);}}
</style>
<script>
(function () {
const loaded = function(){
setTimeout(function(){
const loader = document.getElementById("loading-container");
loader.className="fadeout" ;//使用渐隐的方法淡出loading page
// document.getElementById("body-wrap").style.display="flex";
setTimeout(function(){
loader.style.display="none";
},1000);
},1000);//强制显示loading page 1s
};
loaded();
})()
</script>`;
const injectBody = `
<div id="loading-container">
<p class="loading-text">玩命加载中 . . . </p>
<div class="loading-image">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>`;
if (/<\/head>/gi.test(htmlContent)) {
let lastIndex = htmlContent.lastIndexOf('</head>');
htmlContent = htmlContent.substring(0, lastIndex) + injectHead + htmlContent.substring(lastIndex, htmlContent.length);
}
if (/<body>/gi.test(htmlContent)) {
let index = htmlContent.indexOf('<body>');
htmlContent = htmlContent.substring(0, index) + injectBody + htmlContent.substring(index, htmlContent.length);
}
return htmlContent;
}, 1);

2、图片加载优化

在此之前,我们先了解什么是预加载懒加载

什么是预加载

预加载就是进入项目前提前加载资源,避免在项目中加载缓慢,影响用户体验

  • 缺点:会增加服务器压力

什么是懒加载

懒加载一般是当图片滚动进可视窗口内才加载图片,可视窗口之外的图片则不加载

  • 优点:对服务器有一定的缓解压力作用

我用的 matery主题 整体采用预加载模式,这样可以在我们访问其他页面的时候会稍微快点。我们可以在这个基础上对图片进行懒加载,这样做效果就是html、css、js加载之后,图片再加载。既保证了网页的打开速度,也不会因图片的庞大体积而拖累了整个页面的加载。

开始操作

首先安装图片懒加载插件: hexo-lazyload-image

在Hexo根目录执行

1
npm install hexo-lazyload-image --save

然后在Hexo配置文件末尾加入以下代码:

1
2
3
4
lazyload:
enable: true
onlypost: false # 是否只对文章的图片做懒加载
loadingImg: # eg ./images/loading.gif

本地run前先清除一下缓存,或者直接执行hexo cl && hexo s

图片加载冲突

一般情况下懒加载会和gallery插件会发生冲突,结果可能就是点开图片,左翻右翻都是loading image。matery主题的解决方案是:

修改, /themes/matery/source/js 中的 matery.js文件

在第108行加上:

1
2
3
$(document).find('img[data-original]').each(function(){
$(this).parent().attr("href", $(this).attr("data-original"));
});

做完这步之后,还有点小Bug,首页的logo点击会直接打开logo图,而不是跳到首页。

解决方案:打开/themes/matery/layout/_partial/header.ejs文件,

imgspan的两个头加个div:

1
2
3
4
5
6
7
8
9
10
<div class="brand-logo">
<a href="<%- url_for() %>" class="waves-effect waves-light">
<div>
<% if (theme.logo !== undefined && theme.logo.length > 0) { %>
<img src="<%= theme.logo %>" class="logo-img" alt="LOGO">
<% } %>
<span class="logo-span"><%- config.title %></span>
</div>
</a>
</div>
自定义loading图片

hexo-lazyload-image 插件提供了自定义loading图片的选项

方法就是在 loadingImg 后配置图片的路径,如:

1
2
3
4
lazyload:
enable: true
onlypost: false # 是否只对文章的图片做懒加载
loadingImg: /medias/loading.gif # eg ./images/loading.gif

注:是在主目录下的配置文件下添加如上代码,路径去主题下找如:themes\hexo-theme-matery\source\medias

懒加载优化
  • 其实第一次加载后本地都是有缓存的,如果每次都把loading显示出来就不那么好看

  • 所以我们需要对插件进行魔改,让图片稍微提前加载,避开加载动画

  • 打开 Hexo根目录>node_modules > hexo-lazyload-image > lib > simple-lazyload.js 文件

  • 第9行修改为:

1
&& rect.top <= (window.innerHeight +240 || document.documentElement.clientHeight +240)
  • 作用:提前240个像素加载图片;当然这个值也可以根据自己情况修改

    二、优化文章永久链接

    使用编码生成永久链接

    采用编码形式,这种缺点是可读性差,优点很明显,链接很短
    先看看效果:
1
http://chuchendjs.github.com/posts/15325.html

安装插件:

1
npm install hexo-abbrlink --save

然后在站点根目录config中设置两处,一个是修改permalink为:

1
permalink: posts/:abbrlink.html

在根目录config添加如下配置:

1
2
3
abbrlink:
alg: crc32 #算法 crc16(default) and crc32
rep: hex #进制 dec(default) and hex 十进制和十六进制,默认为10进制。

不同算法组成的链接有如下几种,挑选自己喜欢的,然后替换上面crc32和hex

1
2
3
4
5
6
7
8
9
10
11
crc16 & hex
https://lovelijunyi.gitee.io/posts/66c8.html

crc16 & dec
https://lovelijunyi.gitee.io/posts/65535.html

crc32 & hex
https://lovelijunyi.gitee.io/posts/8ddf18fb.html

crc32 & dec
https://lovelijunyi.gitee.io/posts/1690090958.html

三、优化搜索

matery主题自带搜索,但是只支持英文,所以我们需要拓展搜索功能,先安装插件,在主目录下

1
npm install hexo-generator-search --save

紧接着在博客站点目录的配置文件_config.yml下,添加如下配置:

1
2
3
4
# 中文搜索功能
search:
path: search.xml
field: post

四、添加评论功能

1、给文章添加valine评论功能

进入主题文件的配置文件D:\blog\themes\matery_config.yml。启用valine,其中需要设置Appid和appkey。此两项需要到Leancloud官网下载。

注册和身份验证通过后,新建应用,名字随意起。

注意:密码开头至少要有一个大写,有两个区域,华北和华东
可能会有出现bug,后面有说到
在这里插入图片描述

  • 再将信息填入:
1
2
3
4
5
6
7
8
9
10
11
valine:
enable: true
appid: your app id
appkey: your app key
notify: false
verify: false
visitor: true
avatar: 'mm' # Gravatar style : mm/identicon/monsterid/wavatar/retro/hide
pageSize: 10
placeholder: 'just go go' # Comment Box placeholder
background: /medias/comment_bg.png

Bug:就是如果你注册的是华东节点的可能会出现,背景图没正常显示,拉升到右边,去华北再次注册一个账号就可以了,更多问题请去官方询问

2、添加Gittalk评论插件

matery主题自带gittalk评论插件,我们只需要开启就可以了。

  1. 打开GitHub申请,填写信息:

    1
    2
    3
    4
    Application name //应用名称,随便填
    Homepage URL //填自己的博客地址
    Application description //应用描述,随便填
    Authorization callback URL //填自己的博客地址

    在这里插入图片描述

  2. 打开themes/_config.yml下修改gitalk那里:

    1
    2
    3
    4
    5
    6
    7
    8
    gitalk:
    enable: true
    owner: 你的github用户名
    repo: 你的github用户名.github.io
    oauth:
    clientId: 粘贴刚刚注册完显示的字符串
    clientSecret: 粘贴刚刚注册完显示的字符串
    admin: 你的github用户名

五、关闭音乐的歌词显示

默认音乐播放器会显示歌词,影响观感,想要关闭,去到主题根目录找到一个css文件,APlayer.min.css,themes\hexo-theme-matery\source\libs\aplayer

  • 打开后搜索.aplayer-lrc{display:block}
  • 将block改为none,即为.aplayer-lrc{display:none}

六、添加RSS订阅

简易信息聚合是“Really Simple Syndication”或“Richsite summary”(网站内容摘要)的中文名字。是站点用来和其他站点之间共享内容的一种简易方式。英文缩写为RSS技术。

RSS是一种信息聚合的技术,是某一站点和其他站点之间共享内容的一种简易信息发布与传递的方式,使得一个网站可以方便的调用其他提供RSS订阅服务的网站内容,从而形成非常高效的信息聚合,让网站发布的内容在更大的范围内传播。他是一种用于共享新闻和其他WEB内容的数据交换规范,也是使用最广泛的一种扩展性标识语言。

安装

  1. 在本地hexo目录下右键git bash here,输入以下命令:
1
npm install hexo-generator-feed
  1. 安装完成后,打开hexo目录下配置文件的_config.yml,在末尾添加以下代码:
1
2
3
4
5
6
7
8
9
10
# Extensions
## Plugins: http://hexo.io/plugins/
#RSS订阅
plugin:
- hexo-generator-feed
#Feed Atom
feed:
type: atom
path: atom.xml
limit: 20
  1. 最后打开主题配置文件themes/_config.yml,添加以下代码:
1
rss: /atom.xml

七、增加建站时间

  1. /themes/matery/layout/_partial/footer.ejs 最后加上以下代码:
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
<script language=javascript>
function siteTime() {
window.setTimeout("siteTime()", 1000);
var seconds = 1000;
var minutes = seconds * 60;
var hours = minutes * 60;
var days = hours * 24;
var years = days * 365;
var today = new Date();
var todayYear = today.getFullYear();
var todayMonth = today.getMonth() + 1;
var todayDate = today.getDate();
var todayHour = today.getHours();
var todayMinute = today.getMinutes();
var todaySecond = today.getSeconds();
/* Date.UTC() -- 返回date对象距世界标准时间(UTC)1970年1月1日午夜之间的毫秒数(时间戳)
year - 作为date对象的年份,为4位年份值
month - 0-11之间的整数,做为date对象的月份
day - 1-31之间的整数,做为date对象的天数
hours - 0(午夜24点)-23之间的整数,做为date对象的小时数
minutes - 0-59之间的整数,做为date对象的分钟数
seconds - 0-59之间的整数,做为date对象的秒数
microseconds - 0-999之间的整数,做为date对象的毫秒数 */
var t1 = Date.UTC(2017, 09, 11, 00, 00, 00); // 北京时间2018-2-13 00:00:00
var t2 = Date.UTC(todayYear, todayMonth, todayDate, todayHour, todayMinute, todaySecond);
var diff = t2 - t1;
var diffYears = Math.floor(diff / years);
var diffDays = Math.floor((diff / days) - diffYears * 365);
var diffHours = Math.floor((diff - (diffYears * 365 + diffDays) * days) / hours);
var diffMinutes = Math.floor((diff - (diffYears * 365 + diffDays) * days - diffHours * hours) / minutes);
var diffSeconds = Math.floor((diff - (diffYears * 365 + diffDays) * days - diffHours * hours - diffMinutes * minutes) / seconds);
document.getElementById("sitetime").innerHTML = "本站已运行 " +diffYears+" 年 "+diffDays + " 天 " + diffHours + " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒";
}
siteTime();
</script>

八、添加404页面

  1. 在/source/目录下新建一个404.md,加上以下代码:
1
2
3
4
5
6
7
---
title: 404
date: 2019-07-19 16:41:10
type: "404"
layout: "404"
description: "页面丢失了 :("
---
  1. 然后在/themes/matery/layout/目录下新建一个404.ejs文件,代码如下:
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
<style type="text/css">
/* don't remove. */
.about-cover {
height: 75vh;
}
</style>

<div class="bg-cover pd-header about-cover">
<div class="container">
<div class="row">
<div class="col s10 offset-s1 m8 offset-m2 l8 offset-l2">
<div class="brand">
<div class="title center-align">
404
</div>
<div class="description center-align">
<%= page.description %>
</div>
</div>
</div>
</div>
</div>
</div>

<script>
$('.bg-cover').css('background-image', 'url(/medias/banner/' + new Date().getDay() + '.jpg)');
</script>

九、文章图片水印

  1. 在博客根目录下新建一个watermark.py,代码如下:
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
# -*- coding: utf-8 -*-
import sys
import glob
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont


def watermark(post_name):
if post_name == 'all':
post_name = '*'
dir_name = 'source/_posts/' + post_name + '/*'
for files in glob.glob(dir_name):
im = Image.open(files)
if len(im.getbands()) < 3:
im = im.convert('RGB')
print(files)
font = ImageFont.truetype('STSONG.TTF', max(30, int(im.size[1] / 20)))
draw = ImageDraw.Draw(im)
draw.text((im.size[0] / 2, im.size[1] / 2),
u'@yourname', fill=(0, 0, 0), font=font)
im.save(files)


if __name__ == '__main__':
if len(sys.argv) == 2:
watermark(sys.argv[1])
else:
print('[usage] <input>')

写完一篇文章可以运行python3 watermark.py postname添加水印,如果第一次运行要给所有文章添加水印,可以运行python3 watermark.py all

十、在线聊天插件

主题配置文件里已经支持了两款在线聊天插件,不过我没有用,我用的是crisp

这个配置倒是简单,就是后面会出一点小问题,需要自己手动改css,问题不大。😆

直接用邮箱注册crisp,登录进去以后,复制html代码到layout.ejs里面就ok了。

十一、今日诗词:

官方指南

这个今日诗词API需要在使用前将主题配置文件的subtitle的值改为false。

themes\hexo-theme-matery\layout_partial\head.ejs文件下添加如下代码:

1
2
3
<script src="https://sdk.jinrishici.com/v2/browser/jinrishici.js"

charset="utf-8"></script>

然后再将/themes/hexo-theme-matery/layout/_partial/bg-cover-content.ejs中的<%= config.description %>改为<%- ‘正在加载今日诗词….‘ %>。

十二、添加雪花飘落效果

方法:在themes/matery/source/libs/others下新建文件snow.js,并插入如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*样式一*/
(function($){
$.fn.snow = function(options){
var $flake = $('<div id="snowbox" />').css({'position': 'absolute','z-index':'9999', 'top': '-50px'}).html('&#10052;'),
documentHeight = $(document).height(),
documentWidth = $(document).width(),
defaults = {
minSize : 10,
maxSize : 20,
newOn : 1000,
flakeColor : "#AFDAEF" /* 此处可以定义雪花颜色,若要白色可以改为#FFFFFF */
},
options = $.extend({}, defaults, options);
var interval= setInterval( function(){
var startPositionLeft = Math.random() * documentWidth - 100,
startOpacity = 0.5 + Math.random(),
sizeFlake = options.minSize + Math.random() * options.maxSize,
endPositionTop = documentHeight - 200,
endPositionLeft = startPositionLeft - 500 + Math.random() * 500,
durationFall = documentHeight * 10 + Math.random() * 5000;
$flake.clone().appendTo('body').css({
left: startPositionLeft,
opacity: startOpacity,
'font-size': sizeFlake,
color: options.flakeColor
}).animate({
top: endPositionTop,
left: endPositionLeft,
opacity: 0.2
},durationFall,'linear',function(){
$(this).remove()
});
}, options.newOn);
};
})(jQuery);
$(function(){
$.fn.snow({
minSize: 5, /* 定义雪花最小尺寸 */
maxSize: 50,/* 定义雪花最大尺寸 */
newOn: 300 /* 定义密集程度,数字越小越密集 */
});
});
/*样式二*/
/* 控制下雪 */
function snowFall(snow) {
/* 可配置属性 */
snow = snow || {};
this.maxFlake = snow.maxFlake || 200; /* 最多片数 */
this.flakeSize = snow.flakeSize || 10; /* 雪花形状 */
this.fallSpeed = snow.fallSpeed || 1; /* 坠落速度 */
}
/* 兼容写法 */
requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function(callback) { setTimeout(callback, 1000 / 60); };

cancelAnimationFrame = window.cancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.msCancelAnimationFrame ||
window.oCancelAnimationFrame;
/* 开始下雪 */
snowFall.prototype.start = function(){
/* 创建画布 */
snowCanvas.apply(this);
/* 创建雪花形状 */
createFlakes.apply(this);
/* 画雪 */
drawSnow.apply(this)
}
/* 创建画布 */
function snowCanvas() {
/* 添加Dom结点 */
var snowcanvas = document.createElement("canvas");
snowcanvas.id = "snowfall";
snowcanvas.width = window.innerWidth;
snowcanvas.height = document.body.clientHeight;
snowcanvas.setAttribute("style", "position:absolute; top: 0; left: 0; z-index: 1; pointer-events: none;");
document.getElementsByTagName("body")[0].appendChild(snowcanvas);
this.canvas = snowcanvas;
this.ctx = snowcanvas.getContext("2d");
/* 窗口大小改变的处理 */
window.onresize = function() {
snowcanvas.width = window.innerWidth;
/* snowcanvas.height = window.innerHeight */
}
}
/* 雪运动对象 */
function flakeMove(canvasWidth, canvasHeight, flakeSize, fallSpeed) {
this.x = Math.floor(Math.random() * canvasWidth); /* x坐标 */
this.y = Math.floor(Math.random() * canvasHeight); /* y坐标 */
this.size = Math.random() * flakeSize + 2; /* 形状 */
this.maxSize = flakeSize; /* 最大形状 */
this.speed = Math.random() * 1 + fallSpeed; /* 坠落速度 */
this.fallSpeed = fallSpeed; /* 坠落速度 */
this.velY = this.speed; /* Y方向速度 */
this.velX = 0; /* X方向速度 */
this.stepSize = Math.random() / 30; /* 步长 */
this.step = 0 /* 步数 */
}
flakeMove.prototype.update = function() {
var x = this.x,
y = this.y;
/* 左右摆动(余弦) */
this.velX *= 0.98;
if (this.velY <= this.speed) {
this.velY = this.speed
}
this.velX += Math.cos(this.step += .05) * this.stepSize;

this.y += this.velY;
this.x += this.velX;
/* 飞出边界的处理 */
if (this.x >= canvas.width || this.x <= 0 || this.y >= canvas.height || this.y <= 0) {
this.reset(canvas.width, canvas.height)
}
};
/* 飞出边界-放置最顶端继续坠落 */
flakeMove.prototype.reset = function(width, height) {
this.x = Math.floor(Math.random() * width);
this.y = 0;
this.size = Math.random() * this.maxSize + 2;
this.speed = Math.random() * 1 + this.fallSpeed;
this.velY = this.speed;
this.velX = 0;
};
// 渲染雪花-随机形状(此处可修改雪花颜色!!!)
flakeMove.prototype.render = function(ctx) {
var snowFlake = ctx.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.size);
snowFlake.addColorStop(0, "rgba(255, 255, 255, 0.9)"); /* 此处是雪花颜色,默认是白色 */
snowFlake.addColorStop(.5, "rgba(255, 255, 255, 0.5)"); /* 若要改为其他颜色,请自行查 */
snowFlake.addColorStop(1, "rgba(255, 255, 255, 0)"); /* 找16进制的RGB 颜色代码。 */
ctx.save();
ctx.fillStyle = snowFlake;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
};
/* 创建雪花-定义形状 */
function createFlakes() {
var maxFlake = this.maxFlake,
flakes = this.flakes = [],
canvas = this.canvas;
for (var i = 0; i < maxFlake; i++) {
flakes.push(new flakeMove(canvas.width, canvas.height, this.flakeSize, this.fallSpeed))
}
}
/* 画雪 */
function drawSnow() {
var maxFlake = this.maxFlake,
flakes = this.flakes;
ctx = this.ctx, canvas = this.canvas, that = this;
/* 清空雪花 */
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var e = 0; e < maxFlake; e++) {
flakes[e].update();
flakes[e].render(ctx);
}
/* 一帧一帧的画 */
this.loop = requestAnimationFrame(function() {
drawSnow.apply(that);
});
}
/* 调用及控制方法 */
var snow = new snowFall({maxFlake:60});
snow.start();


然后在themes/_config里libs.js.下面添加一行:

1
snow: /libs/others/snow.js

themes/matery/layout/layout.ejs里添加如下代码:

1
2
3
4
<!-- 雪花特效 --> 
<% if (theme.snow.enable) { %>
<script type="text/javascript" src="<%- theme.libs.js.snow %>"></script>
<% } %>

最后在themes/_config添加:

1
2
3
# 雪花特效
snow:
enable: true

十三、添加动漫人物挂件

方法

  1. 获取模型:
1
npm install --save hexo-helper-live2d
  1. 安装喜欢的模型:
1
$ npm install packagename

将packagename换成模型名字,如我使用的模型:

1
$ npm install live2d-widget-model-shizuku
  1. 然后打开博客根目录下的 _config.yml文件,添加如下代码:
1
2
3
4
5
6
7
8
9
10
11
live2d:
enable: true
scriptFrom: local
model:
use: live2d-widget-model-haruto #模型选择
display:
position: right #模型位置
width: 150 #模型宽度
height: 300 #模型高度
mobile:
show: false #是否在手机端显示

效果是这样子的:
这个人物模型是这样子的

这里有个坑,就是修改上面属性值无法定位人物模型的位置,目前还没有找到很好的解决方法,如果你有很好的解决方法请在评论区告诉我,谢谢你啦!

十四、浏览器网页标题

  1. \themes\material-x\source\js 下新建一个 FunnyTitle.js 文件,填写如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 浏览器搞笑标题
var OriginTitle = document.title;
var titleTime;
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
$('[rel="icon"]').attr('href', "/funny.ico");
document.title = '╭(°A°`)╮ 页面崩溃啦 ~';
clearTimeout(titleTime);
}
else {
$('[rel="icon"]').attr('href', "/favicon.ico");
document.title = '(ฅ>ω<*ฅ) 噫又好啦 ~' + OriginTitle;
titleTime = setTimeout(function () {
document.title = OriginTitle;
}, 2000);
}
});
  1. \themes\material-x\layout\layout.ejs 文件中添加如下代码:
1
2
<!--浏览器搞笑标题-->
<script type="text/javascript" src="/js/FunnyTitle.js"></script>

十五、添加鼠标点击爱心效果

1.在 \themes\hexo-theme-spfk\source\js 下新建文件 love.js,在 love.js 文件中添加以下代码:

1
!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: 500%;-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+=.004,d[e].alpha-=.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);
  1. \themes\hexo-theme-spfk\layout\layout.ejs 文件末尾添加以下代码:
1
2
<!-- 页面点击小红心 -->
<script type="text/javascript" src="/js/love.js"></script>