跳到主要内容

VoxelViewerController

VoxelViewerController 是 VoxelViewer 的命令入口。一个 Controller 对应一个可替换的预览场景;可以连续导入多个文件,但不应跨多个同时可见的 Viewer 共享。

构造函数​

new VoxelViewerController(options?: VoxelViewerOptions)
参数类型默认值说明
options`VoxelViewerOptionsundefined`新建默认配置

导入方法​

loadText()​

async loadText(text: string, sourceName: string = 'model.json'): Promise<VoxelLoadResult>
参数说明
textPixForge 体素 JSON 文本。UTF-8 编码后的字节数不得超过 options.maxJsonBytes。
sourceName结果和状态文字中展示的名称,不参与解析。

loadBytes()​

async loadBytes(bytes: ArrayBuffer, sourceName: string = 'model'): Promise<VoxelLoadResult>

自动识别 JSON、VFP 1.2、VFP 1.3。JSON 走 maxJsonBytes 限制;URI 以外的 VFP 由调用方负责控制内存来源。

loadUri()​

async loadUri(uri: string, sourceName: string = ''): Promise<VoxelLoadResult>
参数说明
uri由系统文档选择器返回、且当前应用有读取权限的 URI。
sourceName为空时从 URI 最后一段推导文件名。

Reader 最多读取 64 MiB。大于此限制、空文件、权限失效、短读、非法 JSON/VFP 均会拒绝 Promise。

一次完整导入​

async function showFile(controller: VoxelViewerController, uri: string): Promise<void> {
try {
const result = await controller.loadUri(uri);
console.info('loaded ' + result.sourceFormat + ': ' + result.voxelCount);
} catch (error) {
console.error(controller.getLastError());
}
}

状态与结果​

方法返回值说明
isLoading()boolean导入或准备场景期间为 true。
getStatus()string可直接展示的当前状态。
getLastError()string最近一次导入错误;下一次开始加载时清空。
getSourceName()string最近一次成功导入的名称。
canExportTurntableGif()boolean当前预览是否保留了可恢复为离屏 GIF 的 JSON/VFP 体素源;无需进入编辑模式。
getOptions()VoxelViewerOptions当前选项对象。
getRenderTuning()VoxelRenderTuning当前渲染调参对象。

VoxelLoadResult 包含 sourceName、sourceFormat、gridSize、voxelCount、surfaceCount、vfpCacheHit。其中 vfpCacheHit=true 仅说明预览缓存命中,不能证明 VOXO 权威数据已校验。

运行时设置​

controller.setGroundGridVisible(false);
controller.setBackgroundImageOpacity(0.58);
controller.setOptions(options);
controller.setRenderTuning(tuning);

setOptions() 会立即同步地面网格和加载动画时长;背景/加载层将在组件下一次状态更新时采用新配置。setRenderTuning() 会立即重新应用光照、阴影与描边设置。详见 VoxelViewerOptions 和 VoxelRenderTuning。

setBackgroundImageOpacity()​

setBackgroundImageOpacity(opacity: number): void

仅更新 backgroundImageOpacity,并将输入钳制为 0..1。它不会重新加载模型、重建 ArkGraphics Scene 或改变当前相机状态,适合直接绑定 Slider。背景模式不是 BUILTIN_CUSTOM 或未设置 backgroundImage 时,该调用只会保存配置,不会产生可见图片变化。

手势锁定​

手势锁只拦截用户在 Viewer 画布上的输入,不会取消加载、释放场景,也不会阻止本页下面的程序化相机方法。它可用于只读展示、教程步骤、弹层打开期间临时冻结某一类操作,或编辑模式中仅允许选区而禁止相机转动。

setGestureLocks() 与 getGestureLocks()​

setGestureLocks(locks: VoxelGestureLockOptions): void
getGestureLocks(): VoxelGestureLockOptions

setGestureLocks() 替换当前的六项锁定策略;Controller 会复制传入对象,因此调用后再修改原对象不会隐式改变已生效配置。getGestureLocks() 也返回副本。

VoxelGestureLockOptions 字段true 时拦截不会影响
rotation单指拖拽的轨道旋转,以及已启用选择手势桥接后的双指旋转。双指平移/缩放、编辑点击。
twoFingerRotation已启用选择手势桥接后的双指旋转。单指旋转、双指平移/缩放。
pan双指平移分量。同一次双指捏合中的缩放分量。
zoom双指捏合缩放分量。同一次双指操作中的平移分量。
voxelEdit点击选择、滑动选择、放置、替换、删除、取色。相机手势、已有选区状态。
boxSelectionBOX_SELECT 下的屏幕矩形拖拽和实时选区预览。非框选编辑模式;未锁 rotation 时单指可继续旋转。
import { VoxelGestureLockOptions } from 'voxel-kit';

// 作品详情页:禁止改模型,但允许用户观察。
controller.setGestureLocks(new VoxelGestureLockOptions(false, false, false, true, true));

// 教程步骤:禁止旋转,保留双指平移/缩放和编辑。
controller.setGestureLocks(new VoxelGestureLockOptions(true, false, false, false, false));

第六个构造参数是 twoFingerRotation,位于末尾以保持已有五参数调用兼容:

// 保留单指旋转,但锁定 SELECT_BRUSH 桥接中的双指旋转。
controller.setGestureLocks(new VoxelGestureLockOptions(false, false, false, false, false, true));

选择手势桥接​

setSelectionGestureOptions(options: VoxelSelectionGestureOptions): void
getSelectionGestureOptions(): VoxelSelectionGestureOptions
resetSelectionGestureState(): void

它专用于 VoxelEditMode.SELECT_BRUSH。默认 VoxelSelectionGestureOptions 的 enableBrush=false,因此不影响既有页面。无论是否启用桥接,刷选都只会在单指按下点命中可见体素时开始;空白画布起手交给普通相机环绕。宿主需要刷选状态、按笔画设置追加策略,或在 SELECT_BRUSH 内开启双指旋转时再调用它。

字段默认说明
enableBrushfalse开启状态机与配置桥接。
enableTwoFingerCamerafalse允许第二指进入配置的相机路径。
twoFingerPan / twoFingerZoomtrue分别启用双指平移、缩放。
twoFingerRotationfalse启用双指旋转;受 rotation 和 twoFingerRotation 手势锁控制。
brushAppendtrue本笔是否保留旧选区;仅桥接开启时覆盖 Editor 默认值。
onBrushStateChanged空函数接收 VoxelSelectionGestureState,其 phase 为 IDLE、BRUSHING、CAMERA 或 CANCELLED。

getSelectionGestureOptions() 返回副本。setSelectionGestureOptions()、resetSelectionGestureState()、场景替换及手势锁变更会安全结束正在进行的笔画;回调异常会被组件隔离。

一键锁定​

setGestureLocked(locked: boolean): void
setGesturesEnabled(enabled: boolean): void
isGestureLocked(): boolean

setGestureLocked(true) 会同时锁定以上六项;setGesturesEnabled(false) 是同义的反向写法。isGestureLocked() 仅在六项均已锁定时返回 true,因此不适合判断“是否存在任意局部锁定”;局部状态请使用 getGestureLocks()。

相机控制​

Viewer 不暴露内部 ArkGraphics Camera,但 Controller 提供版本化的命令式控制。调用可以发生在导入前、导入过程中或场景显示后:如果相机尚未创建,最后一次命令会在当前模型的初始取景完成后应用。调用不会重新解析 JSON/VFP、重建模型或影响当前缩放距离。

VoxelCameraTransform​

new VoxelCameraTransform(
rotationX = 0, rotationY = 0, rotationZ = 0,
translationX = 0, translationY = 0, translationZ = 0
)
字段单位含义
rotationX弧度轨道俯仰;为保证稳定性会限制在接近 -π/2..π/2 的安全范围。
rotationY弧度水平方位/环绕角。
rotationZ弧度围绕当前视线的屏幕滚转。0 保持默认世界 Y 向上。
translationX/Y/Z场景单位观察焦点的绝对平移;相机同步平移,因而不改变镜头距离和缩放。

设置、查询与重置​

setCameraRotation(x: number, y: number, z: number): void
setCameraTranslation(x: number, y: number, z: number): void
setCameraTransform(transform: VoxelCameraTransform): void
getCameraTransform(): VoxelCameraTransform
resetCamera(): void

setCameraRotation() 只更新旋转,保留当前平移;setCameraTranslation() 只更新平移,保留当前旋转。setCameraTransform() 同时设置两者。非有限数值不会污染已经可用的相机状态。getCameraTransform() 返回 Controller 最近管理或程序化应用的值副本;加载完成前尚无真实相机时返回默认值。resetCamera() 恢复当前模型完成自动取景后捕获的初始半径、X/Y/Z 旋转与平移,而不是回到一个固定世界原点。

:::caution 2.14.3 的手动相机读取边界 为避免连续单指/双指手势在松手后触发 @Observed 状态发布和 ArkUI 生命周期工作,2.14.3 不会在用户手动旋转、平移或缩放结束时把实时 Camera 快照写回 Controller。因此手动操作后,getCameraTransform() 不保证立即与画面姿态一致;程序化 setCamera*()、resetCamera() 和模型初始取景仍会更新可查询值。需要精确保存机位或指定 GIF 俯仰时,请由业务维护程序化相机值,或显式传入导出参数。 :::

import { VoxelCameraTransform } from 'voxel-kit';

// 先给展示页一个确定机位,再允许用户继续拖动。
controller.setCameraTransform(new VoxelCameraTransform(0.28, 0.76, 0.08, 0, 0.5, 0));

// 例如关闭弹层时恢复该模型的自动初始取景。
controller.resetCamera();

直接设置 rotationZ 后,双指平移、点击命中和框选会同步使用滚转后的屏幕坐标;无需在宿主侧补偿坐标。

dispose()​

dispose(): void

取消已排队的延迟描边、完成当前加载动画、释放当前场景引用,并把状态置为“预览器已释放”。释放后若要再次显示模型,仍可调用 loadText、loadBytes 或 loadUri 重建场景。

不要依赖 bindStateListener() 或 getSceneResult():它们服务于 HAR 内部组件协作,不属于稳定公开 API。