/** * @description 飞行漫游 */ import Dialog from '../../../BaseDialog'; import { html } from "./_element"; import Base from "../index"; import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../Global/global' class FlyRoam extends Base { #clickHandler = undefined constructor(sdk, options = {}, _Dialog = {}) { super(sdk, options) this.options.id = options.id || this.randomString() this.options.name = options.name || '漫游路径' this.options.points = options.points || [] if(this.options.repeat) { this.options.repeat = Number(this.options.repeat) } this.Dialog = _Dialog } get repeat() { return this.options.repeat } /**设置循环次数 (Infinity: 无限循环)*/ set repeat(v) { if (this.options.repeat != Number(v)) { this.options.repeat = Number(v) if (this._DialogObject && this._DialogObject._element && this._DialogObject._element.content) { let repeatElm = this._DialogObject._element.content.querySelector("input[name='repeat']") if (v === Infinity) { repeatElm.checked = true } else { repeatElm.checked = false } this.Dialog.changeRepeatStateCallBack && this.Dialog.changeRepeatStateCallBack(repeatElm.checked) } } } async edit(state) { let _this = this let viewer = this.sdk.viewer let active = 0 if (this._DialogObject && this._DialogObject.close) { this._DialogObject.close() this._DialogObject = null } if (state) { this._DialogObject = await new Dialog(viewer._container, { title: '飞行漫游', left: '180px', top: '100px', closeCallBack: () => { this.cease() }, }) await this._DialogObject.init() let contentElm = document.createElement('div'); contentElm.className = 'fly-roam' contentElm.innerHTML = html() this._DialogObject.contentAppChild(contentElm) let all_elm = contentElm.getElementsByTagName("*") // EventBinding(all_elm) let tableBody = contentElm.getElementsByClassName('table-body')[0]; let tableEmpty = contentElm.getElementsByClassName('table-empty')[0] let handler = { set: function (target, prop, value) { target[prop] = value; if (target.length > 0) { tableEmpty.style.display = 'none' } else { tableEmpty.style.display = 'flex' } return true; }, }; let i = 0 let points = new Proxy([], handler); for (i = 0; i < this.options.points.length; i++) { points.push(this.options.points[i]) addTrElm(this.options.points[i]) } // let nameImputBoxElm = contentElm.getElementsByClassName('input-box')[0] // check(nameImputBoxElm, { validator: 'notEmpty', message: '名称不能为空!', trigger: 'input' }) let nameElm = contentElm.querySelector("input[name='name']") nameElm.value = this.name nameElm.addEventListener('input', () => { this.name = nameElm.value }) let addListBtn = document.createElement('button'); addListBtn.innerHTML = '保存' addListBtn.addEventListener('click', () => { if (!this.name) { this.name = '漫游路径' nameElm.value = this.name } let newPoints = [] points.map((item) => { newPoints.push(item) }) this._DialogObject.close() this.Dialog.confirmCallBack && this.Dialog.confirmCallBack( { id: this.options.id, name: this.name, points: newPoints, repeat: this.repeat+'' } ) }) this._DialogObject.footAppChild(addListBtn) let endBtn = contentElm.getElementsByClassName('cease')[0] endBtn.addEventListener('click', () => { viewer.camera.cancelFlight() }) let flyBtn = contentElm.getElementsByClassName('afreshPlay')[0] flyBtn.addEventListener('click', () => { if (points.length > 0) { this.flyTo(0) } }) let addBtn = contentElm.getElementsByClassName('add-point')[0] addBtn.addEventListener('click', () => { let position = this.cartesian3Towgs84(viewer.camera.position, viewer) let time = 0 let data = { duration: time, position: position, orientation: { heading: viewer.camera.heading, pitch: viewer.camera.pitch, roll: viewer.camera.roll } } points.splice(active, 0, data) this.options.points.splice(active, 0, data) addTrElm(data) i++ }) let modifyBtn = contentElm.getElementsByClassName('modify-point')[0] modifyBtn.addEventListener('click', () => { if (!active) { return } let position = this.cartesian3Towgs84(viewer.camera.position, viewer) this.options.points[active - 1].position = points[active - 1].position = position this.options.points[active - 1].orientation = points[active - 1].orientation = { heading: viewer.camera.heading, pitch: viewer.camera.pitch, roll: viewer.camera.roll } }) let totalTimeElm = contentElm.querySelector("input[name='totalTime']") let isTotalTimeElm = contentElm.querySelector("input[name='isTotalTime']") let repeatElm = contentElm.querySelector("input[name='repeat']") isTotalTimeElm.addEventListener('change', () => { let trList = tableBody.getElementsByClassName('tr') if (isTotalTimeElm.checked && trList.length > 0) { let time = Number((Number(totalTimeElm.value) / (trList.length - 1)).toFixed(2)) for (let i = 0; i < trList.length - 1; i++) { points[i].duration = time this.options.points[i].duration = time trList[i].querySelector("input[name='time']").value = time } trList[trList.length - 1].querySelector("input[name='time']").value = 0 } }) totalTimeElm.addEventListener('blur', () => { let trList = tableBody.getElementsByClassName('tr') totalTimeElm.value = Number(totalTimeElm.value) if (totalTimeElm.value < 0) { totalTimeElm.value = 0 } if (isTotalTimeElm.checked && trList.length > 0) { let time = Number((Number(totalTimeElm.value) / (trList.length - 1)).toFixed(2)) for (let i = 0; i < trList.length - 1; i++) { points[i].duration = time this.options.points[i].duration = time trList[i].querySelector("input[name='time']").value = time } trList[trList.length - 1].querySelector("input[name='time']").value = 0 } }) repeatElm.checked = (this.repeat === Infinity ? true : false) repeatElm.addEventListener('change', () => { if (repeatElm.checked) { this.repeat = Infinity } else { this.repeat = 0 } }) // Object.defineProperty(options, 'points', { // get() { // return e_allArea.value // }, // set(value) { // e_allArea.value = value // } // }) function addTrElm(data) { let trList = tableBody.getElementsByClassName('tr') if (trList.length > 0) { trList[trList.length - 1].querySelector("input[name='time']").disabled = undefined } let tr_active = tableBody.getElementsByClassName('tr active')[0] tr_active && (tr_active.className = 'tr') let tr = document.createElement('div'); tr.className = 'tr active' tr.innerHTML = `
视点${i + 1}
` tr.addEventListener('click', (v) => { if (v.target.parentNode === tr) { let tr_active = tableBody.getElementsByClassName('tr active')[0] tr_active && (tr_active.className = 'tr') tr.className = 'tr active' for (let m = 0; m < trList.length; m++) { if (trList[m] === tr) { active = m + 1 break } } } }) tr.addEventListener('dblclick', (v) => { if (v.target.parentNode === tr) { for (let m = 0; m < trList.length; m++) { if (trList[m] === tr) { viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(points[m].position.lng, points[m].position.lat, points[m].position.alt), orientation: points[m].orientation, duration: 1 }) break } } } }) let e_play = tr.getElementsByClassName('play')[0] let e_delete = tr.getElementsByClassName('delete')[0] let e_time = tr.querySelector("input[name='time']") e_play.addEventListener('click', () => { for (let m = 0; m < trList.length; m++) { if (trList[m] === e_delete.parentNode.parentNode) { _this.flyTo(m) } } }) e_delete.addEventListener("click", (v) => { for (let m = 0; m < trList.length; m++) { if (trList[m] === e_delete.parentNode.parentNode) { points.splice(m, 1) points[points.length-1].duration = 0 _this.options.points.splice(m, 1) tableBody.removeChild(tr) if (active > m + 1) { active-- trList[active - 1].className = 'tr active' } else if (active == m + 1) { if (trList.length == m) { active -= 1 } if (trList.length != 0) { trList[active - 1].className = 'tr active' } } // else if(active == m) { // console.log(trList.length-1, active) // if (trList.length == active-1) { // trList[active-2].className = 'tr active' // } // else { // trList[active-1].className = 'tr active' // } // } if (trList.length > 0) { let lastElm = trList[trList.length - 1].querySelector("input[name='time']") lastElm.disabled = 'disabled' lastElm.value = 0 } break } } // points.splice(i, 1) // tableBody.removeChild(tr) // if (trList.length > 0) { // trList[trList.length - 1].querySelector("input[name='time']").disabled = 'disabled' // } }) e_time.addEventListener('input', (v) => { isTotalTimeElm.checked = false data.duration = Number(e_time.value) if (data.duration < 0) { data.duration = 0 } }) e_time.addEventListener('blur', () => { e_time.value = Number(Number(e_time.value).toFixed(2)) if (e_time.value < 0) { e_time.value = 0 } }); tableBody.insertBefore(tr, trList[active]) active++ trList[trList.length - 1].querySelector("input[name='time']").disabled = 'disabled' } } } flyTo(i = 0) { setActiveViewer(0) let _this = this let points = this.options.points let currentRepeat = this.repeat closeRotateAround(_this.sdk) const executeFlyTo = (index = 0, noStart) => { if (this.#clickHandler) { this.#clickHandler.destroy() } let _this = this this.#clickHandler = new Cesium.ScreenSpaceEventHandler(_this.sdk.viewer.canvas) this.#clickHandler.setInputAction((movement) => { this.cease() }, Cesium.ScreenSpaceEventType.RIGHT_CLICK) let viewer = _this.sdk.viewer setActiveViewer(0) viewer.camera.cancelFlight() // function pauseExecution(seconds) { // return new Promise(resolve => setTimeout(resolve, seconds * 1000)); // } viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(points[index].position.lng, points[index].position.lat, points[index].position.alt), orientation: points[index].orientation, duration: noStart ? points[index - 1].duration : 0.5, maximumHeight: points[index].position.alt, complete: async () => { // if (!noStart) { // // await pauseExecution(2) // } index++ if (this.repeat === Infinity) { currentRepeat = Infinity } else if (currentRepeat === Infinity) { currentRepeat = this.repeat } if (index <= points.length - 1) { executeFlyTo(index, true) } else if (currentRepeat) { currentRepeat-- executeFlyTo(0) } else { if (this.#clickHandler) { this.#clickHandler.destroy() } } }, easingFunction: noStart ? Cesium.EasingFunction.LINEAR_NONE : Cesium.EasingFunction.EXPONENTIAL_OUT }) } executeFlyTo(i) } /** 停止 */ cease() { this.sdk && this.sdk.viewer && this.sdk.viewer.camera.cancelFlight() if (this.#clickHandler) { this.#clickHandler.destroy() } } remove() { if (this._DialogObject && this._DialogObject.close) { this._DialogObject.close() this._DialogObject = null } else { this.cease() } } } export default FlyRoam