0%

使用阿里云的oss+cdn搭建高速访问的静态博客

之前一直想搭建一个博客 但是一直没找到便宜 并且访问速度快的方案 前几种方案
1:git pages + cdn
国内访问速度简直吃屎 不知道 同行是如何忍受的 cdn从源站拉取资源的时候 慢到无法忍受
2:coding pages+cdn
不想用 coding pages 还不如直接用git pages
3: 购买vps或者静态托管服务器
博客初期完全用不起 太特么贵了 穷吊 用不起

综上所述 我需要的博客大致需要
1:源站访问速度快
2:cdn 好用
3:域名
4:https http2访问
5:价格相对便宜
6:管理相对方便
7:增加ca证书方便

最终选择方案
全部使用阿里云的相关资源
域名:万网
cdn:阿里云 cdn
源站:使用阿里云的oss对象存储

1
2
oss  原本只是 阿里云的一个放文件的一个功能 后来他支持设定首页 就可以用来托管静态页面 
速度不用说 肯定快 而且支持 https

ca证书:阿里云 ca免费赛门铁克证书
静态博客:hexo + next主题

其实这些主要是选择 具体如何使用 直接操作阿里云控制台就是的 没啥难度

遇到的麻烦的点:
1: oss 存储hexo生成的静态资源 路由问题
由于oss 里面 文件夹也是可访问的一种资源 这就导致 hexo初始生成的路由 例如/tags/ming/ 这个时候他访问的是oss里面的/tags/ming/ 文件夹 然后是空白
解决办法: 修改站点配置_config.yaml 中permalink参数
我是用abbrlink 来重写url了 如果不用 就是在hexo的permalink中 后面加上.html 即可

1
2
3
# 使用abbrlink 来重写固定url  https://segmentfault.com/a/1190000005799711
permalink: ming/:abbrlink.html
permalink_defaults:

标签、归档、分页相关路由 调整
修改 当前目录下node_modules/hexo/lib/plugins/helper/index.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
'use strict';

module.exports = function (ctx) {
。。。

//重写 归档 js 增加index.html 路径 配合 oss 访问
// helper.register('list_categories', require('./list_categories'));
helper.register('list_categories', require('./ming_list_categories'));

。。。

//重写分页相关地址 配合oss
// helper.register('paginator', require('./paginator'));
helper.register('paginator', require('./ming_paginator'));

。。。

// var tagcloud = require('./tagcloud');
// helper.register('tagcloud', tagcloud);
// helper.register('tag_cloud', tagcloud);
//引入 自定义 tag cloud 标签 修改生成路径的函数 适应oss
var ming_tag = require('./ming_tag')
helper.register('tagcloud', ming_tag);
helper.register('tag_cloud', ming_tag);
。。。

在index.js目录下
新增下面三个文件

归档插件的实现
新增 ming_list_categories.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
'use strict';

function listCategoriesHelper(categories, options) {
if (!options && (!categories || !categories.hasOwnProperty('length'))) {
options = categories;
categories = this.site.categories;
}

if (!categories || !categories.length) return '';
options = options || {};

var style = options.hasOwnProperty('style') ? options.style : 'list';
var showCount = options.hasOwnProperty('show_count') ? options.show_count : true;
var className = options.class || 'category';
var depth = options.depth ? parseInt(options.depth, 10) : 0;
var orderby = options.orderby || 'name';
var order = options.order || 1;
var transform = options.transform;
var separator = options.hasOwnProperty('separator') ? options.separator : ', ';
var showCurrent = options.show_current || false;
// 添加 /index.html 配合oss 访问
//var suffix = options.suffix || '';
var suffix = "index.html";
var childrenIndicator = options.hasOwnProperty('children_indicator') ? options.children_indicator : false;
var result = '';
var self = this;

function prepareQuery(parent) {
var query = {};

if (parent) {
query.parent = parent;
} else {
query.parent = {$exists: false};
}

return categories.find(query).sort(orderby, order).filter(function(cat) {
return cat.length;
});
}

function hierarchicalList(level, parent) {
var result = '';

prepareQuery(parent).forEach(function(cat, i) {
var child;
if (!depth || level + 1 < depth) {
child = hierarchicalList(level + 1, cat._id);
}

var isCurrent = false;
if (showCurrent && self.page) {
for (var j = 0; j < cat.length; j++) {
var post = cat.posts.data[j];
if (post && post._id === self.page._id) {
isCurrent = true;
break;
}
}

// special case: category page
if (!isCurrent && self.page.base) {
if (self.page.base.indexOf(cat.path) === 0) {
isCurrent = true;
}
}
}

var additionalClassName = '';
if (child && childrenIndicator) {
additionalClassName = ' ' + childrenIndicator;
}

result += '<li class="' + className + '-list-item' + additionalClassName + '">';
result += '<a class="' + className + '-list-link' + (isCurrent ? ' current' : '') + '" href="' + self.url_for(cat.path) + suffix + '">';
result += transform ? transform(cat.name) : cat.name;
result += '</a>';

if (showCount) {
result += '<span class="' + className + '-list-count">' + cat.length + '</span>';
}

if (child) {
result += '<ul class="' + className + '-list-child">' + child + '</ul>';
}

result += '</li>';
});

return result;
}

function flatList(level, parent) {
var result = '';

prepareQuery(parent).forEach(function(cat, i) {
if (i || level) result += separator;

result += '<a class="' + className + '-link" href="' + self.url_for(cat.path) + suffix + '">';
result += transform ? transform(cat.name) : cat.name;

if (showCount) {
result += '<span class="' + className + '-count">' + cat.length + '</span>';
}

result += '</a>';

if (!depth || level + 1 < depth) {
result += flatList(level + 1, cat._id);
}
});

return result;
}

if (style === 'list') {
result += '<ul class="' + className + '-list">' + hierarchicalList(0) + '</ul>';
} else {
result += flatList(0);
}

return result;
}

module.exports = listCategoriesHelper;

分页插件的实现
新增 ming_paginator.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
'use strict';

function paginatorHelper(options) {
options = options || {};

var current = options.current || this.page.current || 0;
var total = options.total || this.page.total || 1;
var endSize = options.hasOwnProperty('end_size') ? +options.end_size : 1;
var midSize = options.hasOwnProperty('mid_size') ? +options.mid_size : 2;
var space = options.hasOwnProperty('space') ? options.space : '&hellip;';
var base = options.base || this.page.base || '';
var format = options.format || this.config.pagination_dir + '/%d/';
var prevText = options.prev_text || 'Prev';
var nextText = options.next_text || 'Next';
var prevNext = options.hasOwnProperty('prev_next') ? options.prev_next : true;
var transform = options.transform;
var self = this;
var result = '';
var i;
//配合 oss 使用index.html
var suffix = "index.html";


if (!current) return '';

var currentPage = '<span class="page-number current">' +
(transform ? transform(current) : current) +
'</span>';

function link(i) {
return self.url_for(i === 1 ? base : base + format.replace('%d', i));
}

function pageLink(i) {
return '<a class="page-number" href="' + link(i) + suffix +'">' +
(transform ? transform(i) : i) +
'</a>';
}

// Display the link to the previous page
if (prevNext && current > 1) {
result += '<a class="extend prev" rel="prev" href="' + link(current - 1) + suffix +'">' + prevText + '</a>';
}

if (options.show_all) {
// Display pages on the left side of the current page
for (i = 1; i < current; i++) {
result += pageLink(i);
}

// Display the current page
result += currentPage;

// Display pages on the right side of the current page
for (i = current + 1; i <= total; i++) {
result += pageLink(i);
}
} else {
// It's too complicated. May need refactor.
var leftEnd = current <= endSize ? current - 1 : endSize;
var rightEnd = total - current <= endSize ? current + 1 : total - endSize + 1;
var leftMid = current - midSize <= endSize ? leftEnd + 1 : current - midSize;
var rightMid = current + midSize + endSize > total ? rightEnd - 1 : current + midSize;
var spaceHtml = '<span class="space">' + space + '</span>';

// Display pages on the left edge
for (i = 1; i <= leftEnd; i++) {
result += pageLink(i);
}

// Display spaces between edges and middle pages
if (space && current - endSize - midSize > 1) {
result += spaceHtml;
}

// Display left middle pages
if (leftMid > leftEnd) {
for (i = leftMid; i < current; i++) {
result += pageLink(i);
}
}

// Display the current page
result += currentPage;

// Display right middle pages
if (rightMid < rightEnd) {
for (i = current + 1; i <= rightMid; i++) {
result += pageLink(i);
}
}

// Display spaces between edges and middle pages
if (space && total - endSize - midSize > current) {
result += spaceHtml;
}

// Dispaly pages on the right edge
for (i = rightEnd; i <= total; i++) {
result += pageLink(i);
}
}

// Display the link to the next page
if (prevNext && current < total) {
result += '<a class="extend next" rel="next" href="' + link(current + 1) + suffix+ '">' + nextText + '</a>';
}

return result;
}

module.exports = paginatorHelper;

标签插件的实现
新增 ming_tag.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
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
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
'use strict';

// https://github.com/imathis/hsl-picker/blob/master/assets/javascripts/modules/color.coffee
var rHex3 = /^#([0-9a-f]{3})$/;
var rHex6 = /^#([0-9a-f]{6})$/;
var rRGB = /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,?\s*(0?\.?\d+)?\s*\)$/;
var rHSL = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*,?\s*(0?\.?\d+)?\s*\)$/;

// http://www.w3.org/TR/css3-color/#svg-color
var colorNames = {
aliceblue: {r: 240, g: 248, b: 255, a: 1},
antiquewhite: {r: 250, g: 235, b: 215, a: 1},
aqua: {r: 0, g: 255, b: 255, a: 1},
aquamarine: {r: 127, g: 255, b: 212, a: 1},
azure: {r: 240, g: 255, b: 255, a: 1},
beige: {r: 245, g: 245, b: 220, a: 1},
bisque: {r: 255, g: 228, b: 196, a: 1},
black: {r: 0, g: 0, b: 0, a: 1},
blanchedalmond: {r: 255, g: 235, b: 205, a: 1},
blue: {r: 0, g: 0, b: 255, a: 1},
blueviolet: {r: 138, g: 43, b: 226, a: 1},
brown: {r: 165, g: 42, b: 42, a: 1},
burlywood: {r: 222, g: 184, b: 135, a: 1},
cadetblue: {r: 95, g: 158, b: 160, a: 1},
chartreuse: {r: 127, g: 255, b: 0, a: 1},
chocolate: {r: 210, g: 105, b: 30, a: 1},
coral: {r: 255, g: 127, b: 80, a: 1},
cornflowerblue: {r: 100, g: 149, b: 237, a: 1},
cornsilk: {r: 255, g: 248, b: 220, a: 1},
crimson: {r: 220, g: 20, b: 60, a: 1},
cyan: {r: 0, g: 255, b: 255, a: 1},
darkblue: {r: 0, g: 0, b: 139, a: 1},
darkcyan: {r: 0, g: 139, b: 139, a: 1},
darkgoldenrod: {r: 184, g: 134, b: 11, a: 1},
darkgray: {r: 169, g: 169, b: 169, a: 1},
darkgreen: {r: 0, g: 100, b: 0, a: 1},
darkgrey: {r: 169, g: 169, b: 169, a: 1},
darkkhaki: {r: 189, g: 183, b: 107, a: 1},
darkmagenta: {r: 139, g: 0, b: 139, a: 1},
darkolivegreen: {r: 85, g: 107, b: 47, a: 1},
darkorange: {r: 255, g: 140, b: 0, a: 1},
darkorchid: {r: 153, g: 50, b: 204, a: 1},
darkred: {r: 139, g: 0, b: 0, a: 1},
darksalmon: {r: 233, g: 150, b: 122, a: 1},
darkseagreen: {r: 143, g: 188, b: 143, a: 1},
darkslateblue: {r: 72, g: 61, b: 139, a: 1},
darkslategray: {r: 47, g: 79, b: 79, a: 1},
darkslategrey: {r: 47, g: 79, b: 79, a: 1},
darkturquoise: {r: 0, g: 206, b: 209, a: 1},
darkviolet: {r: 148, g: 0, b: 211, a: 1},
deeppink: {r: 255, g: 20, b: 147, a: 1},
deepskyblue: {r: 0, g: 191, b: 255, a: 1},
dimgray: {r: 105, g: 105, b: 105, a: 1},
dimgrey: {r: 105, g: 105, b: 105, a: 1},
dodgerblue: {r: 30, g: 144, b: 255, a: 1},
firebrick: {r: 178, g: 34, b: 34, a: 1},
floralwhite: {r: 255, g: 250, b: 240, a: 1},
forestgreen: {r: 34, g: 139, b: 34, a: 1},
fuchsia: {r: 255, g: 0, b: 255, a: 1},
gainsboro: {r: 220, g: 220, b: 220, a: 1},
ghostwhite: {r: 248, g: 248, b: 255, a: 1},
gold: {r: 255, g: 215, b: 0, a: 1},
goldenrod: {r: 218, g: 165, b: 32, a: 1},
gray: {r: 128, g: 128, b: 128, a: 1},
green: {r: 0, g: 128, b: 0, a: 1},
greenyellow: {r: 173, g: 255, b: 47, a: 1},
grey: {r: 128, g: 128, b: 128, a: 1},
honeydew: {r: 240, g: 255, b: 240, a: 1},
hotpink: {r: 255, g: 105, b: 180, a: 1},
indianred: {r: 205, g: 92, b: 92, a: 1},
indigo: {r: 75, g: 0, b: 130, a: 1},
ivory: {r: 255, g: 255, b: 240, a: 1},
khaki: {r: 240, g: 230, b: 140, a: 1},
lavender: {r: 230, g: 230, b: 250, a: 1},
lavenderblush: {r: 255, g: 240, b: 245, a: 1},
lawngreen: {r: 124, g: 252, b: 0, a: 1},
lemonchiffon: {r: 255, g: 250, b: 205, a: 1},
lightblue: {r: 173, g: 216, b: 230, a: 1},
lightcoral: {r: 240, g: 128, b: 128, a: 1},
lightcyan: {r: 224, g: 255, b: 255, a: 1},
lightgoldenrodyellow: {r: 250, g: 250, b: 210, a: 1},
lightgray: {r: 211, g: 211, b: 211, a: 1},
lightgreen: {r: 144, g: 238, b: 144, a: 1},
lightgrey: {r: 211, g: 211, b: 211, a: 1},
lightpink: {r: 255, g: 182, b: 193, a: 1},
lightsalmon: {r: 255, g: 160, b: 122, a: 1},
lightseagreen: {r: 32, g: 178, b: 170, a: 1},
lightskyblue: {r: 135, g: 206, b: 250, a: 1},
lightslategray: {r: 119, g: 136, b: 153, a: 1},
lightslategrey: {r: 119, g: 136, b: 153, a: 1},
lightsteelblue: {r: 176, g: 196, b: 222, a: 1},
lightyellow: {r: 255, g: 255, b: 224, a: 1},
lime: {r: 0, g: 255, b: 0, a: 1},
limegreen: {r: 50, g: 205, b: 50, a: 1},
linen: {r: 250, g: 240, b: 230, a: 1},
magenta: {r: 255, g: 0, b: 255, a: 1},
maroon: {r: 128, g: 0, b: 0, a: 1},
mediumaquamarine: {r: 102, g: 205, b: 170, a: 1},
mediumblue: {r: 0, g: 0, b: 205, a: 1},
mediumorchid: {r: 186, g: 85, b: 211, a: 1},
mediumpurple: {r: 147, g: 112, b: 219, a: 1},
mediumseagreen: {r: 60, g: 179, b: 113, a: 1},
mediumslateblue: {r: 123, g: 104, b: 238, a: 1},
mediumspringgreen: {r: 0, g: 250, b: 154, a: 1},
mediumturquoise: {r: 72, g: 209, b: 204, a: 1},
mediumvioletred: {r: 199, g: 21, b: 133, a: 1},
midnightblue: {r: 25, g: 25, b: 112, a: 1},
mintcream: {r: 245, g: 255, b: 250, a: 1},
mistyrose: {r: 255, g: 228, b: 225, a: 1},
moccasin: {r: 255, g: 228, b: 181, a: 1},
navajowhite: {r: 255, g: 222, b: 173, a: 1},
navy: {r: 0, g: 0, b: 128, a: 1},
oldlace: {r: 253, g: 245, b: 230, a: 1},
olive: {r: 128, g: 128, b: 0, a: 1},
olivedrab: {r: 107, g: 142, b: 35, a: 1},
orange: {r: 255, g: 165, b: 0, a: 1},
orangered: {r: 255, g: 69, b: 0, a: 1},
orchid: {r: 218, g: 112, b: 214, a: 1},
palegoldenrod: {r: 238, g: 232, b: 170, a: 1},
palegreen: {r: 152, g: 251, b: 152, a: 1},
paleturquoise: {r: 175, g: 238, b: 238, a: 1},
palevioletred: {r: 219, g: 112, b: 147, a: 1},
papayawhip: {r: 255, g: 239, b: 213, a: 1},
peachpuff: {r: 255, g: 218, b: 185, a: 1},
peru: {r: 205, g: 133, b: 63, a: 1},
pink: {r: 255, g: 192, b: 203, a: 1},
plum: {r: 221, g: 160, b: 221, a: 1},
powderblue: {r: 176, g: 224, b: 230, a: 1},
purple: {r: 128, g: 0, b: 128, a: 1},
red: {r: 255, g: 0, b: 0, a: 1},
rosybrown: {r: 188, g: 143, b: 143, a: 1},
royalblue: {r: 65, g: 105, b: 225, a: 1},
saddlebrown: {r: 139, g: 69, b: 19, a: 1},
salmon: {r: 250, g: 128, b: 114, a: 1},
sandybrown: {r: 244, g: 164, b: 96, a: 1},
seagreen: {r: 46, g: 139, b: 87, a: 1},
seashell: {r: 255, g: 245, b: 238, a: 1},
sienna: {r: 160, g: 82, b: 45, a: 1},
silver: {r: 192, g: 192, b: 192, a: 1},
skyblue: {r: 135, g: 206, b: 235, a: 1},
slateblue: {r: 106, g: 90, b: 205, a: 1},
slategray: {r: 112, g: 128, b: 144, a: 1},
slategrey: {r: 112, g: 128, b: 144, a: 1},
snow: {r: 255, g: 250, b: 250, a: 1},
springgreen: {r: 0, g: 255, b: 127, a: 1},
steelblue: {r: 70, g: 130, b: 180, a: 1},
tan: {r: 210, g: 180, b: 140, a: 1},
teal: {r: 0, g: 128, b: 128, a: 1},
thistle: {r: 216, g: 191, b: 216, a: 1},
tomato: {r: 255, g: 99, b: 71, a: 1},
turquoise: {r: 64, g: 224, b: 208, a: 1},
violet: {r: 238, g: 130, b: 238, a: 1},
wheat: {r: 245, g: 222, b: 179, a: 1},
white: {r: 255, g: 255, b: 255, a: 1},
whitesmoke: {r: 245, g: 245, b: 245, a: 1},
yellow: {r: 255, g: 255, b: 0, a: 1},
yellowgreen: {r: 154, g: 205, b: 50, a: 1}
};

function tagcloudHelper(tags, options) {
if (!options && (!tags || !tags.hasOwnProperty('length'))) {
options = tags;
tags = this.site.tags;
}

if (!tags || !tags.length) return '';
options = options || {};

var min = options.min_font || 10;
var max = options.max_font || 20;
var orderby = options.orderby || 'name';
var order = options.order || 1;
var unit = options.unit || 'px';
var color = options.color;
var transform = options.transform;
var separator = options.separator || ' ';
var result = [];
var self = this;
var startColor, endColor;

if (color) {
startColor = new Color(options.start_color);
endColor = new Color(options.end_color);

if (!startColor || !endColor) color = false;
}

// Sort the tags
if (orderby === 'random' || orderby === 'rand') {
tags = tags.random();
} else {
tags = tags.sort(orderby, order);
}

// Ignore tags with zero posts
tags = tags.filter(function(tag) {
return tag.length;
});

// Limit the number of tags
if (options.amount) {
tags = tags.limit(options.amount);
}

var sizes = [];

tags.sort('length').forEach(function(tag) {
var length = tag.length;
if (~sizes.indexOf(length)) return;

sizes.push(length);
});

var length = sizes.length - 1;

tags.forEach(function(tag) {
var ratio = length ? sizes.indexOf(tag.length) / length : 0;
var size = min + ((max - min) * ratio);
var style = 'font-size: ' + parseFloat(size.toFixed(2)) + unit + ';';

if (color) {
var midColor = startColor.mix(endColor, ratio);
style += ' color: ' + midColor.toString();
}

result.push(
// 增加/index.html 跳转地址
'<a href="' + self.url_for(tag.path) + 'index.html" style="' + style + '">' +
(transform ? transform(tag.name) : tag.name) +
'</a>'
);
});

return result.join(separator);
}

function Color(color) {
if (typeof color === 'object') {
this.r = color.r;
this.g = color.g;
this.b = color.b;
this.a = color.a;
} else if (typeof color === 'string') {
this.parse(color);
} else {
throw new TypeError('color is required!');
}

if (this.r < 0 || this.r > 255 ||
this.g < 0 || this.g > 255 ||
this.b < 0 || this.b > 255 ||
this.a < 0 || this.a > 1) {
throw new Error(color + ' is invalid.');
}
}

Color.prototype.parse = function(color) {
color = color.toLowerCase();

if (colorNames.hasOwnProperty(color)) {
var obj = colorNames[color];

this.r = obj.r;
this.g = obj.g;
this.b = obj.b;
this.a = obj.a;

return;
}

var match, txt, code;

if (rHex3.test(color)) {
txt = color.substring(1);
code = parseInt(txt, 16);

this.r = ((code & 0xF00) >> 8) * 17;
this.g = ((code & 0xF0) >> 4) * 17;
this.b = (code & 0xF) * 17;
this.a = 1;
} else if (rHex6.test(color)) {
txt = color.substring(1);
code = parseInt(txt, 16);

this.r = (code & 0xFF0000) >> 16;
this.g = (code & 0xFF00) >> 8;
this.b = code & 0xFF;
this.a = 1;
} else if (rRGB.test(color)) {
match = color.match(rRGB);

this.r = match[1] | 0;
this.g = match[2] | 0;
this.b = match[3] | 0;
this.a = match[4] ? +match[4] : 1;
} else if (rHSL.test(color)) {
match = color.match(rHSL);

var h = +match[1] / 360;
var s = +match[2] / 100;
var l = +match[3] / 100;

this.a = match[4] ? +match[4] : 1;

if (!s) {
this.r = this.g = this.b = l * 255;
}

var q = l < 0.5 ? l * (1 + s) : l + s - (l * s);
var p = (2 * l) - q;

var rt = h + (1 / 3);
var gt = h;
var bt = h - (1 / 3);

this.r = convertHue(p, q, rt);
this.g = convertHue(p, q, gt);
this.b = convertHue(p, q, bt);
} else {
throw new Error(color + ' is not a supported color format.');
}
};

Color.prototype.toString = function() {
if (this.a === 1) {
var r = convertRGB(this.r);
var g = convertRGB(this.g);
var b = convertRGB(this.b);

if (this.r % 17 || this.g % 17 || this.b % 17) {
return '#' + r + g + b;
}

return '#' + r[0] + g[0] + b[0];
}

return 'rgba(' + this.r + ', ' + this.g + ', ' + this.b + ', ' + parseFloat(this.a.toFixed(2)) + ')';
};

Color.prototype.mix = function(color, ratio) {
switch (ratio) {
case 0:
return new Color(this);

case 1:
return new Color(color);
}

return new Color({
r: Math.round(mixValue(this.r, color.r, ratio)),
g: Math.round(mixValue(this.g, color.g, ratio)),
b: Math.round(mixValue(this.b, color.b, ratio)),
a: mixValue(this.a, color.a, ratio)
});
};

function convertHue(p, q, h) {
if (h < 0) h++;
if (h > 1) h--;

var color;

if (h * 6 < 1) {
color = p + ((q - p) * h * 6);
} else if (h * 2 < 1) {
color = q;
} else if (h * 3 < 2) {
color = p + ((q - p) * ((2 / 3) - h) * 6);
} else {
color = p;
}

return Math.round(color * 255);
}

function convertRGB(value) {
var str = value.toString(16);
if (value < 16) return '0' + str;

return str;
}

function mixValue(a, b, ratio) {
return a + ((b - a) * ratio);
}

module.exports = tagcloudHelper;

参考地址: https://github.com/xuxianyu/ming/tree/master/hexo

实例地址: https://www.xujiuming.com 本网站就是采用这种方法实现的