3D内容放置屏幕
相关参考:
把 3D 内容“放到屏幕上”是可以实现的,但更准确地说,这不是单独的一条专用 API,而是通过把对象挂到相机下面来实现。
核心思路如下:
js
const camera = await api.getDefaultCamera();
await api.addChild(camera, obj);这样对象会跟随相机一起移动和旋转,视觉上就会更接近“固定在屏幕前方”。
更推荐的方案:宿主层叠加 UI
如果你的目标是典型 HUD 或固定 UI,仍然更推荐:
- 宿主页面自己做一层 HTML/CSS UI
- Kivicube iframe 只负责 3D/AR 内容
这种方式更适合:
- 标题
- 按钮
- 说明文字
- 引导箭头
- 响应式布局
原因也很直接:
- 更容易做多端适配
- 更容易和宿主页面样式统一
- 更容易点击、埋点、做动画
- 不需要反复调 3D 坐标
什么时候适合用 3D 对象贴屏
更适合下面这类内容:
- 希望它仍然是一个 3D 对象
- 需要参与场景内的材质、光照或透明效果
- 想做“漂浮在镜头前方”的 3D 装饰
- 想让它继续复用已有对象动画或模型资源
基本实现方式
1. 获取相机和目标对象
js
const camera = await api.getDefaultCamera();
const obj = await api.getObject('screen-object');如果对象是你运行时创建的,也可以直接使用创建返回的句柄:
js
const obj = await api.createImage('/assets/tag.png');2. 挂到相机下面
js
await api.addChild(camera, obj);3. 调整对象在相机坐标系下的位置
js
await api.setPosition(obj, 0, 0, -2);
await api.setScale(obj, 0.5, 0.5, 0.5);这里最关键的是 z:
z一般要放在负方向,表示放到镜头前方- 数值越接近
0,看起来越贴近屏幕 - 数值越小,看起来越远
x、y 则决定它在屏幕中的左右和上下位置。
例如:
js
// 居中偏下
await api.setPosition(obj, 0, -0.6, -2);
// 左上角附近
await api.setPosition(obj, -1.2, 0.8, -2);4. 修改渲染状态
js
// 使物体始终最上层显示,取消渲染时的深度测试,以及对深度缓冲区的影响
const recursive = true; // 是否同时设置所有子节点。默认为false
await api.setGLState(obj, "depthTest", false, recursive);
await api.setGLState(obj, "depthWrite", false, recursive);一个完整示例
js
iframe.addEventListener('ready', async (event) => {
const { api } = event.detail;
const camera = await api.getDefaultCamera();
const image = await api.createImage('/assets/floating-badge.png');
await api.addChild(camera, image);
await api.setPosition(image, 1.1, -0.8, -2);
await api.setScale(image, 0.35, 0.35, 0.35);
const recursive = true;
await api.setGLState(obj, "depthTest", false, recursive);
await api.setGLState(obj, "depthWrite", false, recursive);
});取消贴屏
如果后面不想继续挂在相机下,可以移除父子关系,再重新挂回其他对象:
js
await api.removeChild(camera, obj);如果只是想隐藏:
js
await api.setObjectVisible(obj, false);适配建议
虽然这种方案可以实现“贴屏”,但它仍然是 3D 坐标,不是 CSS 像素坐标。因此:
- 不同屏幕比例下,位置可能需要微调
- 不同 FOV 下,视觉位置也会变化
- 过于靠近镜头时,容易显得过大或裁切异常
更稳妥的方式是:
- 固定一套基础坐标
- 在关键机型上做少量微调
- 把真正的交互按钮仍放在宿主层 HTML 中
什么时候不建议用这种方式
- 需要精确对齐宿主页面按钮
- 需要复杂响应式布局
- 需要大量文字内容
- 需要稳定的点击热区
- 需要和页面滚动、弹层、表单联动
这种情况下,HTML/CSS 会比 3D 方案更适合。