模型事件
586 words
3 min
l2d 提供了一套完整的事件系统,覆盖模型生命周期的每个阶段以及用户交互。所有事件都通过 l2d.on(event, listener) 注册监听。
生命周期事件
以下是模型从加载到销毁的完整流程:
参考: 事件 以查阅所有可监听的模型事件
loadstart
ts
l2d.on("loadstart", (total: number) => {
console.log(`开始加载,共 ${total} 个文件`);
});loadprogress
ts
l2d.on("loadprogress", (loaded: number, total: number, file: string) => {
const percent = Math.round((loaded / total) * 100);
console.log(`${percent}% — ${file}`);
});loaded
loaded 是最常用的事件,表示模型已完全就绪,可以安全地调用 getMotions()、getExpressions() 等方法:
ts
l2d.on("loaded", () => {
console.log("模型已就绪");
const motions = l2d.getMotions();
const expressions = l2d.getExpressions();
});destroy
ts
l2d.on("destroy", () => {
console.log("模型已销毁,WebGL 资源已释放");
});交互事件
tap
用户点击 canvas 且命中某个 Hit Area 时触发。Hit Area 是模型作者在 model3.json 中定义的可交互区域(如头部、身体等):
ts
l2d.on("tap", (areaName: string) => {
console.log(`点击了: ${areaName}`); // 例如 "Head"、"Body"
});根据点击区域触发不同动作是最常见的交互模式:
ts
l2d.on("tap", (areaName) => {
switch (areaName) {
case "Body":
l2d.playMotion("TapBody", undefined, 3);
break;
case "Head":
l2d.playMotion("TapHead", undefined, 3);
break;
}
});
tap事件只在点击命中 Hit Area 时触发,点击模型轮廓之外或未定义 Hit Area 的区域不会触发。如需可视化查看 Hit Area 的范围,参见进阶篇可视化点击区域。
动作事件
motionstart
ts
l2d.on(
"motionstart",
(group: string, index: number, duration: number, file: string | null) => {
console.log(
`动作开始: ${group}[${index}],时长: ${duration > 0 ? duration + "s" : "未知"}`,
);
},
);motionend
ts
l2d.on("motionend", (group: string, index: number, file: string | null) => {
console.log(`动作结束: ${group}[${index}]`);
});表情事件
expressionchange
ts
l2d.on("expressionchange", (id: string) => {
console.log(`表情切换: ${id}`);
});表情与动作不同,没有"结束"的概念——表情一旦设置就会永久保持,直到下次调用 setExpression() 为止。因此只有 expressionchange 这一个事件,在调用 setExpression() 后立即触发。
注意事项
监听器注册时机:所有事件监听器应在调用 l2d.load() 之前完成注册。load() 是异步操作,如果在 load() 之后注册 loaded 监听器,可能已经错过了事件。
ts
// ✅ 正确:提前注册监听器,再调用 load()
l2d.on('loaded', () => { ... })
l2d.load({ path: '...' })
// ❌ 错误:load() 已经完成
await l2d.load({ path: '...' })
l2d.on('loaded', () => { ... }) // 可能永远不会触发