3D对象
相关参考:
在 Web 高级 API 里,绝大多数能力都是围绕“对象句柄”展开的。
获取对象
最常见的入口是按名称获取:
js
const obj = await api.getObject('rabbit');如果你已经知道场景内对象名称,这是最直接的方式。
也可以一次取回所有对象:
js
const objects = await api.getAllObject();命名建议
如果你计划在宿主页面里频繁通过 API 操作对象,建议在场景编辑中就把对象名称命名清晰。
句柄不是原生 3D 对象
getObject() 返回的不是可直接操作的 Object3D,而是一个跨 iframe 通信的对象句柄。
因此下面这种写法不成立:
js
const obj = await api.getObject('rabbit');
obj.position.x = 1; // 错误正确方式:
js
const obj = await api.getObject('rabbit');
await api.setPosition(obj, 1, 0, 0);基础属性
名称
js
const name = await api.getObjectName(obj);
await api.setObjectName(obj, 'rabbit-main');显隐
js
const visible = await api.getObjectVisible(obj);
await api.setObjectVisible(obj, !visible);渲染顺序
js
// 查看当前渲染顺序
const renderOrder = await api.getRenderOrder(obj);
// 设置当前渲染顺序
await api.setRenderOrder(obj, 10);当你需要让某个对象更稳定地盖在其他对象前面时,这个属性会很有用。
点击禁用
js
// 查询是否禁用点击
const isDisableClick = await api.getDisableClick(obj);
// 设置为禁止点击
await api.setDisableClick(obj, true);这会阻止对象被点击中。
变换属性
位置
js
const [x, y, z] = await api.getPosition(obj);
await api.setPosition(obj, x, y + 0.2, z);旋转
js
const [x, y, z, order] = await api.getRotation(obj);
// 注意:值为弧度,不是角度
await api.setRotation(obj, 0, Math.PI / 2, 0, 'YXZ');四元数
js
const [x, y, z, w] = await api.getQuaternion(obj);
await api.setQuaternion(obj, 0, 0, 0, 1);缩放
js
const [x, y, z] = await api.getScale(obj);
await api.setScale(obj, 1.2, 1.2, 1.2);面向某点
js
await api.lookAt(obj, 0, 0, 0);获取尺寸
js
const [width, height, depth] = await api.getSize(obj);尺寸来自运行时包围盒计算,更适合做布局判断、点击区域估算或动态缩放。
遍历子对象
js
const children = await api.getChildren(obj);
const mesh = await api.getChildByProperty(obj, 'name', 'rabbit-head');这一组 API 对 glTF 模型尤其有用,因为很多模型的材质、事件等需要落到内部子节点上。
对象事件
你可以监听对象级事件,当前支持:
click- 被点击时触发【支持事件冒泡,因为异步因素,暂不支持阻止冒泡】
支持对象类型:所有3D类型对象。
js
const obj = await api.getObject('rabbit');
function onClick(event) {
const { type, name, object, target } = event;
// type - click
// name - 被点击到的子级3d对象名称,或是自身。
// object - 被点击到的子级3d对象句柄,或是自身。
// target - 当前监听点击事件的对象。click事件会沿父级方向一直冒泡,直到根场景。
}
await api.on('click', onClick, obj);play- 音频/视频/动画/动图等播放时触发
支持对象类型:视频、模型、动图、音频。
js
const obj = await api.getObject('rabbit');
function onPlay(event) {
// 不同的对象类型,和不同的media play类型,支持的info不一致,详细可看不同对象类型的事件说明。
const { type, target, ...info } = event;
}
await api.on('play', onPlay, obj);pause- 音频/视频/动画/动图等暂停时触发
支持对象类型:视频、模型、动图、音频。
js
const obj = await api.getObject('rabbit');
function onPause(event) {
// 不同的对象类型,和不同的media play类型,支持的info不一致,详细可看不同对象类型的事件说明。
const { type, target, ...info } = event;
}
await api.on('pause', onPause, obj);ended- 音频/视频/动画/动图等自然播放完毕时触发
支持对象类型:视频、模型、动图、音频。
js
const obj = await api.getObject('rabbit');
function onEnded(event) {
// 不同的对象类型,和不同的media play类型,支持的info不一致,详细可看不同对象类型的事件说明。
const { type, target, ...info } = event;
}
await api.on('ended', onEnded, obj);replay- 视频/动画/动图等重新播放时触发
支持对象类型:视频、模型、动图、音频。
js
const obj = await api.getObject('rabbit');
function onReplay(event) {
// 不同的对象类型,和不同的media play类型,支持的info不一致,详细可看不同对象类型的事件说明。
const { type, target, ...info } = event;
}
await api.on('replay', onReplay, obj);- 以及某些对象的特殊事件,详细查看不同对象类型的事件说明
推荐模式
在实际项目里,比较稳妥的做法是:
- 等待
loadSceneEnd或sceneStart - 通过
getObject()或getAllObject()拿到对象句柄 - 把这些句柄缓存在宿主层状态里
- 后续统一通过 API 改变对象状态