事件
完整事件总表和 detail 类型见 iframe 事件。
事件都直接在iframe对象上进行监听。
iframe.addEventListener("事件名", (event) => {
const { detail } = event;
const { api, sceneInfo } = detail;
console.log(api, sceneInfo);
});除了iframe的标准事件load和error,其他的事件对象,都是CustomEvent
需要事件信息时,都从属性detail上获取。
不同事件,detail值类型存在差异,详细看各事件定义。
事件范围
在 iframe 上监听到的主要是流程型事件,也就是内容从初始化、下载、加载素材、开始体验到识别状态变化的一系列阶段通知。
如果你希望监听运行中的对象事件,比如某个模型被点击、某个视频播放结束,则应使用高级API中的 api.on()。
触发条件
load 和 error 是浏览器或插件层都会触发的基础事件。
亦可参考:iframe#error_and_load_event_behavior
其余事件是否可用,与账号权限和域名授权有关。
详细条件
| 账号类型 | 是否域名授权 | 能否触发 |
|---|---|---|
| 基础版、个人版 | 未授权(不支持购买授权) | 不触发 |
| 所有用户 | 未授权,但宿主页面使用localhost或局域网IP访问 | 触发 |
| 高级版、企业版 | 未购买授权 | 不触发 |
| 高级版、企业版 | 已授权 | 触发 |
load
浏览器标准事件,表示 iframe 页面本身已加载完成。
它只说明 Kivicube 页面代码已经进入运行,不代表场景素材已经下载完毕。
error
插件内发生错误,皆会触发此事件。
当用户拒绝了摄像头权限,或者陀螺仪权限时,也会触发。
判断方式如下所示:
iframe.addEventListener("error", (e) => {
if(e.detail?.isUserDeniedCamera) {
console.log('用户拒绝了摄像头权限');
}
if (e.detail?.isUserDeniedGyroscope) {
console.log('用户拒绝了陀螺仪权限');
}
});detail值类型
interface ErrorType {
message: string;
isCameraNotFound?: boolean; // 未找到摄像头,可能硬件损坏,或者设备无摄像头
isUserDeniedCamera?: boolean; // 用户手动拒绝摄像头权限
isUserDeniedGyroscope?: boolean; // 用户手动拒绝陀螺仪权限(iOS)
}
interface ResponseServerError {
message: string;
code: number;
}
interface ErrorCustomEvent {
detail: string | ErrorType | ResponseServerError;
}常见情况包括:
- 场景或合辑 ID 不存在
- 摄像头权限被拒绝
- iOS上动作与方向权限被拒绝
- 资源下载失败
incompatibility
场景或合辑在前置兼容性检测失败时会额外触发 incompatibility。
它常见于:
- 当前浏览器不支持摄像头能力
- 当前 App 内 WebView 不适合体验 WebAR
- 某些模式在当前端能力下不可用
detail 的结构并不完全固定,但通常会包含如 unsupportCamera 之类的标记对象,因此推荐把它当作“展示兼容性兜底 UI”的触发信号。
ready
已获取到场景数据,并开始去打开场景时触发。
场景页中,event.detail.sceneInfo 包含场景基础信息,event.detail.api 为场景高级 API 对象。
合辑页中,event.detail.collectionInfo 包含合辑基础信息。event.detail.api 为合辑高级 API 对象。
detail值类型
interface ReadyDetail {
sceneInfo: SceneInfo | CollectionInfo;
api: SceneApi | CollectionApi; // 此值具体类型,参考高级API说明。
}
interface ReadyCustomEvent {
detail: ReadyDetail;
}类型定义:
iframe.addEventListener("ready", (event) => {
const { detail } = event;
const { api, sceneInfo, collectionInfo } = detail;
console.log(api, sceneInfo, collectionInfo);
});downloadAssetStart
开始下载场景素材时触发。
downloadAssetProgress
下载进度变化时触发,detail 范围为 0.0 - 1.0。
iframe.addEventListener('downloadAssetProgress', (event) => {
console.log(`下载进度:${(event.detail * 100).toFixed(0)}%`);
});downloadAssetEnd
素材下载完成时触发。
如果没有隐藏“立即体验”按钮,后续通常还会等待用户点击按钮,之后才进入 loadSceneStart。
如果你准备通过高级 API 自定义“立即体验”按钮的位置或覆盖宿主层按钮,这也是调用 getStartButtonRect() / setStartButtonRect() 的常见时机。
loadSceneStart
开始把素材真正加载进场景时触发。
loadSceneEnd
场景加载结束时触发。
在推荐中,这里是注册对象事件、读取对象列表、做对象二次处理的一个稳妥时机。
sceneStart
场景已经开始体验时触发。
对于非识别类场景,它通常很快触发;对于图像追踪或云识别场景,它代表进入可以实际体验的阶段,但识别扫描状态可能仍会继续变化。
tracked
识别扫描类场景中,成功追踪到识别图时触发。
常见用途:
- 隐藏宿主层的扫描引导
- 展示自定义拍照按钮
- 做埋点统计
lostTrack
识别类场景中,丢失追踪识别图时触发。
openUrl
场景内部触发“打开网页”动作时触发,detail 一般为目标 URL。
如果你设置了属性 disableOpenUrl,此事件仍会触发,可以在这里自行决定是否:
- 弹出跳转二次确认
- 走宿主自己的跳转系统
- 记录埋点后再跳转
仅合辑支持的事件
sceneReady
合辑切换到某个具体场景并拿到该场景数据时触发。
detail.sceneInfo 的结构与场景 ready 中的 sceneInfo 一致。
detail.api 与场景 ready 中的 api 一致。
sceneDestroy
合辑内部准备销毁当前场景、切换到下一个场景时触发。
interface SceneDestroyDetail {
sceneId: string; // 被销毁场景的id
}事件时序参考
场景
通常为:
load
-> ready
-> downloadAssetStart
-> downloadAssetProgress
-> downloadAssetEnd
-> loadSceneStart
-> loadSceneEnd
-> sceneStart合辑
通常为:
load
-> ready
-> sceneReady
-> downloadAssetStart
-> downloadAssetProgress
-> downloadAssetEnd
-> loadSceneStart
-> loadSceneEnd
-> sceneStart推荐监听组合
大部分项目至少建议监听下面几个事件:
iframe.addEventListener('ready', onReady);
iframe.addEventListener('downloadAssetProgress', onProgress);
iframe.addEventListener('sceneStart', onSceneStart);
iframe.addEventListener('tracked', onTracked);
iframe.addEventListener('lostTrack', onLostTrack);
iframe.addEventListener('openUrl', onOpenUrl);
iframe.addEventListener('error', onError);
iframe.addEventListener('incompatibility', onIncompatibility);