-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
153 lines (148 loc) · 4.44 KB
/
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
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
/**
* @description Hexo 莉可丽丝「Sakana! Widget」网页组件注入
*/
const _ = require('lodash');
const logger = require('hexo-log')({
debug: false,
silent: false,
});
const defaultConfig = {
// 默认角色
character: 'takina',
// 是否启用
enable: true,
// 是否在移动端启用
enable_mobile: false,
// 组件大小,默认为 200
size: 200,
// 自适应容器大小 (最小 120px)
// 另见:https://github.com/dsrkafuu/sakana-widget/blob/main/README.zh.md#%E8%87%AA%E5%8A%A8%E7%BC%A9%E6%94%BE
autoFit: false,
// 组件据底部距离,需填写单位或百分号
bottom: '0px',
// 是否启用控制栏
controls: true,
// 线条设置
stroke: {
// 颜色
color: '#b4b4b4',
// 粗细
width: 10,
},
// 停止动画的阈值
threshold: 0.1,
// 旋转角度
rotate: 0,
// 自定义角色
customCharacters: [],
/*
customCharacters 中每个元素应为下方的对象
{
// 基础角色,必须为 takina(即井之上泷奈)或 chisato(即锦木千束)
base: "takina",
// 名称,设置默认角色时可填写
name: "takina1",
// 自定义图片(url 或 base64)
image: "https://raw.githubusercontent.com/dsrkafuu/sakana-widget/master/src/characters/takina.png",
// 惯性
i: 0.08,
// 粘性
s: 0.1,
// 衰减
d: 0.988,
// 角度
r: 12,
// 高度
y: 2,
// 垂直速度
t: 0,
// 水平速度
w: 0,
}
*/
};
let config = _.defaultsDeep(
{},
// eslint-disable-next-line no-undef
hexo.config.sakana,
// eslint-disable-next-line no-undef
hexo.theme.config.sakana,
defaultConfig
);
if (config.enable) {
logger.info('启用 hexo-sakana 组件注入');
logger.info(`默认角色:${config.character}`);
logger.info(`配置文件:${JSON.stringify(config)}`);
// eslint-disable-next-line no-undef
hexo.extend.filter.register('after_render:html', (htmlContent) => {
const scriptToInject = `
function log(msg) {
console.log("[hexo-sakana] " + msg);
}
function initSakanaWidget(config) {
if (
!config.enable_mobile &&
window.navigator.userAgent.match(
/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
)
) {
log(
'检测为移动端,且配置中未开启在移动端启用组件,hexo-sakana 已禁用'
);
return;
}
for (character of config.customCharacters) {
if (!["takina", "chisato"].includes(character.base)) {
log(\`无效基础角色 $\{character.base},取消注册\`);
continue;
}
if (character.name === "") {
log("名称为空,取消注册");
continue;
}
const originCharacter = SakanaWidget.getCharacter(character.base);
originCharacter.initialState = {
...originCharacter.initialState,
...character,
};
originCharacter.image = !character.image ? originCharacter.image : character.image
SakanaWidget.registerCharacter(character.name, originCharacter);
log(\`注册自定义角色:$\{character.name}\`)
}
new SakanaWidget({
character: config.character,
size: config.size,
autoFit: config.autoFit,
controls: config.controls,
stroke: config.stroke,
threshold: config.threshold,
rotate: config.rotate,
}).mount("#sakana");
}
`;
const contentToInject = `
<div id="sakana" style="position:fixed;right:0;bottom:${
config.bottom
};"></div>
<script async onload='initSakanaWidget(${JSON.stringify(
config
)})' src="https://npm.elemecdn.com/sakana-widget@2.3.0/lib/sakana.min.js"></script>
<script>${scriptToInject}</script>
`;
let newHtmlContent = htmlContent;
if (/([\n\r\s\t]*<\/body>)/i.test(htmlContent)) {
const lastIndex = htmlContent.lastIndexOf('</body>');
newHtmlContent = `${htmlContent.substring(
0,
lastIndex
)}${contentToInject}${htmlContent.substring(
lastIndex,
htmlContent.length
)}`;
}
return newHtmlContent;
});
logger.info('「Sakana! Widget」组件注入成功');
} else {
logger.info('hexo-sakana 已禁用');
}