Appearance
ViewerSync 双屏相机同步
让两个 Cesium Viewer 的相机联动:以
on(host)的 host 与options.target组成联动对, 主控 Viewer 每次渲染后把其position/heading/pitch/roll通过公共camera.setView复制到 从属 Viewer,实现实时同步。
能力定位
ViewerSync 适合:
- 双屏对比:同一场景左右分屏,操作一边另一边实时跟随,直观对比视角;
- 大屏联动:主视角 + 从属视角同时呈现,主控操作统一所有屏;
- 多窗口监控台:二三维 / 多窗口的相机统一,从一个屏控制全部。
与 CameraBoundary(被动约束)不同:ViewerSync 是主动联动——主控相机每次移动都会 驱动从属相机,二者可组合使用(约束主控屏范围,其余屏跟随)。
构造函数
ts
constructor(options: ViewerSyncOptions)ts
interface ViewerSyncOptions {
target: Viewer // 必填:与 host 构成联动对的另一 Viewer
mode?: ViewerSyncMode // 同步模式,默认 'hover'
}| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
target | Viewer | (必填) | 与 on(host) 的 host 组成联动对的另一 Viewer |
mode | 'hover' | 'a-to-b' | 'b-to-a' | 'hover' | 主从判定方式 |
主从模式(mode)
| 模式 | 主控 | 说明 |
|---|---|---|
hover(默认) | 鼠标悬停所在 Viewer | 鼠标移到哪屏,哪屏主控,另一屏跟随 |
a-to-b | host | 固定 host 主控,target 跟随 |
b-to-a | target | 固定 target 主控,host 跟随 |
注意:
mode在构造后只读。需要运行时切换模式时,destroy旧实例并按新模式重建 (参考示例代码的「模式切换」按钮做法)。
生命周期
实现 Lifecycle<Viewer> 契约,on/off/destroy 均幂等:
ts
on(viewer: Viewer): void // 绑定两个 Viewer 的 scene.postRender 与容器 mouseenter
off(viewer: Viewer): void // 移除全部监听(幂等,可再次 on)
destroy(viewer: Viewer): void // 等价于 off + 置空 target 引用清理完整性:本类只拥有两个 Viewer 的 postRender 监听与容器 mouseenter 处理器, off/destroy 全部移除并置空引用,不触碰调用方相机与其他资源。
基础示例
ts
import { ViewerSync } from '@nexa/gis-cesium'
// viewer1 为 host,viewer2 为 target,默认 hover 模式
const sync = new ViewerSync({ target: viewer2 })
sync.on(viewer1) // 开启:鼠标所在 Viewer 为主控,另一个跟随
// 页面或场景退出时统一销毁(幂等)
sync.destroy(viewer1)进阶示例
固定主从 + 运行时切换模式:
ts
import { ViewerSync } from '@nexa/gis-cesium'
let sync = new ViewerSync({ target: viewer2, mode: 'a-to-b' })
sync.on(viewer1) // 固定 viewer1 主控,viewer2 跟随
// 切换为 b-to-a:mode 构造后只读,需重建
sync.destroy(viewer1)
sync = new ViewerSync({ target: viewer2, mode: 'b-to-a' })
sync.on(viewer1) // 固定 viewer2 主控,viewer1 跟随实现说明
- 同步时机:分别监听两个 Viewer 的
scene.postRender(每帧渲染回调),按主从判定复制相机, 实现真正的双向联动。 - 源案例缺陷修复:源实现(
Analysis/ViewerSync)仅监听 viewer1 的postRender,当仅 viewer2 相机移动而 viewer1 静止时反向同步失效;本实现分别监听两个 Viewer 的postRender并按主从判定复制,修复该缺陷。 - 防反馈循环:复制使用
dst.camera.setView期间置_syncing重入保护,且主从判定保证 从属屏渲染不会反向驱动主控屏。 - 公共 API:复制相机全部使用 Cesium 公共
camera.position/heading/pitch/roll/setView, 不触碰私有字段。 - 无外部依赖:源案例的外网底图 / 初始飞行 / 隐藏 credit 等 demo 编排迁移时剥离, 使用 SDK 默认底图与示例区域视角。
清理责任
ts
sync.destroy(viewer1) // 或 sync.off(viewer1),等价且幂等重复调用 destroy/off 安全(未 on 时为空操作)。销毁后重新 on 可再次启用同步。
Cesium 版本限制
- 依赖 Cesium 公共
Camera.setView/position/heading/pitch/roll与Scene.postRender事件、EventContainer的mouseenter; - 已验证目标版本:Cesium 1.133.1。