Hexo NexT主题之自定义标签页

在 NexT 主题自带的标签页中,标签以简单的列表形式进行展示,只加了随机字体大小,并没有其它特别的样式。当标签多了以后,页面被挤得满满当当,不是很美观。github 有相关的标签云插件,比如 Hexo Tag Cloud 这款,将标签以立体的效果进行展示,看起来还是不错的。按要求配置后,标签云显示在侧栏 sidebar 区域,之后因侧栏放了别的插件,我将其挪到了单独的标签页。

标签页显示效果:

uPQwTA.gif

标签页的效果前前后后改了好几次,从标签云–>彩色标签页–>心形标签云,下面分别说一下步骤。

标签云

  1. 在 next/layout/ 目录下新建 tagcanvas.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
<div class="tags" id="myTags" style="margin-left:300px">
<canvas width="350" height="350" id="my3DTags">
<p>Anything in here will be replaced on browsers that support the canvas element</p>
</canvas>
</div>
<div class="tags" id="tags">
<ul style="display: none">
{{ tagcloud({
min_font: 16,
max_font: 35,
amount: 999,
color: true,
start_color: 'red',
end_color: 'red',
}) }}
</ul>
</div>
<script type="text/javascript" src="{{ url_for('/js/tagcanvas.js') }}"></script>
<script type="text/javascript" >
window.onload = function() {
try {
TagCanvas.Start('my3DTags','tags',{
textFont: 'Georgia,Optima',
textColour: null,
outlineColour: 'black',
weight: true,
reverse: true,
depth: 0.8,
maxSpeed: 0.05,
bgRadius: 1,
freezeDecel: true
});
} catch(e) {
// something went wrong, hide the canvas container
document.getElementById('myTags').style.display = 'none';
}
};
</script>

其依赖的 tagcanvas.js,与我们使用 Hexo Tag Cloud 插件安装后得到的 tagcanvas.js 一样。

  1. 在 next/layout/page.swig 中,引入这个新建的文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  <div class="post-body{% if theme.han %} han-init-context{% endif %}{% if page.direction && page.direction.toLowerCase() === 'rtl' %} rtl{% endif %}">
{# tagcloud page support #}
{% if page.type === "tags" %}
<div class="tag-cloud">
<div class="tag-cloud-title">
{{ _p('counter.tag_cloud', site.tags.length) }}
</div>
<div class="tag-cloud-tags">
{{ tagcloud({min_font: 10, max_font: 15, amount: 300, color: true, start_color: '#ccc', end_color: '#111'}) }}
</div>
</div>

+ {% include 'tagcanvas.swig' %}

{% elif page.type === 'categories' %}
......

重新部署后即可看到效果

彩色标签页

效果如下:

uPtOFe.png

可参考我的这篇文章:

Hexo NexT 美化2.0——彩色标签页

心形标签云

网站魔改一段时间后,发现之前做好的标签云不显示了,浏览器审查元素中是有的,页面就是出不来。github 已有相关issue。原因是说主题中加了 window.onload 这样的函数,导致 hexo-tag-cloud 的 window.onload 被覆盖,钩子函数不执行,作者是这样说的,不知道算不算 bug 。在浏览器控制台执行如下代码:

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
try {
TagCanvas.textFont = 'Trebuchet MS, Helvetica';
TagCanvas.textColour = '#333';
TagCanvas.textHeight = 18;
TagCanvas.outlineColour = '#E2E1C1';
TagCanvas.maxSpeed = 0.03;
TagCanvas.outlineMethod = 'block';
TagCanvas.minBrightness = 0.2;
TagCanvas.depth = 0.92;
TagCanvas.pulsateTo = 0.6;
TagCanvas.initial = [0.1,-0.1];
TagCanvas.decel = 0.98;
TagCanvas.reverse = true;
TagCanvas.hideTags = false;
TagCanvas.shadow = '#ccf';
TagCanvas.shadowBlur = 3;
TagCanvas.weight = false;
TagCanvas.imageScale = null;
TagCanvas.fadeIn = 1000;
TagCanvas.clickToFront = 600;
TagCanvas.Start('resCanvas');
TagCanvas.tc['resCanvas'].Wheel(false)
} catch(e) {
console.log(e);
document.getElementById('myCanvasContainer').style.display = 'none';
}

标签云立马又出现了。。

uP12Is.png

可能也是这功能不稳定吧,目前还没找到好办法。然后就想着自己做一个类似的吧。无意中在网上发现了一款不错的心形图案,来自算法网,效果如下:

uiEVcd.gif

在此基础上做了部分修改后,整合到了自己的网站中,具体步骤如下:

  1. 在 next/layout/ 目录下,新建 tag-love.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
<style>

.love {
width: 500px;
height: 650px;
position: relative;
margin: 60px auto;
}

.love a {
position: absolute;
left: 0;
//color: goldenrod;
//color: #e804048f;
font-size: 20px;
font-family: sans-serif;
text-shadow: 0 0 1em white;
animation:
x-move 15s ease-in-out infinite alternate,
y-move 30s linear infinite;
animation-delay: calc(45s / var(--particles) * var(--n) * -1);
user-select: auto; // none
}

.love a:first-child {
color: orangered;
font-size: 3em;
text-shadow:
0 0 0.1em black,
0 0 1em white;
z-index: 1;
}

@keyframes x-move {
to {
left: 450px;
}
}

@keyframes y-move {
0% { transform: translateY(180px); }
10% { transform: translateY(45px); }
15% { transform: translateY(5px); }
18% { transform: translateY(0); }
20% { transform: translateY(5px); }
22% { transform: translateY(35px); }
24% { transform: translateY(65px); }
25% { transform: translateY(110px); }
26% { transform: translateY(65px); }
28% { transform: translateY(35px); }
30% { transform: translateY(5px); }
32% { transform: translateY(0); }
35% { transform: translateY(5px); }
40% { transform: translateY(45px); }
50% { transform: translateY(180px); }
71% { transform: translateY(430px); }
72.5% { transform: translateY(440px); }
75% { transform: translateY(450px); }
77.5% { transform: translateY(440px); }
79% { transform: translateY(430px); }
100% { transform: translateY(180px); }
}

/* 移动端样式 */
@media (max-width: 767px) {
.love{
width: 360px;
height: 450px;
margin: 30px auto;
}
@keyframes x-move {
to {
left: 285px;
}
}
}

</style>

<div class="love"></div>

<script type="text/javascript">

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

var words = ['❤️'];
for(var i = 0 ; i < tags.length ; i ++){
// words.push(tags[i].innerHTML)
words.push(tags[i])
}

var dom = {
love: document.querySelector('.love')
}

dom.love.style.setProperty('--particles', words.length)

words.forEach((word, i) => {

let atag = document.createElement('a');
atag.style.setProperty('--n', i + 1);

atag.style.setProperty('text-decoration', 'none');
atag.style.setProperty('border-bottom', 'none');

var r=Math.floor(Math.random()*75+130);
var g=Math.floor(Math.random()*75+100);
var b=Math.floor(Math.random()*75+80);
atag.style.setProperty("color", "rgb("+r+","+g+","+b+")");

atag.setAttribute("href", word.href);
atag.innerText = word.innerText;

if(word.href == undefined){
atag.setAttribute("href", "#");
atag.innerText = word;
}

dom.love.appendChild(atag);
})

</script>
  1. 在 next/layout/page.swig 中,引入这个新建的文件:
1
2
{# 自定义爱心标签云 #}
{% include 'tag-love.swig' %}

引入的位置在上边说的球型云标签下方即可,像这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  <div class="post-body{% if theme.han %} han-init-context{% endif %}{% if page.direction && page.direction.toLowerCase() === 'rtl' %} rtl{% endif %}">
{# tagcloud page support #}
{% if page.type === "tags" %}
<div class="tag-cloud">
<div class="tag-cloud-title">
{{ _p('counter.tag_cloud', site.tags.length) }}
</div>
<div class="tag-cloud-tags">
{{ tagcloud({min_font: 10, max_font: 15, amount: 300, color: true, start_color: '#ccc', end_color: '#111'}) }}
</div>
</div>

{% include 'tagcanvas.swig' %}

+ {# 自定义爱心标签云 #}
+ {% include 'tag-love.swig' %}

{% elif page.type === 'categories' %}
......

注意:部分样式需要根据你的主题进行调整,标签数量最好在 15 个以上,效果会明显一些。

hexo 三连后,查看下效果吧:

uABKAA.gif

另外,原有的标签可在 next/layout/page.swig 中设置为不显示,像这样加上 hidden 属性:

1
2
3
<div class="tag-cloud-tags" hidden>
{{ tagcloud({min_font: 10, max_font: 15, amount: 300, color: true, start_color: '#ccc', end_color: '#111'}) }}
</div>

效果在 Chrome 还可以,在 Safari 就有点变形,其他浏览器因为电脑没装就暂时没测。

球型标签云

给上边的心形标签云加上链接后,点击的效果差强人意,于是又开始捣鼓其它方案。在 17素材网 发现一款不错的标签云,又开始忙起来了~哈哈。修改了部分 JS 代码,效果如下图所示:

uABS0J.gif

立体感很强,球背面的标签也能选中。下面说一下在 NexT 中具体的整合步骤。

  1. 在 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. 在 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. 在 next/layout/_layout.swig 中,引入上边的 bubble.js,引入位置在 head 标签内,比如这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>

{% set html_class = 'theme-next ' + theme.scheme %}
{% if theme.motion.enable %}
{% set html_class = html_class + ' use-motion' %}
{% endif %}

<html class="{{ html_class | lower }}" lang="{{ config.language }}">
<head>
{% include '_partials/head.swig' %}
<title>{% block title %}{% endblock %}</title>

+ <!-- 球型气泡标签云 -->
+ <script type="text/javascript" src="/js/src/bubble.js"></script>

{% include '_third-party/analytics/index.swig' %}
</head>
  1. 在 next/layout/page.swig 中,引入 tag-bubble.swig,位置在 tag-love.swig 下方即可。
1
{% include 'tag-bubble.swig' %}

这样就配置完成了,重启看下效果吧!觉得不错的话,可以在文章下方给个好(da)评(shang)哦~

本站 已集成 5 种标签页样式,可动态配置,欢迎 star、fork

点击查看

本文标题:Hexo NexT主题之自定义标签页

文章作者:北宸

发布时间:2019年09月23日 - 14:54:23

最后更新:2023年08月19日 - 13:26:00

原始链接:https://www.liaofuzhan.com/posts/4158923031.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------------本文结束 感谢您的阅读-------------------
🌞