原文链接及内容

效果如下视频所示:

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<style>
@import url(../templates/bucket.css);
#cesiumContainer {
display: flex;
width: 100%;
height: 100%;
}
#view3D {
display: inline-block;
width: 100%;
}
#view2D {
display: inline-block;
width: 100%;
}
</style>
<div id="cesiumContainer" class="fullSize">
<div id="view3D"></div>
<div id="view2D"></div>
</div>
<div id="loadingOverlay"><h1>加载中...</h1></div>
<div id="toolbar"></div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// 我们希望两个视图能够跨时间同步,因此我们创建两个视图共享的时钟对象
const clockViewModel = new Cesium.ClockViewModel();
const options3D = {
geocoder: false,
homeButton: false,
sceneModePicker: false,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
animation: false,
timeline: false,
fullscreenButton: false,
skyBox: false,
shouldAnimate: true,
baseLayerPicker: false,
shadows: true,
clockViewModel: clockViewModel,
};

const options2D = {
geocoder: false,
homeButton: false,
sceneModePicker: false,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
animation: false,
timeline: false,
fullscreenButton: false,
skyBox: false,
shouldAnimate: true,
baseLayerPicker: false,
shadows: true,
infoBox: false,
sceneMode: Cesium.SceneMode.SCENE2D,
clockViewModel: clockViewModel,
};
// 我们创建了两个Viewer实例对象,一个 2D 和一个 3D 的,CSS 将它们设置为并排放置
const view3D = new Cesium.Viewer("view3D", options3D);
view3D.cesiumWidget.creditContainer.style.display = "none";
const view2D = new Cesium.Viewer("view2D", options2D);
view2D.cesiumWidget.creditContainer.style.display = "none";

let worldPosition;
let distance;

function sync2DView() {
// 视图中心是 3D 相机聚焦的点
const viewCenter = new Cesium.Cartesian2(
Math.floor(view3D.canvas.clientWidth / 2),
Math.floor(view3D.canvas.clientHeight / 2)
);
// 根据中心像素坐标,将其转换为世界位置(三维笛卡尔坐标)
const newWorldPosition = view3D.scene.camera.pickEllipsoid(viewCenter);
//这里加个判断,排除屏幕中心不落在地球上的某个位置
if (Cesium.defined(newWorldPosition)) {
worldPosition = newWorldPosition;
}
// 计算相机聚焦点的世界坐标位置与相机自身世界坐标位置之间的距离
distance = Cesium.Cartesian3.distance(
worldPosition,
view3D.scene.camera.positionWC
);
/**
* 让 2D 相机对准焦点位置。距离参数控制 2D 视图的缩放程度
* (尝试将下方代码行中的`distance`替换为`1e7`,视图仍会同步,但将保持固定缩放比例)
*/
view2D.scene.camera.lookAt(
worldPosition,
new Cesium.Cartesian3(0.0, 0.0, distance)
);
}

/**
* 这里添加一个监听器,每当 3D 相机视图发生变化时,则执行上述的`sync2DView`函数
*/
view3D.camera.changed.addEventListener(sync2DView);
/**
* 默认情况下,当相机变化达到 50%时,会触发`camera.changed`事件。
* 为了提高灵敏度,我们可以降低这个灵敏度。如下将灵敏度改为1%
*/
view3D.camera.percentageChanged = 0.01;

// 由于 2D 视图跟随 3D 视图,我们禁用 2D 视图中的任何相机移动
view2D.scene.screenSpaceCameraController.enableRotate = false;
view2D.scene.screenSpaceCameraController.enableTranslate = false;
view2D.scene.screenSpaceCameraController.enableZoom = false;
view2D.scene.screenSpaceCameraController.enableTilt = false;
view2D.scene.screenSpaceCameraController.enableLook = false;