@chnak/l2d-widget
v0.1.2
Published
<p align="center"> <img width="240" src="https://hacxy-1259720482.cos.ap-hongkong.myqcloud.com/images/logo.svg"/> </p> <h1 align="center">l2d-widget</h1> <h4 align="center">仅一个函数调用,把 Live2D 模型放进任何网页</h4>
Maintainers
Readme
[!IMPORTANT] 本项目是基于 l2d 库对 oh-my-live2d 的完全重构版本,原
oh-my-live2d已更名为 l2d-widget。如果你正在从oh-my-live2d迁移,请查阅文档站了解更新后的 API。
特性
- 单次调用集成 —
createWidget()一个函数完成 canvas 创建、WebGL 上下文初始化、模型加载与交互绑定 - Cubism 2 & 6 运行时 — 基于 l2d,自动识别模型版本并加载对应 Cubism 运行时
- 嘴型参数驱动 — 逐字打字动画实时驱动模型口型参数(
PARAM_MOUTH_OPEN_Y),支持配置开合值域 - 完整生命周期管控 —
switchModel()退场过渡 → WebGL 销毁 → 重建 → 入场过渡,原子化异步操作;destroy()确保资源释放 - AI 对话界面 — 支持显示用户消息、思考状态、工具调用状态,气泡悬停时保持显示
- 可拖拽定位 — 挂件可自由拖拽到任意位置
- ~500 行,零运行时依赖 — 纯 DOM + CSS Animation,无框架。同时输出 ESM 和 IIFE,支持 tree-shaking
安装
npm install @chnak/l2d-widget或通过 CDN 引入:
<script src="https://unpkg.com/@chnak/l2d-widget/dist/index.min.js"></script>快速开始
import { createWidget } from '@chnak/l2d-widget';
const widget = createWidget({
model: {
path: 'https://model.hacxy.cn/cat-black/model.json',
},
});跑完之后页面左下角会出现一个 Live2D 角色,带悬浮菜单和提示气泡,可以交互。
示例
多模型切换
createWidget({
model: [
{ path: '/models/cat-black/model.json' },
{ path: '/models/cat-white/model.json' },
],
});传入数组时,菜单会自动出现切换按钮。
打字动画与嘴型同步
createWidget({
model: {
path: '/models/cat-black/model.json',
tips: {
typing: {
param: 'PARAM_MOUTH_OPEN_Y',
speed: 200,
},
welcomeMessage: ['你好!', '很高兴见到你!'],
messages: ['休息一下吧~', '记得多喝水!'],
duration: 4000,
interval: 6000,
},
},
});提示气泡会逐字显示文字,同时驱动模型的嘴型参数做开合动画。
AI 对话界面
// 发送用户消息
widget.sendMessage('你好');
// 显示思考状态
widget.showThinking('正在思考...');
// 收到 AI 回复后隐藏思考
widget.hideThinking();
// 显示工具调用
widget.showToolCall('正在搜索...', 'loading');
// 工具完成后更新状态
widget.showToolCall('搜索完成', 'success');
setTimeout(() => widget.hideToolCall(), 2000);内置输入框
启用内置输入框,自动绑定回车和点击发送:
createWidget({
model: { path: '/models/cat-black/model.json' },
onInput: true, // 或 '发送' 自定义按钮文字
onUserMessage: msg => {
// 这里是处理 AI 回复的地方
},
});输入框自动显示在模型上方,位置跟随 position 配置。
自定义菜单
createWidget({
model: { path: '/models/cat-black/model.json' },
menus: {
extraItems: [
{
icon: 'mdi:information',
label: '关于',
onClick: widget => {
widget.showUserMessage('l2d-widget v1.0.0');
},
},
],
},
});可拖拽定位
createWidget({
model: { path: '/models/cat-black/model.json' },
draggable: true, // 默认 true,设为 false 禁用拖拽
});自定义样式
createWidget({
model: { path: '/models/cat-black/model.json' },
primaryColor: 'rgba(255,182,193,0.9)', // 自定义主题色
tips: {
style: {
fontSize: '14px',
backgroundColor: 'rgba(0,0,0,0.8)',
},
},
});Widget 实例
createWidget() 返回一个 Widget 对象:
| 方法 / 属性 | 说明 |
| ---------------------------- | ---------------------------------------------- |
| l2d | 底层 l2d 实例,用于高级控制 |
| switchModel(index) | 异步切换到指定索引的模型 |
| sleep() | 隐藏模型并显示休眠状态栏,点击可唤醒 |
| destroy() | 销毁挂件,释放 WebGL 资源并移除 DOM |
| sendMessage(msg) | 发送用户消息(支持排队,悬停不消失) |
| showUserMessage(msg) | 显示用户消息气泡 |
| clearMessages() | 清空消息队列 |
| showThinking(msg?) | 显示思考状态(可带提示文字) |
| hideThinking() | 隐藏思考状态 |
| showToolCall(msg, status?) | 显示工具调用状态(info/loading/success/error) |
| hideToolCall() | 隐藏工具调用状态 |
完整配置项见文档站。
开发
| 命令 | 说明 |
| ------------ | ---------------------------------- |
| pnpm dev | 监听构建(含 sourcemap) |
| pnpm demo | 启动 demo 服务器(localhost:3000) |
| pnpm build | 生产构建 |
| pnpm lint | 代码检查 |
许可证
English documentation: README.md
