HarmonyOS 7 / API 26 3DGS 多设备预览适配:折叠屏、平板和窗口态下视口怎么稳住
HarmonyOS 7 / API 26 3DGS 多设备预览适配:折叠屏、平板和窗口态下视口怎么稳住

3D 预览到了大屏不是简单放大
3DGS 模型预览在手机竖屏里能跑,不代表放到折叠屏、平板、鸿蒙电脑窗口态里也能跑得舒服。二维列表页面放大以后最多是空白多一点,3D 页面放大以后会出现更明显的问题:模型被裁切、手势冲突、相机距离不合适、右侧属性面板遮住主体、窗口缩小时状态没有恢复。
这篇专门看 3DGS 预览在多设备形态下的适配。它不是普通响应式布局文章,因为 3D 页面除了 ArkUI 布局,还要同时处理 3D 视口、相机参数和手势区域。
先分清三个尺寸
很多问题来自一个误区:只拿页面宽度判断布局。3D 预览页至少要看三个尺寸:
| 尺寸 | 含义 | 常见错误 |
| Window Size | 当前应用窗口大小 | 只按屏幕大小,不按窗口变化 |
| Preview Viewport | 真正承载 3D 场景的区域 | 属性面板出现后仍按整屏算相机 |
| Model Bounds | 模型自己的空间范围 | 相机距离固定,模型大了就被裁切 |
3DGS 页面要稳,不能只写“宽度大于 840 就双栏”。双栏以后,3D 视口变窄了,相机也要跟着重新算。
案例一:平板双栏后模型被右侧面板挡住
第一个案例是平板双栏。左边是 3D 预览,右边是模型信息和操作。页面看起来很合理,但如果相机仍按整屏宽度算,模型主体就可能偏到右侧,被面板遮住。
复现步骤
- 手机竖屏打开 3DGS 预览,模型居中;
- 切到平板或展开折叠屏;
- 页面改成左预览、右信息面板;
- 如果 3D 相机仍按窗口宽度计算,主体容易偏移;
- 改成按 previewViewport 计算相机,问题消失。
interface Size2D { width: number; height: number; } interface PreviewLayoutInfo { windowSize: Size2D; viewportSize: Size2D; sidePanelWidth: number; mode: 'phone' | 'tablet' | 'desktopWindow'; } export function calculatePreviewLayout(windowSize: Size2D): PreviewLayoutInfo { if (windowSize.width < 720) { return { windowSize, viewportSize: windowSize, sidePanelWidth: 0, mode: 'phone' }; } const sidePanelWidth = Math.min(360, Math.floor(windowSize.width * 0.32)); return { windowSize, sidePanelWidth, viewportSize: { width: windowSize.width - sidePanelWidth, height: windowSize.height }, mode: windowSize.width > 1100 ? 'desktopWindow' : 'tablet' }; }这里的关键是 viewportSize。3D 场景不关心整个窗口有多宽,它只关心自己实际能画的区域有多大。
相机跟着视口重新算
interface CameraConfig { distance: number; fieldOfView: number; targetOffsetX: number; targetOffsetY: number; } export class ResponsiveCameraPlanner { plan(layout: PreviewLayoutInfo, bounds: ModelBounds): CameraConfig { const aspect = layout.viewportSize.width / Math.max(layout.viewportSize.height, 1); const baseDistance = Math.max(bounds.radius, 1) * 2.6; if (layout.mode === 'phone') { return { distance: baseDistance * 1.08, fieldOfView: 48, targetOffsetX: 0, targetOffsetY: 0 }; } if (aspect > 1.4) { return { distance: baseDistance * 0.95, fieldOfView: 42, targetOffsetX: 0, targetOffsetY: 0 }; } return { distance: baseDistance * 1.15, fieldOfView: 46, targetOffsetX: 0, targetOffsetY: 0 }; } }我不会在 3D 页面里写一个固定相机距离。模型大小、视口宽高比、双栏状态都会影响第一屏效果。相机参数跟随 viewport 计算,才不会出现大屏反而看不清模型的问题。
案例二:窗口缩放后手势区域和 3D 区域错位
第二个案例出现在鸿蒙电脑窗口态或平板分屏里。用户拖动窗口后,页面 UI 变了,但手势识别区域还停留在旧尺寸,结果滑动旋转模型时,手势落点和模型不一致。
复现步骤
- 打开 3DGS 预览页;
- 拖动窗口变窄;
- 右侧面板从常驻变成底部抽屉;
- 如果手势区域没有重新绑定,旋转或缩放会异常;
- 在 onSizeChange 后同步更新 viewport 和 gesture zone。
interface GestureZone { left: number; top: number; width: number; height: number; } export class SpatialGestureZoneStore { private zone: GestureZone = { left: 0, top: 0, width: 0, height: 0 }; updateFromViewport(viewport: Size2D): GestureZone { this.zone = { left: 0, top: 0, width: viewport.width, height: viewport.height }; return { ...this.zone }; } canHandle(pointX: number, pointY: number): boolean { return pointX >= this.zone.left && pointX <= this.zone.left + this.zone.width && pointY >= this.zone.top && pointY <= this.zone.top + this.zone.height; } }3D 手势不要全屏接管。页面里可能还有返回按钮、底部面板、参数滑块、模型信息卡片。手势区域必须跟实际 3D 视口一致,否则用户操作会变得很怪。
页面状态和 3D 状态要一起刷新
interface SpatialPreviewResizeState { layout: PreviewLayoutInfo; camera: CameraConfig; gestureZone: GestureZone; updatedAt: number; } export class SpatialPreviewResizeController { private cameraPlanner = new ResponsiveCameraPlanner(); private gestureStore = new SpatialGestureZoneStore(); resize(windowSize: Size2D, bounds: ModelBounds): SpatialPreviewResizeState { const layout = calculatePreviewLayout(windowSize); const camera = this.cameraPlanner.plan(layout, bounds); const gestureZone = this.gestureStore.updateFromViewport(layout.viewportSize); return { layout, camera, gestureZone, updatedAt: Date.now() }; } }这里我把 resize 单独封装。原因是窗口变化时要更新的不止 ArkUI 布局,还包括相机和手势。只改页面 Column、Row、Stack,不改 3D 视口状态,问题还是会复现。
多设备验证清单
场景 必查点 通过标准 手机竖屏 单栏预览 模型主体首屏可见,底部按钮不挡主体 折叠屏展开 左预览右信息 相机按预览区计算,不按整屏计算 平板横屏 双栏或浮层信息 手势只作用在 3D 区域 鸿蒙电脑窗口 拖动窗口大小 相机、手势、布局同时更新 分屏 视口变窄 面板降级,模型不裁切 最后总结
3DGS 多设备适配不能只看 ArkUI 断点。真正要稳定的是 3D 视口、默认相机和手势区域。窗口变了,预览区变了,相机和手势也要跟着变。
HarmonyOS 7 / API 26 的 3DGS 体验如果只在手机竖屏里验证,很容易漏掉大屏问题。折叠屏、平板、窗口态都是活动要求里的重要方向。把 viewport、camera、gesture 三个状态统一起来,后面接更多 3D 模型和页面形态会稳很多。
更多推荐



所有评论(0)