Files
sdk4.0/src/Global/FlyRoam/index.js
2025-08-23 15:25:25 +08:00

390 lines
12 KiB
JavaScript

/**
* @description 飞行漫游
*/
import Dialog from '../../BaseDialog';
import { html } from "./_element";
import Tools from "../../Tools";
import { closeRotateAround, closeViewFollow} from '../../Global/global'
let _DialogObject = null
let clickHandler
let repeat = 0
let currentRepeat = 0
const open = async (sdk, options = {}, _Dialog = {}) => {
let name = options.name || '漫游路径'
options.points || (options.points = [])
if(options.repeat) {
repeat = Number(options.repeat)
}
let viewer = sdk.viewer
let tools = new Tools(sdk)
let active = 0
if (_DialogObject && _DialogObject.close) {
_DialogObject.close()
_DialogObject = null
}
_DialogObject = await new Dialog(viewer._container, {
title: '飞行漫游', left: '180px', top: '100px',
closeCallBack: () => {
cease({ viewer })
},
})
await _DialogObject.init()
let contentElm = document.createElement('div');
contentElm.className = 'fly-roam'
contentElm.innerHTML = html()
_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 < options.points.length; i++) {
points.push(options.points[i])
addTrElm(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 = name
nameElm.addEventListener('input', () => {
name = nameElm.value
})
let addListBtn = document.createElement('button');
addListBtn.innerHTML = '保存'
addListBtn.addEventListener('click', () => {
if (!name) {
name = '漫游路径'
nameElm.value = name
}
let newPoints = []
points.map((item) => {
newPoints.push(item)
})
_Dialog.clickSavePath && _Dialog.clickSavePath(
{
name: name,
points: newPoints,
repeat: repeat+''
}
)
})
_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) {
flyTo(sdk, points, 0)
}
})
let addBtn = contentElm.getElementsByClassName('add-point')[0]
addBtn.addEventListener('click', () => {
let position = tools.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)
addTrElm(data)
i++
})
let modifyBtn = contentElm.getElementsByClassName('modify-point')[0]
modifyBtn.addEventListener('click', () => {
if (!active) {
return
}
let position = tools.cartesian3Towgs84(viewer.camera.position, viewer)
points[active - 1].position = position
points[active - 1].orientation = {
heading: viewer.camera.heading,
pitch: viewer.camera.pitch,
roll: viewer.camera.roll
}
tools.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
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
trList[i].querySelector("input[name='time']").value = time
}
trList[trList.length - 1].querySelector("input[name='time']").value = 0
}
})
repeatElm.checked = (repeat === Infinity ? true : false)
repeatElm.addEventListener('change', () => {
if (repeatElm.checked) {
repeat = Infinity
}
else {
repeat = 0
}
currentRepeat = repeat
_Dialog.changeRepeatStateCallBack && _Dialog.changeRepeatStateCallBack(repeatElm.checked)
})
// 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) {
flyTo(sdk, points, 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] && (points[points.length-1].duration = 0)
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'
}
}
const close = () => {
if (_DialogObject && _DialogObject.close) {
_DialogObject.close()
_DialogObject = null
}
}
const executeFlyTo = (sdk, points = [], index = 0, noStart) => {
if (clickHandler) {
clickHandler.destroy()
}
clickHandler = new Cesium.ScreenSpaceEventHandler(sdk.viewer.canvas)
clickHandler.setInputAction((movement) => {
cease(sdk)
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
let viewer = sdk.viewer
viewer.camera.cancelFlight()
// function pauseExecution(seconds) {
// return new Promise(resolve => setTimeout(resolve, seconds * 1000));
// }
closeRotateAround(sdk)
closeViewFollow(sdk)
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 (index <= points.length - 1) {
executeFlyTo(sdk, points, index, true)
}
else if (currentRepeat && points.length > 1) {
currentRepeat--
executeFlyTo(sdk, points, 0)
}
else {
if (clickHandler) {
clickHandler.destroy()
}
}
},
easingFunction: noStart ? Cesium.EasingFunction.LINEAR_NONE : Cesium.EasingFunction.EXPONENTIAL_OUT
})
}
const flyTo = (sdk, points = [], index = 0, noStart) => {
currentRepeat = repeat
executeFlyTo(sdk, points, index, noStart)
}
/**设置循环次数 (Infinity: 无限循环)*/
const setRepeat = (v) => {
if (repeat != Number(v)) {
repeat = Number(v)
currentRepeat = repeat
if (_DialogObject && _DialogObject._element && _DialogObject._element.content) {
let repeatElm = _DialogObject._element.content.querySelector("input[name='repeat']")
if (v === Infinity) {
repeatElm.checked = true
}
else {
repeatElm.checked = false
}
}
}
}
/** 停止 */
const cease = (sdk) => {
sdk && sdk.viewer && sdk.viewer.camera.cancelFlight()
if (clickHandler) {
clickHandler.destroy()
}
}
export { open, close, flyTo, setRepeat, cease }