Cesium 模型拖动

同上一篇 模型旋转、缩放 一样,模型拖动也是很常见的操作。

我在网上找了几篇关于模型拖放的博客,修改并进行了封装。

使用方式

npm install cesium-entity-drag
import Drag from 'cesium-entity-drag'

const drag = new Drag(window.viewer)

// start drag
drag.enable()

// or disable
drag.disable()

源码

如果你还有其他定制的需求,可以自行修改源码:

import * as Cesium from 'cesium'

export default class Drag {
  constructor(viewer) {
    this._viewer = viewer
    this.entity = null
    this.handler = null
    this.moving = false

    this._leftDown = this._leftDownHandler.bind(this)
    this._leftUp = this._leftUpHandler.bind(this)
    this._move = this._moveHandler.bind(this)

    this.handler = new Cesium.ScreenSpaceEventHandler(this._viewer.canvas)
  }

  enable() {
    this.handler.setInputAction(this._leftDown, Cesium.ScreenSpaceEventType.LEFT_DOWN);

    this.handler.setInputAction(this._leftUp, Cesium.ScreenSpaceEventType.LEFT_UP)

    this.handler.setInputAction(this._move, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  }

  disable() {    
    this._viewer.scene.screenSpaceCameraController.enableRotate = true

    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP)
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)

    this.moving = false
    this.entity = null
  }

  _leftDownHandler(e) {
    this.entity = this._viewer.scene.pick(e.position)
    this.moving = true
    if (this.entity) {
      this._viewer.scene.screenSpaceCameraController.enableRotate = false
    }
  }

  _leftUpHandler() {
    this.moving = false
    this.entity = null
    this._viewer.scene.screenSpaceCameraController.enableRotate = true
  }

  _moveHandler(e) {
    if (this.moving && this.entity) {
      const ray = this._viewer.camera.getPickRay(e.endPosition)
      const cartesian = this._viewer.scene.globe.pick(ray, this._viewer.scene)
      this.entity.id.position = new Cesium.CallbackProperty(function () {
        return cartesian
      }, false)
    }
  }
}

因为工作关系,也没有进行仔细测试。如果你遇到什么问题,欢迎在下方留言,或者在github仓库 提交 issue

更新(2021年6月21日)

拖动模型还遇到了一个问题, 在_moveHandler中,无论我们是拾取地形坐标、还是球体坐标,总是无法给到正确的高度。

我将拖动进行了修改,仅支持水平拖动,高度的修改请自行实现。原理很简单,将空间坐标cartesian转换成经纬度(实际上是弧度),提取原来的高度,覆盖当前高度。

  _moveHandler(e) {
   if (this.moving && this.entity && this.entity.id) {
     const ray = this._viewer.camera.getPickRay(e.endPosition)
     const cartesian = this._viewer.scene.globe.pick(ray, this._viewer.scene)

     const ellipsoid = viewer.scene.globe.ellipsoid
     const c = ellipsoid.cartesianToCartographic(cartesian)

     const origin = this.entity.id.position.getValue()
     const cc = ellipsoid.cartesianToCartographic(origin)

     this.entity.id.position = new Cesium.CallbackProperty(function () {
       return new Cesium.Cartesian3.fromRadians(c.longitude, c.latitude, cc.height)
     }, false)
   }

代码已更新到npm

本想进行额外的拓展,比如增加高度、旋转操作,但这些并不涉及到鼠标事件,也不复杂,放进来未必能减轻开发人员的负担。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值