最近在b站考古,发现有人做了一只live2d的然然模型

B站原视频
这能忍住的都是神人好吧!
于是顺藤摸瓜在 GitHub 上发现了一位嘉心糖写的js可以在b站右下角添加嘉然小姐的live2d模型
这不现成的吗!直接引入主题的配置文件就能开用了🤤🥰


在这之前先注明一下来源:

以上模型作者为木果阿木果

Js源码来自 journey-ad 的 oh-my-diana.user.js

开始步骤

为避免歧义,以下声明的代码修改位置均以 GitHub Gist 中的源码为准

省流起见先直接贴上修改后的完整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
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
(async function () {
'use strict';

if (inIframe()) {
console.log('iframe中不加载');
return false;
}

const 引流 = [
"https://space.bilibili.com/672328094",
"https://www.bilibili.com/video/BV1FZ4y1F7HH",
"https://www.bilibili.com/video/BV1FX4y1g7u8",
"https://www.bilibili.com/video/BV1aK4y1P7Cg",
"https://www.bilibili.com/video/BV17A411V7Uh",
"https://www.bilibili.com/video/BV1JV411b7Pc",
"https://www.bilibili.com/video/BV1AV411v7er",
"https://www.bilibili.com/video/BV1564y1173Q",

"https://www.bilibili.com/video/BV1MX4y1N75X",
"https://www.bilibili.com/video/BV17h411U71w",
"https://www.bilibili.com/video/BV1ry4y1Y71t",
"https://www.bilibili.com/video/BV1Sy4y1n7c4",
"https://www.bilibili.com/video/BV15y4y177uk",
"https://www.bilibili.com/video/BV1PN411X7QW",
"https://www.bilibili.com/video/BV1Dp4y1H7iB",
"https://www.bilibili.com/video/BV1bi4y1P7Eh",
"https://www.bilibili.com/video/BV1vQ4y1Z7C2",
"https://www.bilibili.com/video/BV1oU4y1h7Sc",
]

const CUSTOM_CSS = `#pio-container {
display: block !important;
bottom: -0.3rem;
right: 3.5rem;
z-index: 22637261;
transition: transform 0.3s;
cursor: grab;
}

#pio-container:hover {
transform: translateY(-0.3rem);
}

#pio-container:active {
cursor: grabbing;
}

#pio-container .pio-dialog {
top: -2rem;
right: -10%;
line-height: 1.5;
background: rgba(255, 255, 255, 0.9);
}

#pio {
height: 240px;
}

.pio-action .pio-home {
display: none;
}

.pio-action span {
background: none;
background-size: 100%;
border: 1px solid #fdcf7b;
border: 0;
width: 2em;
height: 2em;
margin-bottom: 0.6em;
}

.pio-action .pio-skin {
background: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 512c0 282.774 229.226 512 512 512s512-229.226 512-512S794.774 0 512 0 0 229.226 0 512z' fill='%23FEC43C'/%3E%3Cpath d='M1013.76 408.576C965.632 175.104 759.808 0 512 0 229.376 0 0 229.376 0 512c0 123.904 44.032 236.544 116.736 324.608 87.04 48.128 186.368 74.752 292.864 74.752 301.056 0 550.912-217.088 604.16-502.784z' fill='%23FFD73A'/%3E%3Cpath d='M233.456 460.383a93.759 93.759 0 1 0 187.526 0c0-51.783-41.984-93.76-93.767-93.76s-93.759 41.977-93.759 93.76zm458.39 0c0 51.782 41.976 93.759 93.759 93.759s93.759-41.984 93.759-93.76c0-51.782-41.984-93.758-93.76-93.758-51.782 0-93.758 41.976-93.758 93.759z' fill='%23873A18'/%3E%3Cpath d='M556.41 689.577H410.561c-17.707 0-31.256-13.548-31.256-31.255 0-17.715 13.549-31.256 31.256-31.256h145.85c17.714 0 31.255 13.548 31.255 31.256s-13.549 31.255-31.256 31.255zM320.97 429.127H156.357c-14.588 0-27.089-13.548-27.089-31.256s12.5-31.247 27.097-31.247H320.96c14.58 0 27.089 13.54 27.089 31.247 0 17.715-12.509 31.256-27.097 31.256zm454.215 0H618.92c-17.715 0-31.255-13.548-31.255-31.256s13.548-31.247 31.255-31.247h156.263c17.715 0 31.255 13.54 31.255 31.247 0 17.715-13.548 31.256-31.255 31.256z' fill='%23873A18'/%3E%3Cpath d='M102.4 327.68C46.08 327.68 0 281.6 0 225.28 0 133.12 102.4 0 102.4 0s102.4 133.12 102.4 225.28c0 56.32-46.08 102.4-102.4 102.4z' fill='%2361A3E0'/%3E%3C/svg%3E");
}

.pio-action .pio-info {
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 500 500' xmlns='http://www.w3.org/2000/svg'%3E%3Crect transform='rotate(45.001 238.211 363.575)' x='29.285' y='22.411' width='273.903' height='505.038' rx='70' ry='70' fill='%23dcdcdc'/%3E%3Cpath d='M218.543 249.999l-47.186 47.186c-8.987 8.988-8.987 22.47 0 31.457 8.988 8.988 22.47 8.988 31.457 0L250 281.456l15.728 15.729c17.976 17.976 17.976 46.063 0 64.038l-64.037 64.038c-17.976 17.975-46.063 17.975-64.038 0l-64.038-64.038c-17.975-17.975-17.975-46.062 0-64.038l64.038-64.037c17.975-17.976 46.062-17.976 64.038 0l16.852 16.851z' fill='%23fff'/%3E%3Cpath d='M281.457 249.999l47.186-47.186c8.988-8.987 8.988-22.469 0-31.457-8.987-8.987-22.469-8.987-31.457 0L250 218.542l-15.729-15.729c-17.975-17.975-17.975-46.062 0-64.037l64.038-64.038c17.975-17.975 46.062-17.975 64.038 0l64.037 64.038c17.977 17.975 17.977 46.062 0 64.037l-64.037 64.038c-17.976 17.976-46.063 17.976-64.038 0l-16.852-16.852z' fill='%2361a3e0'/%3E%3C/svg%3E");
}

.pio-action .pio-top {
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 500 500' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M262.737 70.075c-3.175-2.89-8.439-5.365-12.737-5.365-4.29 0-9.448 2.37-12.632 5.263l-87.814 87.812c-2.921 3.255-5.23 8.518-5.23 12.73 0 4.203 2.196 9.353 5.118 12.617 3.246 2.915 8.621 5.345 12.842 5.345 4.203 0 9.353-2.197 12.617-5.118l75.093-74.848 74.992 74.993c3.175 2.889 8.433 5.359 12.731 5.359 4.29 0 9.448-2.371 12.632-5.263 2.918-3.247 5.329-8.61 5.329-12.827 0-4.204-2.197-9.354-5.118-12.616zm-103.97 233.514v-36.181H19.695v36.181h51.447v131.444h36.178V303.589zm126.788-35.923h-63.85c-8.732.187-18.571 3.868-25.539 10.451-6.579 6.961-10.367 16.85-10.557 25.589v95.488c.179 8.709 3.781 18.668 10.493 25.582 6.913 6.712 16.839 10.334 25.548 10.514h63.849c8.732-.187 18.571-3.868 25.538-10.45 6.581-6.962 10.368-16.852 10.558-25.59v-95.488c-.187-8.733-3.87-18.573-10.452-25.539-6.962-6.581-16.85-10.367-25.588-10.557zm-.14 131.589l.003.105.403.021a20.74 20.74 0 0 0-.322-.013h-.08c.006.172.014.313.021.414l-.027-.414h-.118l.01-.013.107.005-.007-.117-.033.025-.079.1h-63.648l-.106.003-.032.438c.007-.092.015-.243.021-.438-.163.005-.283.012-.365.017l.365-.023.003-.139-.055-.039-.301-.208.356.244.001-.029v-95.493a3.627 3.627 0 0 0-.004-.108l-.417-.028c.106.007.253.014.417.019a10.069 10.069 0 0 0-.023-.42l.031.42.123.004.016-.022.087-.113.036-.047-.137.182.044.001h63.551l.096.074.064.05-.001.049zm184.441-121.032c-6.963-6.58-16.852-10.367-25.59-10.557h-88.627V435.29h36.181v-68.165h52.39c8.732-.187 18.572-3.87 25.54-10.452 6.579-6.961 10.366-16.851 10.556-25.588v-27.323c-.187-8.733-3.868-18.572-10.45-25.539zm-25.471 52.609l.003.105.437.032a10.682 10.682 0 0 0-.437-.021c.007.211.017.355.023.436l-.033-.436a79.554 79.554 0 0 0-.142-.003l-.038.054-.112.166-.119.175.262-.396H391.82v-27.099h52.451l.112-.004.025-.405a14.96 14.96 0 0 0-.018.405c.171-.006.313-.015.416-.023l-.416.031-.004.122-.01-.008.007-.113-.119.008.041.054.081.062-.001.045z' fill='%234c4c4c'/%3E%3C/svg%3E");
}

.pio-action .pio-close {
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 500 500' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M249.999 198.668L352.665 96c14.667-14.666 36.668-14.666 51.335 0 14.666 14.667 14.666 36.668 0 51.334L301.333 250 404 352.668c14.666 14.667 14.666 36.666 0 51.332-14.667 14.667-36.667 14.667-51.334 0L249.999 301.334 147.333 404c-14.668 14.667-36.666 14.667-51.334 0-14.666-14.666-14.666-36.665 0-51.332L198.666 250 95.999 147.334c-14.666-14.666-14.666-36.667 0-51.334 14.668-14.666 36.665-14.666 51.333 0l102.667 102.668z' fill='%23873a18'/%3E%3C/svg%3E");
}
`

// 用到的库
const LIBS = [
'https://cdn.jsdmirror.com/gh/journey-ad/blog-img@94eb7e2/live2d/lib/pio.css',
'https://cdn.jsdmirror.com/npm/greensock@1.20.2/dist/TweenLite.js',
'https://cubism.live2d.com/sdk-web/cubismcore/live2dcubismcore.min.js',
'https://cdn.jsdmirror.com/npm/pixi.js@5.3.6/dist/pixi.min.js',
'https://cdn.jsdmirror.com/npm/pixi-live2d-display@0.3.1/dist/cubism4.min.js',
'https://cdn.jsdmirror.com/gh/journey-ad/blog-img@94eb7e2/live2d/lib/pio_sdk4.js',
'https://cdn.jsdmirror.com/gh/journey-ad/blog-img@94eb7e2/live2d/lib/pio.js'
]

const reqArr = LIBS.map(src => loadSource(src))

// 创建顺序加载队列
const doTask = reqArr.reduce((prev, next) => prev.then(() => next()), Promise.resolve());

// 队列执行完毕后
doTask.then(() => {
// 移除自带看板娘
const haruna = document.getElementById('my-dear-haruna-vm')
haruna && haruna.remove()

// 初始化pio
_pio_initialize_pixi()

// 添加自定义样式
addStyle(CUSTOM_CSS)

加载圣·嘉然()

console.log("all done.")
});

// 初始化设定
const initConfig = {
mode: "fixed",
hidden: true,
content: {
link: 引流[Math.floor(Math.random() * 引流.length)], // 引流链接
referer: "Hi!", // 存在访问来源时的欢迎文本
welcome: ["Hi!"], // 未开启时间问好时的欢迎文本
skin: ["诶,想看看其他团员吗?", "替换后入场文本"], // 0更换模型提示文案 1更换完毕入场文案
custom: [
// 鼠标移上去提示元素
{ "selector": ".most-viewed-panel .most-viewed-item, .live-up-list .live-detail, .card .user-name, .user .name, .post-content .content-full a, .tag-list .content, .title, h2 a[title]", "type": "link" }
],
},
model: [
// 待加载的模型列表
"https://cdn.jsdmirror.com/gh/journey-ad/blog-img/live2d/Diana/Diana.model3.json",
"https://cdn.jsdmirror.com/gh/journey-ad/blog-img/live2d/Ava/Ava.model3.json",
],
tips: true, // 时间问好
onModelLoad: onModelLoad // 模型加载完成回调
}

let pio_reference // pio实例

function 加载圣·嘉然() {
pio_reference = new Paul_Pio(initConfig)

pio_alignment = "right" // 右下角

const closeBtn = document.querySelector(".pio-container .pio-action .pio-close")
closeBtn.insertAdjacentHTML('beforebegin', '<span class="pio-top"></span>')
const topBtn = document.querySelector(".pio-container .pio-action .pio-top")
// 返回顶部
topBtn.onclick = function () {
window.scrollTo({ top: 0, behavior: 'smooth' });
};
topBtn.onmouseover = function () {
pio_reference.modules.render("想回到页面顶部吗?");
};

// Then apply style
pio_refresh_style()
}

// 模型加载完成回调
function onModelLoad(model) {
const canvas = document.getElementById("pio")
const modelNmae = model.internalModel.settings.name
const coreModel = model.internalModel.coreModel
const motionManager = model.internalModel.motionManager

let touchList = [
{
text: "点击展示文本1",
motion: "Idle"
},
{
text: "点击展示文本2",
motion: "Idle"
}
]

// 播放动作
function playAction(action) {
action.text && pio_reference.modules.render(action.text) // 展示文案
action.motion && pio_reference.model.motion(action.motion) // 播放动作

if (action.from && action.to) {
// 指定部件渐入渐出
Object.keys(action.from).forEach(id => {
const hidePartIndex = coreModel._partIds.indexOf(id)
TweenLite.to(coreModel._partOpacities, 0.6, { [hidePartIndex]: action.from[id] });
// coreModel._partOpacities[hidePartIndex] = action.from[id]
})

motionManager.once("motionFinish", (data) => {
Object.keys(action.to).forEach(id => {
const hidePartIndex = coreModel._partIds.indexOf(id)
TweenLite.to(coreModel._partOpacities, 0.6, { [hidePartIndex]: action.to[id] });
// coreModel._partOpacities[hidePartIndex] = action.to[id]
})
})
}
}

canvas.onclick = function () {
// 除闲置动作外不打断
if (motionManager.state.currentGroup !== "Idle") return

// 随机选择并播放动作
const action = pio_reference.modules.rand(touchList)
playAction(action)
}

if (modelNmae === "Diana") {
// 嘉然小姐

// 入场动作及文案
initConfig.content.skin[1] = ["我是吃货担当 嘉然 Diana~", "嘉心糖们 想然然了没有呀~", "有人在吗?"]
playAction({ motion: "Tap抱阿草-左手" })

// 点击动作及文案,不区分区域
touchList = [
{
text: "嘉心糖屁用没有",
motion: "Tap生气 -领结"
},
{
text: "有人急了,但我不说是谁~",
motion: "Tap= = 左蝴蝶结"
},
{
text: "呜呜...呜呜呜....",
motion: "Tap哭 -眼角"
},
{
text: "想然然了没有呀~",
motion: "Tap害羞-中间刘海"
},
{
text: "阿草好软呀~",
motion: "Tap抱阿草-左手"
},
{
text: "不要再戳啦!好痒!",
motion: "Tap摇头- 身体"
},
{
text: "嗷呜~~~",
motion: "Tap耳朵-发卡"
},
{
text: "zzZ。。。",
motion: "Leave"
},
{
text: "哇!好吃的!",
motion: "Tap右头发"
},
]

} else if (modelNmae === "Ava") {
initConfig.content.skin[1] = ["我是<s>拉胯</s>Gamer担当 向晚 AvA~", "怎么推流辣!", "AAAAAAAAAAvvvvAAA 向晚!"]
playAction({
motion: "Tap左眼",
from: {
"Part15": 1
},
to: {
"Part15": 0
}
})

touchList = [
{
text: "水母 水母~ 只是普通的生物",
motion: "Tap右手"
},
{
text: "可爱的鸽子鸽子~我喜欢你~",
motion: "Tap胸口项链",
from: {
"Part12": 1
},
to: {
"Part12": 0
}
},
{
text: "好...好兄弟之间喜欢很正常啦",
motion: "Tap中间刘海",
from: {
"Part12": 1
},
to: {
"Part12": 0
}
},
{
text: "啊啊啊!怎么推流辣",
motion: "Tap右眼",
from: {
"Part16": 1
},
to: {
"Part16": 0
}
},
{
text: "你怎么老摸我,我的身体是不是可有魅力",
motion: "Tap嘴"
},
{
text: "AAAAAAAAAAvvvvAAA 向晚!",
motion: "Tap左眼",
from: {
"Part15": 1
},
to: {
"Part15": 0
}
}
]

// 钻头比较大,宽度*1.2倍,模型位移也要重新计算
canvas.width = model.width * 1.2
model.x = canvas.width - model.width

// 模型问题,手动隐藏指定部件
const hideParts = [
"Part5", // 晕
"neko", // 喵喵拳
"game", // 左手游戏手柄
"Part15", // 墨镜
"Part21", // 右手小臂
"Part22", // 左手垂下
"Part", // 双手抱拳
"Part16", // 惊讶特效
"Part12" // 小心心
]
const hidePartsIndex = hideParts.map(id => coreModel._partIds.indexOf(id))
hidePartsIndex.forEach(idx => {
coreModel._partOpacities[idx] = 0
})
}
}

// 检测是否处于iframe内嵌环境
function inIframe() {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}

// 加载js或css,返回函数包裹的promise实例,用于顺序加载队列
function loadSource(src) {
return () => {
return new Promise(function (resolve, reject) {
const TYPE = src.split('.').pop()
let s = null;
let r = false;
if (TYPE === 'js') {
s = document.createElement('script');
s.type = 'text/javascript';
s.src = src;
s.async = true;

} else if (TYPE === 'css') {
s = document.createElement('link');
s.rel = 'stylesheet';
s.type = 'text/css';
s.href = src;

}
s.onerror = function (err) {
reject(err, s);
};
s.onload = s.onreadystatechange = function () {
// console.log(this.readyState); // uncomment this line to see which ready states are called.
if (!r && (!this.readyState || this.readyState == 'complete')) {
r = true;
console.log(src)
resolve();
}
};
const t = document.getElementsByTagName('script')[0];
t.parentElement.insertBefore(s, t);
});
}
}

// 添加css
function addStyle(css) {
if (typeof GM_addStyle != "undefined") {
GM_addStyle(css);
} else if (typeof PRO_addStyle != "undefined") {
PRO_addStyle(css);
} else {
const node = document.createElement("style");
node.type = "text/css";
node.appendChild(document.createTextNode(css));
const heads = document.getElementsByTagName("head");

if (heads.length > 0) {
heads[0].appendChild(node);
} else {
// no head yet, stick it whereever
document.documentElement.appendChild(node);
}
}
}

})();

修改源码

首先需要把原js下载下来,然后保存在主题文件夹下的source/js目录中,可以重命名为更简单的名字。我这里就改成diana.js
然后打开源码,注意到头部的注释部分

1
2
3
4
5
6
7
8
9
10
11
12
// ==UserScript==
// @name #相亲相爱一嘉人#
// @description 在哔站右下角添加嘉然小姐的live2d模型
// @version 1.0.1
// @namespace https://github.com/journey-ad
// @author journey-ad
// @include /^https:\/\/(www|live|space|t)\.bilibili\.com\/.*$/
// @icon https://www.google.com/s2/favicons?domain=bilibili.com
// @license GPL v2
// @run-at document-end
// @grant none
// ==/UserScript==

很明显这是一个油猴脚本,毕竟是给b站右下角添加而准备的,不过没关系,在其他网页一样可用
这段没用,可以直接删去或忽略。我们的重点是在源码的103行150行,在这里可以看到加速CDN使用的是原版jsdelivr,这个CDN在国内的连通性很不好,基本没有可用性,需要替换成可用的CDN。这里我选择改为它的镜像CDNcdn.jsdmirror.com
因此需要做的就是把这两行附近的所有cdn.jsdelivr.net字段替换为cdn.jsdmirror.com即可,其他网页路径不用动。

1
2
3
4
5
6
7
8
9
const LIBS = [
'https://cdn.jsdmirror.com/gh/journey-ad/blog-img@94eb7e2/live2d/lib/pio.css',
'https://cdn.jsdmirror.com/npm/greensock@1.20.2/dist/TweenLite.js',
'https://cubism.live2d.com/sdk-web/cubismcore/live2dcubismcore.min.js',
'https://cdn.jsdmirror.com/npm/pixi.js@5.3.6/dist/pixi.min.js',
'https://cdn.jsdmirror.com/npm/pixi-live2d-display@0.3.1/dist/cubism4.min.js',
'https://cdn.jsdmirror.com/gh/journey-ad/blog-img@94eb7e2/live2d/lib/pio_sdk4.js',
'https://cdn.jsdmirror.com/gh/journey-ad/blog-img@94eb7e2/live2d/lib/pio.js'
]
1
2
3
4
5
model: [
// 待加载的模型列表
"https://cdn.jsdmirror.com/gh/journey-ad/blog-img/live2d/Diana/Diana.model3.json",
"https://cdn.jsdmirror.com/gh/journey-ad/blog-img/live2d/Ava/Ava.model3.json",
],

保存后在主题配置文件里把这个js文件引入:
找到inject部分,在bottom项下按格式引入- <script src="/js/diana.js"></script>,文件路径和文件名要与你自己命名的一致
保存后就可以先本地部署看看效果了,打开网页后会出现在你的右下角

效果图
像我的然然出现的位置就有点太靠右了,挡住了右侧栏的按钮,接下来要微调下位置了

修改位置

找到js源码的第44行,这里开始定义了pio的自定义css样式,从这里下手改位置就行

1
2
3
4
5
6
7
8
const CUSTOM_CSS = `#pio-container {
display: block !important;
bottom: -0.3rem;
right: 3.5rem; /* 我让它距离右侧多增加3.5rem */
z-index: 22637261;
transition: transform 0.3s;
cursor: grab;
}

我还觉得对话框有点低,那就来调高点吧。找到60行,这部分是单独对话框的样式。

1
2
3
4
5
6
#pio-container .pio-dialog {
top: -2rem; /* 同理,距顶部-2rem */
right: -10%; /* 往右10% */
line-height: 1.5;
background: rgba(255, 255, 255, 0.9);
}

如果想让整体出现在左侧,先找到162行,把pio_alignment的值改为"left",上面css的right同理替换为left就行,值的大小根据左右位置来调,可以参考一下css的页面定位。

都调整合适后就完成了!可以deploy上去了。至此你也拥有了自己的看板娘然比和向晚~

心路历程

后面都是折腾的经历,如果不感兴趣可以不用看🥹

起初刚导入js后发现,如果关闭VPN访问网页,这个js是没有任何效果的。那么至少问题不在本地,而与网络有关。这才想起来22年的时候jsdelivr突然被大范围墙了,由于它被广泛用于加速各种包和库,而且还免费,是各大平台的首选CDN,当时还有不少网页因此直接回归远古前端的样子

jsdelivr国内连通性

js里加载的库和模型材质大多也都是GitHub仓库里的东西,想要找到一个其他的平替还真不容易。
但是让我没想到的是CDN居然也有镜像。本来它的作用就是从源那里复制一份缓存存为镜像加速的,这不就成了套娃嘛…?
好在国内的镜像可以胜任,把链接全部替换后js终于能正常加载了!

镜像CDN连通性
一片深绿色直接起飞!…只是速度非常非常缓慢…这不应该啊?我不是套了CDN的吗?
这才意识到,有CDN没有命中缓存也是白搭。镜像站的流量不如原CDN大,这些资源之前没有人访问过也就没有镜像过一遍是很正常的事,导致初次加载缓慢还是因为太冷门了😪
果不其然,用上面ITDOG的HTTP全国测速工具访问了一整套资源文件后,每次访问都流畅无比了顺带在全国的jsdmirror都留下了这些缓存