cesium控制及效果(六):卷帘对比

883 阅读2分钟

1、概述

卷帘是指在同一屏幕,左右或者上下同时看到两个图层,可以直观的进行对比。这里主要讲一下左右卷帘的实现。

2、创建地图容器

<div id="cesiumContainer"></div> //cesium容器
<div id="slider"></div>  //滑块容器
//style
#cesiumContainer{
    width: 100%;
    height: 100vh;
}
//滑块初始样式
#slider{
    position: absolute;
    left: 50%;
    top: 0px;
    background-color: #d3d3d3;
    width: 3px;
    height: 100%;
    z-index: 9999;
}
#slider:hover {
    cursor: e-resize;
}

3、地图初始化

import * as Cesium from 'cesium' 
//1、cesium初始化
const initViewer = (cesiumId) =>{ 
    let viewer = new Cesium.Viewer(cesiumId,{ 
        ... //具体内容配置参考前面一篇文章:vue3+cesium项目初始化--https://juejin.cn/post/7234088398020067387 
    }) 
    return viewer 
} 
let viewer = initViewer('cesiumContainer'); //cesuim初始化

4、左侧图层设置

//cesium初始化后调用方法 -- setLeft(viewer)
const setLeft = (viewer) => {
    //加载arcgis地图服务
    const leftLayer = viewer.imageryLayers.addImageryProvider(
        new Cesium.ArcGisMapServerImageryProvider({
            url: 'https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer'
        })
    );
    // 设置arcgis服务显示在卷帘左侧
    leftLayer.splitDirection = Cesium.SplitDirection.LEFT;
    //cesium鼠标事件处理
    setLeftSlider(viewer);
};

let moveActive = false;
let slider;

//cesium鼠标事件处理,实时更新场景分割器位置
const setLeftSlider = (viewer) => {
    //获取滑块dom
    slider = document.getElementById("slider");
    if(slider){
        //设置场景分割器位置
        viewer.scene.splitPosition = slider.offsetLeft / slider.parentElement.offsetWidth;
        //绑定滑块dom,便于后续添加cesium事件
        const handler = new Cesium.ScreenSpaceEventHandler(slider);
        //cesium事件注册,用于设置滑块是否可移动,以及监听滑块位置变化
        //鼠标事件
        //鼠标左键按下事件--允许滑块移动
        handler.setInputAction(() =>{
            moveActive = true;
        }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
        //鼠标移动事件--监听滑块移动,然后计算场景分割器位置
        handler.setInputAction(move, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        // 鼠标左键向上事件--禁止滑块移动
        handler.setInputAction(() => {
            moveActive = false;
        }, Cesium.ScreenSpaceEventType.LEFT_UP);
        
        //触摸事件
        //触摸表面上两指事件的开始
        handler.setInputAction(() => {
            moveActive = true;
        }, Cesium.ScreenSpaceEventType.PINCH_START);
        //触摸表面上两指事件的变化
        handler.setInputAction(move, Cesium.ScreenSpaceEventType.PINCH_MOVE);
        // 触摸表面上的两指事件的结束
        handler.setInputAction(() => {
            moveActive = false;
        }, Cesium.ScreenSpaceEventType.PINCH_END);
    } 
};

//鼠标移动事件监听
const move = (movement) => {
    if(!moveActive){
        return;
    }
    // 获取鼠标移动处x坐标
    const relativeOffset = movement.endPosition.x;
    // 计算分割器位置
    const splitPosition = (slider.offsetLeft + relativeOffset) / slider.parentElement.offsetWidth;
    //设置滑块dom位置
    slider.style.left = `${100.0 * splitPosition}%`;
    //设置场景分割器位置
    viewer.scene.splitPosition = splitPosition;
}

5、实现效果

image.png

项目地址:github.com/DLFouge/vue…

欢迎指正与star