跳转到内容

事件

完整事件总表和 detail 类型见 iframe 事件

事件都直接在iframe对象上进行监听。

js
iframe.addEventListener("事件名", (event) => {
  const { detail } = event;
  const { api, sceneInfo } = detail;
  console.log(api, sceneInfo);
});

除了iframe的标准事件load和error,其他的事件对象,都是CustomEvent

需要事件信息时,都从属性detail上获取。

不同事件,detail值类型存在差异,详细看各事件定义。

事件范围

在 iframe 上监听到的主要是流程型事件,也就是内容从初始化、下载、加载素材、开始体验到识别状态变化的一系列阶段通知。

如果你希望监听运行中的对象事件,比如某个模型被点击、某个视频播放结束,则应使用高级API中的 api.on()

触发条件

loaderror 是浏览器或插件层都会触发的基础事件。

亦可参考:iframe#error_and_load_event_behavior

其余事件是否可用,与账号权限和域名授权有关。

详细条件

账号类型是否域名授权能否触发
基础版、个人版未授权(不支持购买授权)不触发
所有用户未授权,但宿主页面使用localhost或局域网IP访问触发
高级版、企业版未购买授权不触发
高级版、企业版已授权触发

load

浏览器标准事件,表示 iframe 页面本身已加载完成。

它只说明 Kivicube 页面代码已经进入运行,不代表场景素材已经下载完毕。

error

插件内发生错误,皆会触发此事件。

当用户拒绝了摄像头权限,或者陀螺仪权限时,也会触发。

判断方式如下所示:

js
iframe.addEventListener("error", (e) => {
    if(e.detail?.isUserDeniedCamera) {
        console.log('用户拒绝了摄像头权限');
    }

    if (e.detail?.isUserDeniedGyroscope) {
        console.log('用户拒绝了陀螺仪权限');
    }
});

detail值类型

ts
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值类型

ts
interface ReadyDetail {
  sceneInfo: SceneInfo | CollectionInfo;
  api: SceneApi | CollectionApi; // 此值具体类型,参考高级API说明。
}

interface ReadyCustomEvent {
  detail: ReadyDetail;
}

类型定义:

SceneInfo

CollectionInfo

js
iframe.addEventListener("ready", (event) => {
  const { detail } = event;
  const { api, sceneInfo, collectionInfo } = detail;
  console.log(api, sceneInfo, collectionInfo);
});

downloadAssetStart

开始下载场景素材时触发。

downloadAssetProgress

下载进度变化时触发,detail 范围为 0.0 - 1.0

js
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

合辑内部准备销毁当前场景、切换到下一个场景时触发。

ts
interface SceneDestroyDetail {
  sceneId: string; // 被销毁场景的id
}

事件时序参考

场景

通常为:

text
load
-> ready
-> downloadAssetStart
-> downloadAssetProgress
-> downloadAssetEnd
-> loadSceneStart
-> loadSceneEnd
-> sceneStart

合辑

通常为:

text
load
-> ready
-> sceneReady
-> downloadAssetStart
-> downloadAssetProgress
-> downloadAssetEnd
-> loadSceneStart
-> loadSceneEnd
-> sceneStart

推荐监听组合

大部分项目至少建议监听下面几个事件:

js
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);