Appearance
viewer.camera — CameraManager
设计意图
viewer.camera 是相机与导航域,它把「把什么放进视野」抽象成语义操作:fitView 按「显式包围盒 → 指定节点 → 当前选中集 → 整个模型」依次回落解析取景目标,集成方几乎不需要手算相机位姿;setStandardView 提供 7 个工程标准视图(Z-up / CATIA 约定)。鼠标 / 触控交互(旋转 / 平移 / 缩放)由引擎内置接管,API 层只补「程序化导航」与开关(setInteractionEnabled / setNavMode)。
另一个关键抽象是可序列化的位姿快照:getState() 返回 { position, target, up, fov } 纯数据,setState() 部分更新写回——视角书签、跨会话恢复、多视口同步都建立在这一对方法上。相机位姿的一切变化(交互或 API)统一经 camera-changed 事件对外广播。
何时用它:UI 上的「适配 / 标准视图 / 恢复视角」按钮、选中后聚焦、视角持久化与同步。取景目标的「范围」来自模型与选中集,本域只负责「怎么看过去」。
典型用法
工具条「聚焦」按钮(fitView 无参时自动回落:有选中框选中,无选中框整模型):
ts
focusBtn.onclick = () => viewer.camera.fitView();
// 批量出图前跳过动画
viewer.camera.fitView(undefined, { animate: false });视角书签(快照可序列化,跨会话恢复):
ts
const bookmark = viewer.camera.getState(); // { position, target, up, fov }
localStorage.setItem("view-a", JSON.stringify(bookmark));
// 之后恢复:setState 只写传入字段,立即生效
viewer.camera.setState(JSON.parse(localStorage.getItem("view-a")!));主从视口同步(camera-changed 驱动):
ts
main.on("camera-changed", (e) => {
follower.camera.setState({ position: e.position, target: e.target, up: e.up });
});注意事项
fitView解析不出取景范围时静默返回(无模型且无显式box),不抛错;取景保持当前视线方向,只调整距离与注视点。setStandardView在模型尚未取过景时是 no-op:它以最近一次取景范围为中心定距,加载后先fitView()一次再切标准视图。camera-changed交互期间约 30Hz 节流,payload 含position/target/up(不含fov);程序化setState也会触发。setState会取消进行中的相机动画(如fitView的取景过渡):程序化设位姿与用户交互同权,写入的位姿不会被下一帧动画覆盖。setInteractionEnabled(false)只关指针交互,API 控制(setState/fitView)不受影响。
完整签名与延伸
CameraManager— 全部方法的精确签名。FitViewOptions— 取景动画选项(animate默认true、durationMs默认 400)。- 指南:相机与导航 — 内置交互键位、回落链逐条说明与 demo。
- 概念:坐标系与单位 — Z-up 约定与 7 个标准视图的精确语义。