首先可以先看看效果:
采用的是vue2的框架,整体结构较为简单,主要元素如下:
<template>
<div>
<div id="cesiumContainer1" :class="cesiumInitClass1" @mouseenter="leftMouseEnter" @mouseleave="leftMouseLeave"></div>
<div id="cesiumContainer2" :class="cesiumInitClass2" @mouseenter="rightMouseEnter" @mouseleave="rightMouseLeave"></div>
</div>
</template>
就是两个div标签用来初始化两个地球,同时监听了鼠标的移入和移出事件。
主体思路就是:当鼠标移入左边的div时,利用cesium自带的api监听鼠标的移动事件,然后获取此时左边的视角,将右边的视角与左边的设置为一致。移出div时就将之前绑定好的关系解除。
当鼠标移动到右侧的div时也是同理。
因为我用的是vue2,所以在这个组件中运用了一些“全局”变量,方便我在不同的函数中进行调用。
注意:其实这里data中的数据最好改成$开头,否则有可能引起卡顿。详见我的另一篇博客:https://blog.csdn.net/XFIRR/article/details/129259052?spm=1001.2014.3001.5502
data() {
return {
// 这里是两个样式
cesiumInitClass1: "cesiumInitClass1",
cesiumInitClass2: "cesiumInitClass2",
// 左屏幕,最好改成$leftViewer
leftViewer: {},
// 右屏幕,最好改成$rightViewer
rightViewer: {},
// 屏幕的监听事件,最好改成$Handler
Handler:{}
};
},
然后再对监听的事件进行处理即可,要跟data中的保持一致,我这里就没改了。
// 获取相机属性
getViewPoint(viewer) {
return {
position: viewer.camera.position.clone(),
orientation: {
heading: viewer.camera.heading,
pitch: viewer.camera.pitch,
roll: viewer.camera.roll,
},
};
},
// 视窗移动,NowViewer就是鼠标现在在的,AfterViewer就是被联动那个
ViewerMove(NowViewer, AfterViewer) {
const viewPoint = this.getViewPoint(NowViewer);
AfterViewer.camera.setView({
destination: viewPoint.position,
orientation: viewPoint.orientation,
});
},
// 鼠标进入左边
leftMouseEnter(){
this.Handler = new Cesium.ScreenSpaceEventHandler(this.leftViewer.scene.canvas);
this.Handler.setInputAction(()=> {
this.ViewerMove(this.leftViewer,this.rightViewer)
},Cesium.ScreenSpaceEventType.MOUSE_MOVE)
},
// 鼠标从左边出去
leftMouseLeave(){
this.Handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)//移除事件
},
// 鼠标进入右边
rightMouseEnter(){
this.Handler = new Cesium.ScreenSpaceEventHandler(this.rightViewer.scene.canvas);
this.Handler.setInputAction(()=> {
this.ViewerMove(this.rightViewer,this.leftViewer)
},Cesium.ScreenSpaceEventType.MOUSE_MOVE)
},
// 鼠标从右边出去
rightMouseLeave(){
this.Handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)//移除事件
}
大体的实现过程就是这样。
至于展示的动图里面点击HomeButton会有一小段没有处理我就只能等之后在慢慢看看怎么解决了。如果有会解决的兄弟麻烦评论区告诉我一下,Thanks!
顺带一说,我的里面的标注就是直接用的天地图提供的注记图层:
this.leftViewer = new Cesium.Viewer("cesiumContainer1", {
...
let blackMarble = layers.addImageryProvider(
new Cesium.UrlTemplateImageryProvider({
url: "http://t0.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=你的密钥",
})
);
使用的方法也在代码块里了。