8

给网页添加一只 Live2D 看板娘

 2 years ago
source link: https://nekoquq.github.io/posts/0008.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
给网页添加一只 Live2D 看板娘
2021-07-24 / 猫村 あおい 🍭

Live2D 看板娘是很多 二次元 博客的标配。这只猫猫手上刚好有 なちょ猫 的模型,当然要给网站加上可爱的猫娘!

首先想到的是大家都在用的插件:fghrsh/live2d_demo 或者 stevenjoezhang/live2d-widget

1.webp
stevenjoezhang/live2d-widget 的效果

但是这两个插件用的 Live2D 是旧版本的,不能加载 moc3 模型。

如何给博客添加一只猫娘

看板娘的结构(?

以 stevenjoezhang/live2d-widget 为例,这玩意本质是 waifu-tips.js 创建 waifu div,div 里面有纸片人本体 canvas 和对话气泡等小部件,waifu-tips.js 负责加载 Live2D 模型和控制小部件。

waifu-tips.js 调用 live2d.min.js 里面的 loadModel 函数加载模型,live2d.min.js 是 Live2D 的控制器,而 Live2D 的核心是个闭源的东西。

这个 live2d.min.js 对应的 Live2D 版本比较低。其实这个项目是个很老的坑,可以看见 Github 上有很多版本,但是好像很少人升级 Live2D Core。

现在要升级的话,就要把整个 live2d.min.js 换掉。

然后看到这样一篇 笔记:live2d4.0 sdk 博客园网页动画

这篇作者给出了一个百度网盘成品链接,当然还有修改过程。 那么就照着做了。

下载 Live2D Demo 并运行

从这里开始喵

3.sdk
官方sdk api:https://docs.live2d.com/cubism-sdk-tutorials/sample-build-web/

3.1运行实例
需要环境:node.js TypeScript Webpack (TypeScript和Webpack安装慢可以使用淘宝镜像)
编辑器打开sdk项目,具体的目录是什么内容可以看项目根目录下的 README.md 文件(windows用户可以使用Typora软件打开.md文件)

打开控制台跳转到Demo文件夹下输入 npm install 命令(安装了淘宝镜像的可以使用cnpm install命令安装的快一些)
install命令会根据package.json 文件中的配置下载安装需要的插件
这里已经安装好了,安装好后在Demo文件夹下回多出一个 node_modules 文件夹
运行 npm run build命令

运行完成后会在Demo文件夹下生成一个 dist 文件夹,该文件夹下有一个bundle.js,这个就是集合打包好的js文件,在index.html文件中有引用
运行 npm run serve命令,启动服务器

4.在浏览器中输入 http://localhost:5000/Samples/TypeScript/Demo/ 就能看到

可以看到,浏览器里面已经有了可爱的 Live2D 纸片人了!我们只要把她放进 waifu div 里面那个 canvas 就好了!

修改 Live2D Demo

3.2源码
想把一些配置放到html中,比如画布(canvas)的大小位置,模型保存的路径等等信息
否则每次需要改变模型的时候都要改代码,重新编译,麻烦
lappdefine.ts //定义基本的参数
lappdelegate.ts //初始化,释放资源,事件绑定
lapplive2dmanager.ts //模型的管理类,进行模型生成和废弃、事件的处理、模型切换。
lappmodel.ts //模型类,定义模型的基本属性
lappal.ts //读取文件,抽象文件数据(算是工具类)
lappsprite.ts //动画精灵类,(学python时知道了精灵类和精灵组)
lapptexturemanager.ts//纹理管理类,进行图像读取和管理的类
lappview.ts //视图类,生成模型的图像被lapplive2dmanager管理
main.ts //主程序启动程序
touchmanager.ts //事件的管理类(比如移动鼠标,点击鼠标,触摸屏触碰等)

这里只说重要修改点,如果想理解部分原理的,可以看上面那篇文章,里面有中文注释。当然看 Demo 里面的官方日语注释也可以。

主函数 (main.ts)

// 浏览器装入后的处理(打开页面)
window.onload = (): void => {
// create the application instance
if (LAppDelegate.getInstance().initialize() == false) {
return;
}
LAppDelegate.getInstance().run();
};

这个 main.ts 覆盖了 window.onload 使得网页载入完成就启动 LAppDelegate,由于我们要与 waifu-tips.js 整合,所以改成导出这个函数,以后再调用。

export const win: any = window

// js 里面调用 l2d_initInstance() 就开始运行 Live2D
win.l2d_initInstance = () => {
if (LAppDelegate.getInstance().initialize() == false) {
return;
}
LAppDelegate.getInstance().run();
};

LAppDelegate.getInstance().initialize()(lappdelegate.ts)

1.使用现有的 canvas

// キャンバスの作成
// canvas = document.createElement('canvas');
// if (LAppDefine.CanvasSize === 'auto') {
// this._resizeCanvas();
// } else {
// canvas.width = LAppDefine.CanvasSize.width;
// canvas.height = LAppDefine.CanvasSize.height;
// }

canvas = <HTMLCanvasElement>document.getElementById("live2d"); // index.html中的id=live2d的画布
canvas.width = canvas.width;
canvas.height = canvas.height;
canvas.toDataURL("image/png");

2.不要再添加 canvas

// キャンバスを DOM に追加
// document.body.appendChild(canvas);

onResize()

public onResize(): void {
//this._resizeCanvas(); 这个会变形
this._view.initialize();
this._view.initializeSprite();
}

LAppDelegate.getInstance().run()

// 清除彩色缓冲区和深度缓冲区  (加上这一句会导致有些浏览器背景变成黑色,而不是透明)
// gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

部分设置 (lappdefine.ts)

这里有一些参数,我们要导出到 js 供运行时调整。

export const win: any = window

win.l2d_setConfig = function (resourcesPath: string, backImageName: string, modelDir: string[]) {
ResourcesPath = resourcesPath;
BackImageName = backImageName;
ModelDir = modelDir;
ModelDirSize = modelDir.length;
}

更换模型 (main.ts)

win.l2d_changeModel = (no) => {
LAppLive2DManager.getInstance().changeScene(no)
}

修改好之后 html 引入 bundle.js 做测试,大概这样:

<!-- Live2DCubismCore script -->
<script src="https://cdn.jsdelivr.net/gh/wangstong/mycdn/live2d/js/live2dcubismcore.js"></script>
<!-- Build script -->
<script src="bundle.js"></script>

<!-- 这里可以定义画布的大小位置 -->
<canvas id="live2d" width="500" height="500" class="live2d" style="position: fixed; opacity: 1; right: 0px; bottom: -20px; z-index: 99999; pointer-events: none;"></canvas>

<script type="text/javascript">
var resourcesPath = 'https://cdn.jsdelivr.net/gh/wangstong/mycdn/live2d/model/'; // 指定资源文件(模型)保存的路径
var backImageName = ''; // 指定背景图片
var modelDir = ['Hiyori']; // 指定需要加载的模型
l2d_setConfig(resourcesPath, backImageName, models); // 模型设置
l2d_initInstance(); // 开始显示模型
</script>

然后纸片人就显示在 canvas 里面了!

整合到 waifu-tips.js

这个 waifu-tips.js 可以看出来被 114514 人改过喵,过于混乱所以只说加载纸片人的重点:

function displayLive2dModel(cdnBase, models, modelId) {
const resourcesPath = `${cdnBase}/model3/`; // 指定资源文件(模型)保存的路径
const backImageName = ''; // 指定背景图片
l2d_setConfig(resourcesPath, backImageName, models); // 初始化模型
if (!l2d_ok) {
l2d_ok = true
l2d_initInstance()
}
l2d_changeModel(modelId)
}
    async function loadModel(modelId, modelTexturesId, message) {
localStorage.setItem("modelId", modelId);
localStorage.setItem("modelTexturesId", modelTexturesId);
displayLive2dModel(cdnBase, modelList.models, modelId) // 重点
}
async function loadOtherModel() {
let modelId = localStorage.getItem("modelId");
const index = (++modelId >= modelList.models.length) ? 0 : modelId;
loadModel(index, 0, modelList.messages[index]);
}

注意:这里没有实现同一个人物的换装(modelTexturesId)

<canvas id="live2d" width="500" height="500" class="live2d"></canvas>

这里的 width 和 height 为渲染尺寸,修改 css 里面 canvas 大小时需要一起修改避免出现模糊。

到这里主要工作就完成了。

加载 js 时记得加载 live2d core 和 bundle.js

// 加载 waifu.css live2d.min.js waifu-tips.js
if (screen.width >= 768) {
Promise.all([
loadExternalResource(live2d_path + "waifu.css", "css"),
loadExternalResource(live2d_path + "live2dcubismcore.js", "js"),
loadExternalResource(live2d_path + "bundle.js", "js")
loadExternalResource(live2d_path + "waifu-tips.js", "js")
]).then(() => {
initWidget({
waifuPath: live2d_path + "waifu-tips.json",
//apiPath: "https://live2d.fghrsh.net/api/",
cdnPath: "https://cdn.jsdelivr.net/gh/fghrsh/live2d_api/"
});
});
}

live2dcubismcore.js + bundle.js 一共 350kB+ 而旧版的 live2d.min.js 只有 100 多 kB

  1. 由于写的太烂,本博客的看板娘并不会完整开源。
  2. nacho 猫猫可爱!!!
sticker005.webp

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 许可协议。
本文链接:
https://nekoquq.github.io/posts/0008.html


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK