文章目录
  1. 1. 更换插件
  2. 2. 本地部署
  3. 3. 自定义配置
    1. 3.1. 插入画布
    2. 3.2. 构造初始化配置方法
    3. 3.3. 构造模型加载方法
    4. 3.4. 样式优化
    5. 3.5. 实现加载
  4. 4. 总结

修复博客问题的时候,发现加载 Live2D 的模型报了一堆错误。仔细看,是由于看板娘的动作文件出错了,而且居然是大小写的问题,想必windows服务器就不会出现这个问题,所以模型的作者并没有发现。

既然都在批量修复问题了,那把这个问题一并处理掉吧。

更换插件

本来想着应该是个很快的过程,找到问题所在,如果可以修复,我也想继续使用这个模型。或者不可以,那我就换个模型继续用。

但是访问 hexo-helper-live2d - https://github.com/EYHN/hexo-helper-live2d 时,顶部黄条让我心头一颤,接着在 Readme 看到一条让人遗憾的说明。

1
2
3
4
5
This repository has been archived by the owner before Nov 9, 2022. It is now read-only.

...

The project is not actively maintained. Please try similar projects stevenjoezhang/live2d-widget

emmm……看最近更新确实都是3年前了。于是循着他的推荐,我去访问了 Live2D Widget - https://github.com/stevenjoezhang/live2d-widget 这个项目。

该项目并不是hexo的特有插件,所以看起来自定义集成会比之前的插件略微麻烦。当然,如果只需要最基本的功能,则比之前还简单。只用将下面这一行代码加入 html 页面的 headbody 中,即可加载看板娘:

1
<script src="https://fastly.jsdelivr.net/gh/stevenjoezhang/live2d-widget@latest/autoload.js"></script>

我以上方式尝试了一下,得到了下图的结果。

然而,我希望博客上的看板娘插件能干干净净的,不说废话,不用换人换装,更不用各种乱七八糟的功能。很明显这并不是我想要的。

略微纠结了一会要不要换回以前的插件,然后打定主意还是要更换为新的,毕竟有维护更新还是更有保障一些。

本地部署

对于线上托管版本,其实项目已经提供了一些可选配置。项目中的 autoload.js 文件也大致都列出来了可选配置。autoload.js 会自动加载三个文件:waifu.csslive2d.min.jswaifu-tips.jswaifu-tips.js 会创建 initWidget 函数,这就是加载看板娘的主函数。initWidget 函数接收一个 Object 类型的参数,作为看板娘的配置。

选项 类型 默认值 说明
waifuPath string https://fastly.jsdelivr.net/gh/stevenjoezhang/live2d-widget@latest/waifu-tips.json 看板娘资源路径,可自行修改
apiPath string https://live2d.fghrsh.net/api/ API 路径,可选参数
cdnPath string https://fastly.jsdelivr.net/gh/fghrsh/live2d_api/ CDN 路径,可选参数
tools string[] autoload.js 加载的小工具按钮,可选参数

这些配置确实能够解决不要显示小工具的问题,但是自己说话的问题(原来的文本实在是太那个了,都不敢让我孩子看见),以及指定角色和服装,在这里并不能解决。

于是我还是走上了进阶道路——自定义配置。

首先当然是把项目克隆到本地:

1
git clone https://github.com/stevenjoezhang/live2d-widget.git

直接把整个目录复制到source文件夹下面就可以。依赖就不用安装了,毕竟我是要在自己的Hexo博客里运行。

试试引入

1
<script src="https://your.site.com/path/to/live2d-widget/autoload.js"></script>

部署运行没有问题,那么剩下就是真正的自定义阶段了。

自定义配置

要干活首先得安排好要干什么活儿,所以先分析一波它的demo,其中一个是基础例子,不管它,我们来看另外一个 login.html

1
2
3
4
5
6
7
8
live2d-widget
│ live2d.min.js <-- 主文件
│ waifu.css <-- 样式
├─demo
│ login.html <-- 功能实现参考
└─src
index.js <-- 与login.html一起作为实现参考
model.js <-- 模型加载参考

上面的树形图我把不重要的文件都隐藏了,重要的都留下来了。这就是今天的主角们。

感觉废话也不用多说,直接来看我要干什么。

插入画布

调用 insertAdjacentHTML 方法来插入一个固定在左下角的画布。

1
2
3
4
5
6
7
8
9
10
document.body.insertAdjacentHTML("beforeend", `<div id="waifu" style="position:fixed;left:20px; bottom:0;z-index:2;">
<div id="waifu-tips"></div>
<canvas id="live2d" width="250" height="250"></canvas>
<div id="waifu-tool"></div>
</div>`);

// 这里是参考了demo代码,猜想可能是担心bottom 0不生效,又赋值了一遍。因为原来的css里面有个鼠标移上去以后的浮动效果
setTimeout(() => {
document.getElementById("waifu").style.bottom = 0;
}, 0);

构造初始化配置方法

分析Demo我们可以知道,它通过api的方式获得参数,然后传参来创建模型。

那么先来构造一个初始化配置的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
function initConfig(config){
let { apiPath, cdnPath } = config;
let useCDN = false;
if (typeof cdnPath === "string") {
useCDN = true;
if (!cdnPath.endsWith("/")) cdnPath += "/";
} else if (typeof apiPath === "string") {
if (!apiPath.endsWith("/")) apiPath += "/";
} else {
throw "Invalid initWidget argument!";
}
return {useCDN: useCDN, apiPath: apiPath, cdnPath: cdnPath};
}

这里我参考原作者允许了 apicdn 两种获取配置的方式,由传入参数来确定到底用哪种。接下来就调用这个方法初始化我们的配置参数。

1
2
3
4
const config = initConfig({
// apiPath: "https://live2d.fghrsh.net/api/", // 这里是api方式请求,这个api的作者服务器已经用爱发电了很多年,已经说了很多次要废弃了,但是目前还运作着。为了他,也为了保证自己少出问题,我们还是选用cdn的方式。
cdnPath: "https://npm.elemecdn.com/akilar-live2dapi@latest/",
});

构造模型加载方法

因为配置保留了 apicdn 两种方式,所以实现加载的时候,也同时考虑这两种方式。

但是通过分析cdn的文件,我们可以知道,要获取模型参数跟api方式是不一样的。api可以使用url传参的方式直接获取到对应模型,而api也会有自己的容错处理。但cdn就需要我们通过自己的方式来处理了。所以我们还构造了 modelSelection 这个方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
async function loadModel(modelId, modelTexturesId, config) {
localStorage.setItem("modelId", modelId); // 保留了demo 中本地存储配置的思路,随时可以将切换模型工具添加上
if (modelTexturesId === undefined) modelTexturesId = 0;
localStorage.setItem("modelTexturesId", modelTexturesId);
if (config.useCDN) { // cdn load
const response = await fetch(`${config.cdnPath}model_list.json`);
const modelList = await response.json();
const target = modelSelection(modelList.models[modelId], modelTexturesId);
loadlive2d("live2d", `${config.cdnPath}model/${target}/index.json`);
console.log(`Live2D 模型 ${modelId}-${modelTexturesId} 加载完成`);
} else { // api load
loadlive2d("live2d", `${config.apiPath}get/?id=${modelId}-${modelTexturesId}`);
console.log(`Live2D 模型 ${modelId}-${modelTexturesId} 加载完成`);
}
}

function modelSelection(obj, textureId) {
if(Array.isArray(obj)){
if(textureId < obj.length){
return obj[textureId]
}
return obj[Math.floor(Math.random() * obj.length)]
}
}

样式优化

我希望屏幕尺寸太小时不要显示看板娘,但是又不希望pc上改变浏览器尺寸会导致直接不加载,所以用css样式来实现。修改 waifu.css

1
2
3
4
5
@media (max-width: 768px) {
#waifu {
display: none;
}
}

另外,我也不希望鼠标移上去会浮动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#waifu {
bottom: -1000px;
left: 0;
line-height: 0;
margin-bottom: -10px;
position: fixed;
/* transform: translateY(3px); 注释掉 */
transition: transform .3s ease-in-out, bottom 3s ease-in-out;
z-index: 1;
}

#waifu:hover {
/* transform: translateY(0); 注释掉 */
}

最后,记得把尺寸改成跟你的画布同样大小。

1
2
3
4
#live2d {
height: 250px;
width: 250px;
}

实现加载

最后,在页面加载完成后执行加载代码就可以了。

其中的模型ID和材质ID可以通过这个页面去查找,https://github.com/Akilarlxh/live2d_api/blob/master/model_list.json

1
2
3
4
5
6
7
8
9
10
11
12
window.addEventListener("load", () => {
localStorage.removeItem("modelId");
localStorage.removeItem("modelTexturesId");
let state = 0, loading = false,
modelId = localStorage.getItem("modelId"),
modelTexturesId = localStorage.getItem("modelTexturesId");
if (modelId === null) {
modelId = 3;
modelTexturesId = 20;
}
loadModel(modelId, modelTexturesId, config);
});

锵锵,完成。

总结

其实总体来说还是挺简单的,主要是读懂代码,看看原作者的方法都在做什么就行了。

思路 > 方法 > 实现。

收工。

♦ 本文固定连接:https://www.gsgundam.com/2022/2022-12-16-z11-live2d-update-customize-config-with-cdn/

♦ 转载请注明:GSGundam 2022年12月16日发布于 GSGUNDAM砍柴工

♦ 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

♦ 原创不易,如果页面上有适合你的广告,不妨点击一下看看,支持作者。(广告来源:Google Adsense)

♦ 本文总阅读量