Hexo中Next主题添加主页标签页以及美化标签页 | StriveZs的博客

Hexo中Next主题添加主页标签页以及美化标签页

Hexo中Next主题添加主页标签页以及美化标签页

添加主页标签云

使用 tag-cloud 插件

hexo-tag-cloud插件是作者写的一个Hexo博客的标签云插件,旨在直观的展示标签的种类,美观大方且非常优雅。

插件地址:
插件的GitHub地址

安装插件
进入到 hexo 的根目录,在 package.json 中添加依赖: “hexo-tag-cloud”: “2.0.*” 操作如下:
使用命令行进行安装

1
npm install hexo-tag-cloud@^2.0.* --save

配置文件

在主题文件夹找到文件 theme/next/layout/_macro/sidebar.swig, 然后添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
{% if site.tags.length > 1 %}
<script type="text/javascript" charset="utf-8" src="/js/tagcloud.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/tagcanvas.js"></script>
<div class="widget-wrap">
<h3 class="widget-title">Tag Cloud</h3>
<div id="myCanvasContainer" class="widget tagcloud">
<canvas width="250" height="250" id="resCanvas" style="width=100%">
{{ list_tags() }}
</canvas>
</div>
</div>
{% endif %}

代码添加到内容最后面即可如下:
figure1

主题配置

在博客根目录,找到 _config.yml配置文件然后在最后添加如下的配置项,可以自定义标签云的字体和颜色,还有突出高亮:

1
2
3
4
5
6
7
# hexo-tag-cloud
tag_cloud:
textFont: Trebuchet MS, Helvetica
textColor: '#333'
textHeight: 25
outlineColor: '#E2E1D1'
maxSpeed: 0.1

textColor: ‘#333’ 字体颜色
textHeight: 25 字体高度,根据部署的效果调整
maxSpeed: 0.1 文字滚动速度,根据自己喜好调整

显示效果

figure5

美化标签页面

添加球形标签页面

  1. 在/themes/next/layout/目录下,新建tag-bubble.swig文件,内容如下:
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
<style>
.wrapper {
margin: 0 auto;
padding:0;
width: 700px;
min-width: 100px;
}
.tagbubble {
position: relative;
margin-top: 300px;
}
.tagbubble a {
display: block;
border-radius: 50%;
color: #fff;
font-weight: bold;
font-size: 14px;
text-decoration: none;
text-align: center;
}

.b0{
width: 95px;
height: 90px;
line-height: 90px;
}
.b1{
width: 70px;
height: 70px;
line-height: 55px;
}
.b2{
width: 60px;
height: 60px;
line-height: 60px;
}
.b3{
width: 45px;
height: 45px;
line-height: 40px;
}

.c0{
background: -moz-linear-gradient(top, #d1e5fd 0%, #3d86f4 100%);
background: -webkit-linear-gradient(top, #d1e5fd 0%,#3d86f4 100%);
background: -o-linear-gradient(top, #d1e5fd 0%,#3d86f4 100%);
background: -ms-linear-gradient(top, #d1e5fd 0%,#3d86f4 100%);
background: linear-gradient(to bottom, #d1e5fd 0%,#3d86f4 100%);
}
.c1{
background: -moz-linear-gradient(top, #b9f8ff 0%, #1de7ff 100%);
background: -webkit-linear-gradient(top, #b9f8ff 0%,#1de7ff 100%);
background: -o-linear-gradient(top, #b9f8ff 0%,#1de7ff 100%);
background: -ms-linear-gradient(top, #b9f8ff 0%,#1de7ff 100%);
background: linear-gradient(to bottom, #b9f8ff 0%,#1de7ff 100%);
}
.c2{
background: -moz-linear-gradient(top, #fff4e2 0%, #ffd79c 100%);
background: -webkit-linear-gradient(top, #fff4e2 0%,#ffd79c 100%);
background: -o-linear-gradient(top, #fff4e2 0%,#ffd79c 100%);
background: -ms-linear-gradient(top, #fff4e2 0%,#ffd79c 100%);
background: linear-gradient(to bottom, #fff4e2 0%,#ffd79c 100%);
}
.c3{
background: -moz-linear-gradient(top, #fef4fa 0%, #fbbae0 100%);
background: -webkit-linear-gradient(top, #fef4fa 0%,#fbbae0 100%);
background: -o-linear-gradient(top, #fef4fa 0%,#fbbae0 100%);
background: -ms-linear-gradient(top, #fef4fa 0%,#fbbae0 100%);
background: linear-gradient(to bottom, #fef4fa 0%,#fbbae0 100%);
}
.c4{
background: -moz-linear-gradient(top, #fedc90 0%, #ffb515 100%);
background: -webkit-linear-gradient(top, #fedc90 0%,#ffb515 100%);
background: -o-linear-gradient(top, #fedc90 0%,#ffb515 100%);
background: -ms-linear-gradient(top, #fedc90 0%,#ffb515 100%);
background: linear-gradient(to bottom, #fedc90 0%,#ffb515 100%);
}
.c5{
background: -moz-linear-gradient(top, #bcf7ca 0%, #1fda4b 100%);
background: -webkit-linear-gradient(top, #bcf7ca 0%,#1fda4b 100%);
background: -o-linear-gradient(top, #bcf7ca 0%,#1fda4b 100%);
background: -ms-linear-gradient(top, #bcf7ca 0%,#1fda4b 100%);
background: linear-gradient(to bottom, #bcf7ca 0%,#1fda4b 100%);
}
.c6{
background: -moz-linear-gradient(top, #f7cdf8 0%, #db43e7 100%);
background: -webkit-linear-gradient(top, #f7cdf8 0%,#db43e7 100%);
background: -o-linear-gradient(top, #f7cdf8 0%,#db43e7 100%);
background: -ms-linear-gradient(top, #f7cdf8 0%,#db43e7 100%);
background: linear-gradient(to bottom, #f7cdf8 0%,#db43e7 100%);
}

/* 移动端样式 */
@media (max-width: 767px){
.wrapper {
width: 10px;
margin-left:20px;
min-width: 0px;
}
.tagbubble{
width: 300px;
min-width: 0px;
margin-top: 200px;
margin-left: 10px;
}
.tagbubble a {
font-size: 13px;
}
.b0{
width: 65px;
height: 65px;
line-height: 60px;
}
.b1{
width: 50px;
height: 50px;
line-height: 45px;
}
.b2{
width: 40px;
height: 40px;
line-height: 40px;
}
.b3{
width: 35px;
height: 35px;
line-height: 35px;
}
}

</style>

<div class="wrapper">
<div class="tagbubble">

</div>
</div>
<script type="text/javascript">

var alltags = document.getElementsByClassName('tag-cloud-tags');
var tags = alltags[0].getElementsByTagName('a');

var bo = new Array();
var co = new Array();
for(var i=0;i<4;i++){
bo.push("b" + i);
}
for(var i=0;i<7;i++){
co.push("c" + i);
}

var divDom = document.querySelector('.tagbubble')
//var divDom = document.getElementsByClassName('tagbubble')[0];
for(var i=0;i<tags.length;i++){
var atag = document.createElement('a');
var boStyle = bo[Math.floor(Math.random()*4)];
var coStyle = co[Math.floor(Math.random()*7)];
if(tags[i].innerText.length > 10){
boStyle = "b0";
}else if(tags[i].innerText.length > 5 && tags[i].innerText.length < 10){
boStyle = "b1";
}
atag.setAttribute("class", boStyle+" "+coStyle);
atag.setAttribute("href", tags[i].href);
atag.innerText = tags[i].innerText;
divDom.appendChild(atag);
}

function browserRedirect() {
var sUserAgent = navigator.userAgent.toLowerCase();
var bIsIpad = sUserAgent.match(/ipad/i) == "ipad";
var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os";
var bIsMidp = sUserAgent.match(/midp/i) == "midp";
var bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4";
var bIsUc = sUserAgent.match(/ucweb/i) == "ucweb";
var bIsAndroid = sUserAgent.match(/android/i) == "android";
var bIsCE = sUserAgent.match(/windows ce/i) == "windows ce";
var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile";
if (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM) {
//移动端页面
return 80;
} else {
//pc端页面
return 150;
}
}

var tagRadius = browserRedirect();

/*3D标签云*/
tagcloud({
selector: ".tagbubble", //元素选择器
fontsize: 14, //基本字体大小, 单位px
radius: tagRadius, //滚动半径, 单位px 页面宽度和高度的五分之一
mspeed: "slow", //滚动最大速度, 取值: slow, normal(默认), fast
ispeed: "slow", //滚动初速度, 取值: slow, normal(默认), fast
direction: 135, //初始滚动方向, 取值角度(顺时针360): 0对应top, 90对应left, 135对应right-bottom(默认)...
keep: false //鼠标移出组件后是否继续随鼠标滚动, 取值: false, true(默认) 对应 减速至初速度滚动, 随鼠标滚动
});
</script>
  1. 在/themes/next/source/js/src/目录下,新建其依赖的bubble.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
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
/*
* 3d标签云
* 功能:鼠标移入标签,当前标签静止放大
* 说明:
* */
window.tagcloud = (function(win, doc) { // ns
// 判断对象
function isObject (obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}

// 构造函数
function TagCloud (options) {
var self = this;

self.config = TagCloud._getConfig(options);
self.box = self.config.element; //组件元素
self.fontsize = self.config.fontsize; //平均字体大小
self.radius = self.config.radius; //滚动半径
self.depth = 2 * self.radius; //滚动深度
self.size = 2 * self.radius; //随鼠标滚动变速作用区域

self.mspeed = TagCloud._getMsSpeed(self.config.mspeed);
self.ispeed = TagCloud._getIsSpeed(self.config.ispeed);
self.items = self._getItems();

self.direction = self.config.direction; //初始滚动方向
self.keep = self.config.keep; //鼠标移出后是否保持之前滚动

//初始化
self.active = false; //是否为激活状态
self.lasta = 1;
self.lastb = 1;
self.mouseX0 = self.ispeed * Math.sin(self.direction * Math.PI / 180); //鼠标与滚动圆心x轴初始距离
self.mouseY0 = -self.ispeed * Math.cos(self.direction * Math.PI / 180); //鼠标与滚动圆心y轴初始距离
self.mouseX = self.mouseX0; //鼠标与滚动圆心x轴距离
self.mouseY = self.mouseY0; //鼠标与滚动圆心y轴距离
self.index = -1;

//鼠标移入
TagCloud._on(self.box, 'mouseover', function () {
self.active = true;
});
//鼠标移出
TagCloud._on(self.box, 'mouseout', function () {
self.active = false;
});

//鼠标在内移动
TagCloud._on(self.keep ? win : self.box, 'mousemove', function (ev) {
var oEvent = win.event || ev;
var boxPosition = self.box.getBoundingClientRect();
self.mouseX = (oEvent.clientX - (boxPosition.left + self.box.offsetWidth / 2)) / 5;
self.mouseY = (oEvent.clientY - (boxPosition.top + self.box.offsetHeight / 2)) / 5;
});

for (var j = 0, len = self.items.length; j < len; j++) {
self.items[j].element.index=j;

//鼠标移出子元素,当前元素静止放大
self.items[j].element.onmouseover = function(){
self.index = this.index;
};

//鼠标移出子元素,当前元素继续滚动
self.items[j].element.onmouseout = function(){
self.index = -1;
};
}

//定时更新
TagCloud.boxs.push(self.box);
self.update(self); //初始更新
self.box.style.visibility = "visible";
self.box.style.position = "relative";
// self.box.style.minHeight = 1.2 * self.size + "px";
// self.box.style.minWidth = 2.5 * self.size + "px";
self.box.style.minHeight = 0 * self.size + "px";
self.box.style.minWidth = 0 * self.size + "px";
for (var j = 0, len = self.items.length; j < len; j++) {
self.items[j].element.style.position = "absolute";
self.items[j].element.style.zIndex = j + 1;
}
self.up = setInterval(function() {
self.update(self);
}, 10);
}

//实例
TagCloud.boxs = []; //实例元素数组
// 静态方法们
TagCloud._set = function (element) {
if (TagCloud.boxs.indexOf(element) == -1) {//ie8不支持数组的indexOf方法
return true;
}
};

//添加数组IndexOf方法
if (!Array.prototype.indexOf){
Array.prototype.indexOf = function(elt /*, from*/){
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;

for (; from < len; from++){
if (from in this && this[from] === elt)
return from;
}
return -1;
};
}

TagCloud._getConfig = function (config) {
var defaultConfig = { //默认值
fontsize: 16, //基本字体大小, 单位px
radius: 60, //滚动半径, 单位px
mspeed: "normal", //滚动最大速度, 取值: slow, normal(默认), fast
ispeed: "normal", //滚动初速度, 取值: slow, normal(默认), fast
direction: 135, //初始滚动方向, 取值角度(顺时针360): 0对应top, 90对应left, 135对应right-bottom(默认)...
keep: true //鼠标移出组件后是否继续随鼠标滚动, 取值: false, true(默认) 对应 减速至初速度滚动, 随鼠标滚动
};

if(isObject(config)) {
for(var i in config) {
if(config.hasOwnProperty(i)) {//hasOwnProperty()用来判断一个属性是定义在对象本身而不是继承自原型链
defaultConfig[i] = config[i]; //用户配置
}
}
}

return defaultConfig;// 配置 Merge
};
TagCloud._getMsSpeed = function (mspeed) { //滚动最大速度
var speedMap = {
slow: 1.5,
normal: 3,
fast: 5
};
return speedMap[mspeed] || 3;
};
TagCloud._getIsSpeed = function (ispeed) { //滚动初速度
var speedMap = {
slow: 10,
normal: 25,
fast: 50
};
return speedMap[ispeed] || 25;
};
TagCloud._getSc = function(a, b) {
var l = Math.PI / 180;
//数组顺序0,1,2,3表示asin,acos,bsin,bcos
return [
Math.sin(a * l),
Math.cos(a * l),
Math.sin(b * l),
Math.cos(b * l)
];
};

TagCloud._on = function (ele, eve, handler, cap) {
if (ele.addEventListener) {
ele.addEventListener(eve, handler, cap);
} else if (ele.attachEvent) {
ele.attachEvent('on' + eve, handler);
} else {
ele['on' + eve] = handler;
}
};

// 原型方法
TagCloud.prototype = {
constructor: TagCloud, // 反向引用构造器

update: function () {
var self = this, a, b;

if (!self.active && !self.keep) {
self.mouseX = Math.abs(self.mouseX - self.mouseX0) < 1 ? self.mouseX0 : (self.mouseX + self.mouseX0) / 2; //重置鼠标与滚动圆心x轴距离
self.mouseY = Math.abs(self.mouseY - self.mouseY0) < 1 ? self.mouseY0 : (self.mouseY + self.mouseY0) / 2; //重置鼠标与滚动圆心y轴距离
}

a = -(Math.min(Math.max(-self.mouseY, -self.size), self.size) / self.radius ) * self.mspeed;
b = (Math.min(Math.max(-self.mouseX, -self.size), self.size) / self.radius ) * self.mspeed;

if (Math.abs(a) <= 0.01 && Math.abs(b) <= 0.01) { return; }

self.lasta = a;
self.lastb = b;

var sc = TagCloud._getSc(a, b);

for (var j = 0, len = self.items.length; j < len; j++) {

var rx1 = self.items[j].x,
ry1 = self.items[j].y*sc[1] + self.items[j].z*(-sc[0]),
rz1 = self.items[j].y*sc[0] + self.items[j].z*sc[1];

var rx2 = rx1 * sc[3] + rz1 * sc[2],
ry2 = ry1,
rz2 = rz1 * sc[3] - rx1 * sc[2];

if(self.index==j){

self.items[j].scale = 1; //取值范围0.6 ~ 3
self.items[j].fontsize = 16;
self.items[j].alpha = 1;
self.items[j].element.style.zIndex = 99;
}else{
var per = self.depth / (self.depth + rz2);
self.items[j].x = rx2;
self.items[j].y = ry2;
self.items[j].z = rz2;

self.items[j].scale = per; //取值范围0.6 ~ 3
self.items[j].fontsize = Math.ceil(per * 2) + self.fontsize - 6;
self.items[j].alpha = 1.5 * per - 0.5;
self.items[j].element.style.zIndex = Math.ceil(per*10-5);
}
//self.items[j].element.style.fontSize = self.items[j].fontsize + "px";//字体变大小
self.items[j].element.style.left = self.items[j].x + (self.box.offsetWidth - self.items[j].offsetWidth) / 2 + "px";
self.items[j].element.style.top = self.items[j].y + (self.box.offsetHeight - self.items[j].offsetHeight) / 2 + "px";
self.items[j].element.style.filter = "alpha(opacity=" + 100 * self.items[j].alpha + ")";
self.items[j].element.style.opacity = self.items[j].alpha;
}
},

_getItems: function () {
var self = this,
items = [],
element = self.box.children, // children 全部是Element
length = element.length,
item;

for (var i = 0; i < length; i++) {
item = {};
item.angle = {};
item.angle.phi = Math.acos(-1 + (2 * i + 1) / length);
item.angle.theta = Math.sqrt((length + 1) * Math.PI) * item.angle.phi;
item.element = element[i];
item.offsetWidth = item.element.offsetWidth;
item.offsetHeight = item.element.offsetHeight;
item.x = self.radius * 1.5 * Math.cos(item.angle.theta) * Math.sin(item.angle.phi);
item.y = self.radius * 1.5 * Math.sin(item.angle.theta) * Math.sin(item.angle.phi);
item.z = self.radius * 1.5 * Math.cos(item.angle.phi);
item.element.style.left = item.x + (self.box.offsetWidth - item.offsetWidth) / 2 + "px";
item.element.style.top = item.y + (self.box.offsetHeight - item.offsetHeight) / 2 + "px";
items.push(item);
}

return items; //单元素数组
}
};

if (!doc.querySelectorAll) {//ie7不支持querySelectorAll,所以要重新定义
doc.querySelectorAll = function (selectors) {
var style = doc.createElement('style'), elements = [], element;
doc.documentElement.firstChild.appendChild(style);
doc._qsa = [];

style.styleSheet.cssText = selectors + '{x-qsa:expression(document._qsa && document._qsa.push(this))}';
window.scrollBy(0, 0);
style.parentNode.removeChild(style);

while (doc._qsa.length) {
element = doc._qsa.shift();
element.style.removeAttribute('x-qsa');
elements.push(element);
}
doc._qsa = null;
return elements;
};
}

return function (options) { // factory
options = options || {}; // 短路语法
var selector = options.selector || '.tagcloud', //默认选择class为tagcloud的元素
elements = doc.querySelectorAll(selector),
instance = [];
for (var index = 0, len = elements.length; index < len; index++) {
options.element = elements[index];
if (!!TagCloud._set(options.element)) {
instance.push(new TagCloud(options));
}
}
return instance;
};

})(window, document);
  1. 在/themes/next/layout/_layout.swig中,引入上边的bubble.js,引入位置在head标签内,比如这样:
    figure2
  2. 在/themes/next/layout/page.swig中,引入tag-bubble.swig,具体如下:
    figure3

显示效果

具体显示效果如下:
figure4

StriveZs wechat
Hobby lead  creation, technology change world.