core/analysis/Split.js

import { Cesium } from '../../../namespace'
import { BaseLayer } from '../Layers'
/**
 * 卷帘分析类
 * @class
 */
class Split {
  /**
   * 构造函数
   * @param {Object} viewer 地图场景对象
   */
  constructor(viewer) {
    this._viewer = viewer
    this._enabled = false
    this._splitLayer = BaseLayer.DefaultTdtVec
    this._splitDirection = Cesium.SplitDirection.RIGHT
    this._dom = undefined
  }

  /**
   * 是否启用
   * @type {Boolean}
   */
  get enabled() {
    return this._enabled
  }
  set enabled(bool) {
    if (bool === this._enabled) return
    this._enabled = bool
    bool ? this.init() : this.remove()
  }

  /**
   * 卷帘图层方向,-1:左侧,1:右侧
   * @type {Number}
   */
  get splitDirection() {
    return this._splitDirection
  }
  set splitDirection(val) {
    if (val === -1) {
      this._splitLayer.splitDirection = Cesium.SplitDirection.LEFT
      this._splitDirection = -1
    }
    if (val === 1) {
      this._splitLayer.splitDirection = Cesium.SplitDirection.RIGHT
      this._splitDirection = 1
    }
  }

  /**
   * 卷帘图层,ImageryLayer类型,参考Cesium
   * @type {ImageryLayer}
   */
  get splitLayer() {
    return this._splitLayer
  }
  set splitLayer(layer) {
    this._viewer.imageryLayers.remove(this._splitLayer)
    this._splitLayer = layer
    this._splitLayer.splitDirection = this._splitDirection
    this._viewer.imageryLayers.add(this._splitLayer)
  }

  init() {
    if (this._splitLayer.isDestroyed()) {
      this._splitLayer = BaseLayer.DefaultTdtVec
    }
    this._splitLayer.splitDirection = this._splitDirection
    this._viewer.imageryLayers.add(this._splitLayer)
    this._viewer.scene.splitPosition = 0.5
    this.initDom()
  }

  initDom() {
    this._dom = document.createElement('div')
    this._dom.id = 'cus-layer-slider'
    const innerHTML = `
    <div class="slider-main">
      <span id="optionOne" class="option left">方案一</span>
      <span class="line"></span>
      <span id="optionTwo" class="option right">方案二</span>
    </div>
    <div id="slider-button"></div>
    `
    this._dom.innerHTML = innerHTML
    this._viewer.container.appendChild(this._dom)
    // 给滑块添加鼠标进入事件监听器
    const sliderButton = this._dom.querySelector('#slider-button')
    sliderButton.addEventListener('mouseenter', this.mouseEnter.bind(this))
    sliderButton.addEventListener('mouseleave', this.mouseleave.bind(this))

    this._handler = new Cesium.ScreenSpaceEventHandler(sliderButton)

    let moveActive = false
    let left = '0'
    const $this = this
    function move(movement) {
      if (!moveActive) return
      const relativeOffset = movement.endPosition.x
      const splitPosition =
        ($this._dom.offsetLeft + relativeOffset) /
        $this._dom.parentElement.offsetWidth
      left = `${100.0 * splitPosition}%`
      $this._dom.style.left = left
      $this._viewer.scene.splitPosition = splitPosition
    }

    this._handler.setInputAction(function () {
      moveActive = true
    }, Cesium.ScreenSpaceEventType.LEFT_DOWN)
    this._handler.setInputAction(function () {
      moveActive = true
    }, Cesium.ScreenSpaceEventType.PINCH_START)

    this._handler.setInputAction(move, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
    this._handler.setInputAction(move, Cesium.ScreenSpaceEventType.PINCH_MOVE)

    this._handler.setInputAction(function () {
      moveActive = false
    }, Cesium.ScreenSpaceEventType.LEFT_UP)
    this._handler.setInputAction(function () {
      moveActive = false
    }, Cesium.ScreenSpaceEventType.PINCH_END)
  }
  mouseEnter(event) {
    this.active(true)
  }
  mouseleave(event) {
    this.active(false)
  }
  active(bool) {
    const line = this._dom.querySelector('.line')
    bool ? line.classList.add('active') : line.classList.remove('active')
    const sliderButton = this._dom.querySelector('#slider-button')
    bool
      ? sliderButton.classList.add('active')
      : sliderButton.classList.remove('active')
  }
  /**
   * 移除卷帘
   */
  remove() {
    this._viewer.container.removeChild(this._dom)
    this._dom = undefined
    this._handler && this._handler.destroy()
    this._handler = undefined
    this._viewer.imageryLayers.remove(this._splitLayer)
  }
}

export default Split