438 lines
15 KiB
JavaScript
438 lines
15 KiB
JavaScript
|
|
/**
|
|
* @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
|
|
* @param sdk
|
|
* @description 飞行漫游
|
|
* @param options {object}
|
|
* @param options.id {string} 标注id
|
|
* @param options.name {string} 名称
|
|
* @param options.repeat=0 {number} 重复次数
|
|
* @param options.points=[]] {array} 视点列表
|
|
* @param options.points[].position {object} 视点位置
|
|
* @param options.points[].position.lng {number} 经度
|
|
* @param options.points[].position.lat {number} 纬度
|
|
* @param options.points[].position.alt {number} 高度
|
|
* @param options.points[].orientation {object} 视点方向
|
|
* @param options.points[].orientation.heading=0 {number} 视点航向角
|
|
* @param options.points[].orientation.pitch=0 {number} 视点俯仰角
|
|
* @param options.points[].orientation.roll=0 {number} 视点翻滚角
|
|
* @param options.points[].duration=0 {number} 持续时间
|
|
**/
|
|
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
|
|
}
|
|
this.message({text: '操作成功'})
|
|
})
|
|
|
|
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 = `
|
|
<div class="td" style="justify-content: center;">视点${i + 1}</div>
|
|
<div class="td">
|
|
<input class="input time" type="number" title="" min="0" max="999.99" step="0.01" name="time" value="${data.duration}">
|
|
</div>
|
|
<div class="td action">
|
|
<button class="play">播放</span>
|
|
<button class="delete">删除</span>
|
|
</div>
|
|
`
|
|
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 |