修改了动画逻辑 在动画结束的时候 删除掉新增的动画实体
This commit is contained in:
parent
539f1b16db
commit
dd74af0930
@ -146,10 +146,10 @@ export function useEntityAnimation() {
|
|||||||
const pulseScale = options.disablePulse
|
const pulseScale = options.disablePulse
|
||||||
? 1.0
|
? 1.0
|
||||||
: new Cesium.CallbackProperty((time) => {
|
: new Cesium.CallbackProperty((time) => {
|
||||||
const elapsed = Cesium.JulianDate.secondsDifference(time, startTime)
|
const elapsed = Cesium.JulianDate.secondsDifference(time, startTime)
|
||||||
// 使用正弦波产生脉冲效果,频率 3Hz,幅度 ±30%
|
// 使用正弦波产生脉冲效果,频率 3Hz,幅度 ±30%
|
||||||
return 1.0 + Math.sin(elapsed * 3) * 0.3
|
return 1.0 + Math.sin(elapsed * 3) * 0.3
|
||||||
}, false)
|
}, false)
|
||||||
|
|
||||||
// 创建动画实体
|
// 创建动画实体
|
||||||
const entity = viewer.entities.add({
|
const entity = viewer.entities.add({
|
||||||
@ -302,66 +302,70 @@ export function useEntityAnimation() {
|
|||||||
* @returns {Cesium.Entity}
|
* @returns {Cesium.Entity}
|
||||||
*/
|
*/
|
||||||
const createMovingEntity = (viewer, pathCoordinates, config, startTime, stopTime) => {
|
const createMovingEntity = (viewer, pathCoordinates, config, startTime, stopTime) => {
|
||||||
const positionProperty = new Cesium.SampledPositionProperty()
|
try {
|
||||||
const numberOfPoints = pathCoordinates.length
|
const positionProperty = new Cesium.SampledPositionProperty()
|
||||||
const timeInterval = config.duration / (numberOfPoints - 1)
|
const numberOfPoints = pathCoordinates.length
|
||||||
|
|
||||||
pathCoordinates.forEach((coord, index) => {
|
if (numberOfPoints === 0) {
|
||||||
const time = Cesium.JulianDate.addSeconds(
|
console.warn('[useEntityAnimation] 路径坐标为空')
|
||||||
startTime,
|
return null
|
||||||
index * timeInterval,
|
}
|
||||||
new Cesium.JulianDate()
|
|
||||||
)
|
|
||||||
const position = new Cesium.Cartesian3(coord.x, coord.y, coord.z)
|
|
||||||
positionProperty.addSample(time, position)
|
|
||||||
})
|
|
||||||
|
|
||||||
const pulseScale = config.disablePulse
|
const timeInterval = config.duration / (numberOfPoints - 1)
|
||||||
? 1.0
|
|
||||||
: new Cesium.CallbackProperty((time) => {
|
pathCoordinates.forEach((coord, index) => {
|
||||||
|
const time = Cesium.JulianDate.addSeconds(
|
||||||
|
startTime,
|
||||||
|
index * timeInterval,
|
||||||
|
new Cesium.JulianDate()
|
||||||
|
)
|
||||||
|
const position = new Cesium.Cartesian3(coord.x, coord.y, coord.z)
|
||||||
|
positionProperty.addSample(time, position)
|
||||||
|
})
|
||||||
|
|
||||||
|
const pulseScale = config.disablePulse
|
||||||
|
? 1.0
|
||||||
|
: new Cesium.CallbackProperty((time) => {
|
||||||
const elapsed = Cesium.JulianDate.secondsDifference(time, startTime)
|
const elapsed = Cesium.JulianDate.secondsDifference(time, startTime)
|
||||||
return 1.0 + Math.sin(elapsed * 3) * 0.3
|
return 1.0 + Math.sin(elapsed * 3) * 0.3
|
||||||
}, false)
|
}, false)
|
||||||
|
|
||||||
const icon = config.type === 'device' ? deviceIcon : soldierIcon
|
const icon = config.type === 'device' ? deviceIcon : soldierIcon
|
||||||
const trailColor = config.type === 'device' ? Cesium.Color.ORANGE : Cesium.Color.CYAN
|
|
||||||
|
|
||||||
return viewer.entities.add({
|
const entity = viewer.entities.add({
|
||||||
availability: new Cesium.TimeIntervalCollection([
|
availability: new Cesium.TimeIntervalCollection([
|
||||||
new Cesium.TimeInterval({ start: startTime, stop: stopTime })
|
new Cesium.TimeInterval({ start: startTime, stop: stopTime })
|
||||||
]),
|
]),
|
||||||
position: positionProperty,
|
position: positionProperty,
|
||||||
orientation: new Cesium.VelocityOrientationProperty(positionProperty),
|
orientation: new Cesium.VelocityOrientationProperty(positionProperty),
|
||||||
billboard: {
|
billboard: {
|
||||||
image: icon,
|
image: icon,
|
||||||
width: 48,
|
width: 48,
|
||||||
height: 56,
|
height: 56,
|
||||||
scale: pulseScale,
|
scale: pulseScale,
|
||||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
scaleByDistance: new Cesium.NearFarScalar(1000, 1.5, 50000, 0.8)
|
scaleByDistance: new Cesium.NearFarScalar(1000, 1.5, 50000, 0.8)
|
||||||
},
|
},
|
||||||
// path: {
|
properties: {
|
||||||
// resolution: 1,
|
type: config.type === 'device' ? 'animatedDevice' : 'animatedSoldier',
|
||||||
// material: new Cesium.PolylineGlowMaterialProperty({
|
name: config.name,
|
||||||
// glowPower: 0.4,
|
department: config.department,
|
||||||
// taperPower: 0.5,
|
isAnimating: true
|
||||||
// color: trailColor
|
}
|
||||||
// }),
|
})
|
||||||
// width: 8,
|
|
||||||
// leadTime: 0,
|
console.log(`[useEntityAnimation] 创建${config.type === 'device' ? '设备' : '人员'}实体: ${config.name}`)
|
||||||
// trailTime: config.duration
|
return entity
|
||||||
// },
|
|
||||||
properties: {
|
} catch (error) {
|
||||||
type: config.type === 'device' ? 'animatedDevice' : 'animatedSoldier',
|
console.error('[useEntityAnimation] 创建移动实体失败:', error)
|
||||||
name: config.name,
|
return null
|
||||||
department: config.department,
|
}
|
||||||
isAnimating: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动多组移动动画(设备组 + 人员组2)
|
* 启动多组移动动画(设备组 + 人员组2)
|
||||||
* @param {Cesium.Viewer} viewer
|
* @param {Cesium.Viewer} viewer
|
||||||
@ -373,6 +377,9 @@ export function useEntityAnimation() {
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 先停止所有现有动画
|
||||||
|
stopAllMovements(viewer)
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
duration: options.duration ?? 60
|
duration: options.duration ?? 60
|
||||||
}
|
}
|
||||||
@ -382,17 +389,15 @@ export function useEntityAnimation() {
|
|||||||
const startTime = Cesium.JulianDate.now()
|
const startTime = Cesium.JulianDate.now()
|
||||||
const stopTime = Cesium.JulianDate.addSeconds(startTime, config.duration, new Cesium.JulianDate())
|
const stopTime = Cesium.JulianDate.addSeconds(startTime, config.duration, new Cesium.JulianDate())
|
||||||
|
|
||||||
|
// 配置 viewer 时钟
|
||||||
viewer.clock.startTime = startTime.clone()
|
viewer.clock.startTime = startTime.clone()
|
||||||
viewer.clock.stopTime = stopTime.clone()
|
viewer.clock.stopTime = stopTime.clone()
|
||||||
viewer.clock.currentTime = startTime.clone()
|
viewer.clock.currentTime = startTime.clone()
|
||||||
viewer.clock.clockRange = Cesium.ClockRange.CLAMPED // 动画到达终点后停止,不循环
|
viewer.clock.clockRange = Cesium.ClockRange.CLAMPED
|
||||||
viewer.clock.multiplier = 1
|
viewer.clock.multiplier = 1
|
||||||
viewer.clock.shouldAnimate = true
|
viewer.clock.shouldAnimate = true
|
||||||
|
|
||||||
// 清除之前的动画实体
|
// 确保实体数组是空的
|
||||||
animatedEntities.value.forEach(entity => {
|
|
||||||
if (entity) viewer.entities.remove(entity)
|
|
||||||
})
|
|
||||||
animatedEntities.value = []
|
animatedEntities.value = []
|
||||||
|
|
||||||
// 创建设备组移动实体
|
// 创建设备组移动实体
|
||||||
@ -400,31 +405,47 @@ export function useEntityAnimation() {
|
|||||||
duration: config.duration,
|
duration: config.duration,
|
||||||
type: 'device',
|
type: 'device',
|
||||||
name: '应急设备车',
|
name: '应急设备车',
|
||||||
department: '应急装备队'
|
department: '应急装备队',
|
||||||
|
disablePulse: options.disablePulse
|
||||||
}, startTime, stopTime)
|
}, startTime, stopTime)
|
||||||
animatedEntities.value.push(deviceEntity)
|
|
||||||
|
if (deviceEntity) {
|
||||||
|
animatedEntities.value.push(deviceEntity)
|
||||||
|
}
|
||||||
|
|
||||||
// 创建人员组2移动实体
|
// 创建人员组2移动实体
|
||||||
const personnel2Entity = createMovingEntity(viewer, PERSONNEL_PATH_COORDINATES_2, {
|
const personnel2Entity = createMovingEntity(viewer, PERSONNEL_PATH_COORDINATES_2, {
|
||||||
duration: config.duration,
|
duration: config.duration,
|
||||||
type: 'soldier',
|
type: 'soldier',
|
||||||
name: '应急救援队员',
|
name: '应急救援队员',
|
||||||
department: '应急救援队'
|
department: '应急救援队',
|
||||||
|
disablePulse: options.disablePulse
|
||||||
}, startTime, stopTime)
|
}, startTime, stopTime)
|
||||||
animatedEntities.value.push(personnel2Entity)
|
|
||||||
|
if (personnel2Entity) {
|
||||||
|
animatedEntities.value.push(personnel2Entity)
|
||||||
|
}
|
||||||
|
|
||||||
isAnimating.value = true
|
isAnimating.value = true
|
||||||
|
|
||||||
|
// 设置超时清理
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
console.log('[useEntityAnimation] 多组动画超时,强制清理')
|
||||||
|
stopAllMovements(viewer)
|
||||||
|
}, (config.duration + 5) * 1000) // 动画时长+5秒缓冲
|
||||||
|
|
||||||
const removeListener = viewer.clock.onStop.addEventListener(() => {
|
const removeListener = viewer.clock.onStop.addEventListener(() => {
|
||||||
console.log('[useEntityAnimation] 多组动画已结束')
|
console.log('[useEntityAnimation] 多组动画已结束')
|
||||||
|
clearTimeout(timeoutId)
|
||||||
isAnimating.value = false
|
isAnimating.value = false
|
||||||
removeListener()
|
removeListener()
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('[useEntityAnimation] 已启动 2 组额外移动动画')
|
console.log('[useEntityAnimation] 已启动 2 组移动动画')
|
||||||
return animatedEntities.value
|
return animatedEntities.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停止所有移动动画
|
* 停止所有移动动画
|
||||||
* @param {Cesium.Viewer} viewer
|
* @param {Cesium.Viewer} viewer
|
||||||
@ -432,25 +453,64 @@ export function useEntityAnimation() {
|
|||||||
const stopAllMovements = (viewer) => {
|
const stopAllMovements = (viewer) => {
|
||||||
if (!viewer) return
|
if (!viewer) return
|
||||||
|
|
||||||
|
console.log('[useEntityAnimation] 停止所有移动动画')
|
||||||
|
|
||||||
|
// 停止时钟动画
|
||||||
viewer.clock.shouldAnimate = false
|
viewer.clock.shouldAnimate = false
|
||||||
|
|
||||||
|
// 取消相机跟随
|
||||||
|
if (viewer.trackedEntity) {
|
||||||
|
viewer.trackedEntity = undefined
|
||||||
|
}
|
||||||
|
|
||||||
// 停止所有脉冲效果
|
// 停止所有脉冲效果
|
||||||
stopAllPulses(viewer)
|
stopAllPulses(viewer)
|
||||||
|
|
||||||
|
// 移除单个动画实体
|
||||||
if (animatedEntity.value) {
|
if (animatedEntity.value) {
|
||||||
viewer.entities.remove(animatedEntity.value)
|
try {
|
||||||
|
viewer.entities.remove(animatedEntity.value)
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[useEntityAnimation] 移除单个实体时出错:', e)
|
||||||
|
}
|
||||||
animatedEntity.value = null
|
animatedEntity.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 移除所有动画实体
|
||||||
animatedEntities.value.forEach(entity => {
|
animatedEntities.value.forEach(entity => {
|
||||||
if (entity) viewer.entities.remove(entity)
|
if (entity) {
|
||||||
|
try {
|
||||||
|
viewer.entities.remove(entity)
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[useEntityAnimation] 移除实体时出错:', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
animatedEntities.value = []
|
animatedEntities.value = []
|
||||||
|
|
||||||
|
// 额外清理:移除所有类型为 animatedSoldier 和 animatedDevice 的实体
|
||||||
|
const entitiesToRemove = []
|
||||||
|
viewer.entities.values.forEach(entity => {
|
||||||
|
const entityType = entity.properties?.type?.getValue?.()
|
||||||
|
if (entityType === 'animatedSoldier' || entityType === 'animatedDevice') {
|
||||||
|
entitiesToRemove.push(entity)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
entitiesToRemove.forEach(entity => {
|
||||||
|
try {
|
||||||
|
viewer.entities.remove(entity)
|
||||||
|
console.log('[useEntityAnimation] 清理残留实体:', entity.properties?.name?.getValue?.() || '未知')
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[useEntityAnimation] 清理残留实体时出错:', e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
isAnimating.value = false
|
isAnimating.value = false
|
||||||
console.log('[useEntityAnimation] 已停止所有移动动画')
|
console.log('[useEntityAnimation] 已停止所有移动动画,并清理残留实体')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据动态路线创建动画实体
|
* 根据动态路线创建动画实体
|
||||||
* @param {Cesium.Viewer} viewer
|
* @param {Cesium.Viewer} viewer
|
||||||
@ -508,13 +568,13 @@ export function useEntityAnimation() {
|
|||||||
const pulseScale = options.disablePulse
|
const pulseScale = options.disablePulse
|
||||||
? 1.0
|
? 1.0
|
||||||
: new Cesium.CallbackProperty((time) => {
|
: new Cesium.CallbackProperty((time) => {
|
||||||
if (!scaleState.isPulsing) {
|
if (!scaleState.isPulsing) {
|
||||||
return scaleState.fixedScale // 停止脉冲,返回固定值
|
return scaleState.fixedScale // 停止脉冲,返回固定值
|
||||||
}
|
}
|
||||||
|
|
||||||
const elapsed = Cesium.JulianDate.secondsDifference(time, startTime)
|
const elapsed = Cesium.JulianDate.secondsDifference(time, startTime)
|
||||||
return 1.0 + Math.sin(elapsed * 3) * 0.3
|
return 1.0 + Math.sin(elapsed * 3) * 0.3
|
||||||
}, false)
|
}, false)
|
||||||
|
|
||||||
// 选择图标和轨迹颜色
|
// 选择图标和轨迹颜色
|
||||||
const icon = route.type === 'equipment' ? deviceIcon : soldierIcon
|
const icon = route.type === 'equipment' ? deviceIcon : soldierIcon
|
||||||
@ -633,15 +693,26 @@ export function useEntityAnimation() {
|
|||||||
|
|
||||||
// 监听时钟,检测动画完成
|
// 监听时钟,检测动画完成
|
||||||
const clockListener = viewer.clock.onTick.addEventListener((clock) => {
|
const clockListener = viewer.clock.onTick.addEventListener((clock) => {
|
||||||
checkAnimationsCompletion(viewer, clock.currentTime, onEntityComplete)
|
checkAnimationsCompletion(viewer, clock.currentTime, (routeId, entity) => {
|
||||||
|
// 调用原有的路线清除回调
|
||||||
|
if (options.onEntityComplete) {
|
||||||
|
options.onEntityComplete(routeId)
|
||||||
|
}
|
||||||
|
|
||||||
// 注释掉自动停止时钟的逻辑,让时钟继续运行
|
// 延迟移除实体
|
||||||
// 原因:时钟停止会导致 Cesium 停止更新实体位置,导致前面完成的实体消失
|
setTimeout(() => {
|
||||||
// if (areAllAnimationsCompleted()) {
|
if (viewer && !viewer.isDestroyed() && entity) {
|
||||||
// console.log('[useEntityAnimation] 所有动画已完成,停止时钟')
|
viewer.entities.remove(entity)
|
||||||
// viewer.clock.shouldAnimate = false
|
console.log(`[useEntityAnimation] 动画完成,已移除实体`)
|
||||||
// clockListener() // 移除监听器
|
|
||||||
// }
|
// 从动画实体列表中移除
|
||||||
|
const index = animatedEntities.value.indexOf(entity)
|
||||||
|
if (index > -1) {
|
||||||
|
animatedEntities.value.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 1000) // 延迟1秒移除
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听动画结束
|
// 监听动画结束
|
||||||
@ -652,17 +723,69 @@ export function useEntityAnimation() {
|
|||||||
clockListener() // 移除 tick 监听器
|
clockListener() // 移除 tick 监听器
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 新增:60秒超时强制清除所有实体
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
console.log('[useEntityAnimation] 60秒超时,强制清除所有动画实体')
|
||||||
|
forceCleanupAllAnimations(viewer, options.onEntityComplete)
|
||||||
|
}, 60000) // 60秒超时
|
||||||
|
|
||||||
console.log(`[useEntityAnimation] 成功启动 ${animatedEntities.value.length} 个动画实体`)
|
console.log(`[useEntityAnimation] 成功启动 ${animatedEntities.value.length} 个动画实体`)
|
||||||
|
|
||||||
return animatedEntities.value
|
return animatedEntities.value
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查动画是否完成,如果完成则停止脉冲并清除路线
|
* 强制清理所有动画实体和路线
|
||||||
* @param {Cesium.Viewer} viewer
|
* @param {Cesium.Viewer} viewer
|
||||||
* @param {Cesium.JulianDate} currentTime
|
* @param {Function} onEntityComplete - 路线清除回调
|
||||||
* @param {Function} onEntityComplete - 完成回调 (routeId) => void
|
*/
|
||||||
*/
|
const forceCleanupAllAnimations = (viewer, onEntityComplete) => {
|
||||||
|
if (!viewer) return
|
||||||
|
|
||||||
|
// 停止时钟
|
||||||
|
viewer.clock.shouldAnimate = false
|
||||||
|
|
||||||
|
// 停止所有脉冲
|
||||||
|
stopAllPulses(viewer)
|
||||||
|
|
||||||
|
// 移除所有实体并触发回调
|
||||||
|
animatedEntities.value.forEach(entity => {
|
||||||
|
if (!entity || !entity.properties) return
|
||||||
|
|
||||||
|
const routeId = entity.properties.routeId?.getValue()
|
||||||
|
|
||||||
|
// 触发路线清除回调
|
||||||
|
if (onEntityComplete && typeof onEntityComplete === 'function' && routeId) {
|
||||||
|
console.log(`[useEntityAnimation] 超时清除路线: ${routeId}`)
|
||||||
|
onEntityComplete(routeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除实体
|
||||||
|
if (viewer && !viewer.isDestroyed()) {
|
||||||
|
viewer.entities.remove(entity)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 清空实体列表
|
||||||
|
animatedEntities.value = []
|
||||||
|
|
||||||
|
// 清除单个动画实体
|
||||||
|
if (animatedEntity.value) {
|
||||||
|
viewer.entities.remove(animatedEntity.value)
|
||||||
|
animatedEntity.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
isAnimating.value = false
|
||||||
|
console.log('[useEntityAnimation] 强制清理完成')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查动画是否完成,如果完成则停止脉冲、清除路线并移除实体
|
||||||
|
* @param {Cesium.Viewer} viewer
|
||||||
|
* @param {Cesium.JulianDate} currentTime
|
||||||
|
* @param {Function} onEntityComplete - 完成回调 (routeId, entity) => void
|
||||||
|
*/
|
||||||
const checkAnimationsCompletion = (viewer, currentTime, onEntityComplete) => {
|
const checkAnimationsCompletion = (viewer, currentTime, onEntityComplete) => {
|
||||||
animatedEntities.value.forEach(entity => {
|
animatedEntities.value.forEach(entity => {
|
||||||
if (!entity || !entity.properties) return
|
if (!entity || !entity.properties) return
|
||||||
@ -698,17 +821,25 @@ export function useEntityAnimation() {
|
|||||||
// 2. 标记为已完成(使用 ConstantProperty)
|
// 2. 标记为已完成(使用 ConstantProperty)
|
||||||
entity.properties.isCompleted = new Cesium.ConstantProperty(true)
|
entity.properties.isCompleted = new Cesium.ConstantProperty(true)
|
||||||
|
|
||||||
// 3. 触发回调清除对应路线
|
// 3. 触发回调清除对应路线,并传递实体信息以便移除
|
||||||
if (onEntityComplete && typeof onEntityComplete === 'function') {
|
if (onEntityComplete && typeof onEntityComplete === 'function') {
|
||||||
console.log(`[useEntityAnimation] 触发 onEntityComplete 回调,routeId: ${routeId}`)
|
console.log(`[useEntityAnimation] 触发 onEntityComplete 回调,routeId: ${routeId}`)
|
||||||
onEntityComplete(routeId)
|
onEntityComplete(routeId, entity) // 传递实体信息
|
||||||
} else {
|
} else {
|
||||||
console.warn(`[useEntityAnimation] onEntityComplete 回调不存在或不是函数`)
|
console.warn(`[useEntityAnimation] onEntityComplete 回调不存在或不是函数`)
|
||||||
|
// 如果没有回调,直接移除实体
|
||||||
|
setTimeout(() => {
|
||||||
|
if (viewer && !viewer.isDestroyed()) {
|
||||||
|
viewer.entities.remove(entity)
|
||||||
|
console.log(`[useEntityAnimation] 已自动移除实体: ${entityName}`)
|
||||||
|
}
|
||||||
|
}, 1000) // 延迟1秒移除,确保动画完全结束
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停止所有实体的脉冲效果
|
* 停止所有实体的脉冲效果
|
||||||
* @param {Cesium.Viewer} viewer
|
* @param {Cesium.Viewer} viewer
|
||||||
@ -762,7 +893,9 @@ export function useEntityAnimation() {
|
|||||||
startMultipleAnimationsWithRoutes,
|
startMultipleAnimationsWithRoutes,
|
||||||
// 新增:脉冲控制方法
|
// 新增:脉冲控制方法
|
||||||
checkAnimationsCompletion,
|
checkAnimationsCompletion,
|
||||||
stopAllPulses
|
stopAllPulses,
|
||||||
|
// 新增:强制清理方法
|
||||||
|
forceCleanupAllAnimations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,45 +32,45 @@ export function useSimulatedMarkers() {
|
|||||||
const newMarkers = []
|
const newMarkers = []
|
||||||
|
|
||||||
// 1. Create 2 center markers (static, no animation)
|
// 1. Create 2 center markers (static, no animation)
|
||||||
const centerPersonnelCoords = applyRandomOffset(disasterCenter, 10, 30)
|
// const centerPersonnelCoords = applyRandomOffset(disasterCenter, 10, 30)
|
||||||
const centerPersonnel = viewer.entities.add({
|
// const centerPersonnel = viewer.entities.add({
|
||||||
position: Cesium.Cartesian3.fromDegrees(centerPersonnelCoords.lon, centerPersonnelCoords.lat, 0),
|
// position: Cesium.Cartesian3.fromDegrees(centerPersonnelCoords.lon, centerPersonnelCoords.lat, 0),
|
||||||
billboard: {
|
// billboard: {
|
||||||
image: soldierIcon,
|
// image: soldierIcon,
|
||||||
width: 36,
|
// width: 36,
|
||||||
height: 40,
|
// height: 40,
|
||||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||||
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
// disableDepthTestDistance: Number.POSITIVE_INFINITY
|
||||||
},
|
// },
|
||||||
properties: new Cesium.PropertyBag({
|
// properties: new Cesium.PropertyBag({
|
||||||
type: 'centerPersonnel',
|
// type: 'centerPersonnel',
|
||||||
name: '应急人员',
|
// name: '应急人员',
|
||||||
isSimulated: true,
|
// isSimulated: true,
|
||||||
isStatic: true
|
// isStatic: true
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
newMarkers.push(centerPersonnel)
|
// newMarkers.push(centerPersonnel)
|
||||||
|
|
||||||
const centerEquipmentCoords = applyRandomOffset(disasterCenter, 10, 30)
|
// const centerEquipmentCoords = applyRandomOffset(disasterCenter, 10, 30)
|
||||||
const centerEquipment = viewer.entities.add({
|
// const centerEquipment = viewer.entities.add({
|
||||||
position: Cesium.Cartesian3.fromDegrees(centerEquipmentCoords.lon, centerEquipmentCoords.lat, 0),
|
// position: Cesium.Cartesian3.fromDegrees(centerEquipmentCoords.lon, centerEquipmentCoords.lat, 0),
|
||||||
billboard: {
|
// billboard: {
|
||||||
image: deviceIcon,
|
// image: deviceIcon,
|
||||||
width: 36,
|
// width: 36,
|
||||||
height: 40,
|
// height: 40,
|
||||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||||
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
// disableDepthTestDistance: Number.POSITIVE_INFINITY
|
||||||
},
|
// },
|
||||||
properties: new Cesium.PropertyBag({
|
// properties: new Cesium.PropertyBag({
|
||||||
type: 'centerEquipment',
|
// type: 'centerEquipment',
|
||||||
name: '应急装备',
|
// name: '应急装备',
|
||||||
isSimulated: true,
|
// isSimulated: true,
|
||||||
isStatic: true
|
// isStatic: true
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
newMarkers.push(centerEquipment)
|
// newMarkers.push(centerEquipment)
|
||||||
|
|
||||||
// 2. Create 4 emergency point markers (will be animated later)
|
// 2. Create 4 emergency point markers (will be animated later)
|
||||||
emergencyPoints.slice(0, 2).forEach((point, index) => {
|
emergencyPoints.slice(0, 2).forEach((point, index) => {
|
||||||
|
|||||||
@ -41,7 +41,7 @@
|
|||||||
v-if="isCompareMode"
|
v-if="isCompareMode"
|
||||||
class="situational-awareness__sync-btn"
|
class="situational-awareness__sync-btn"
|
||||||
@click="toggleCameraSync"
|
@click="toggleCameraSync"
|
||||||
:text="isCameraSyncEnabled ? '同步' : '不同步'"
|
:text="isCameraSyncEnabled ? '同步灾前灾后实景' : '未同步灾前灾后实景'"
|
||||||
>
|
>
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
<!-- 灾前现场实景标签 - 在中间分割线左侧 -->
|
<!-- 灾前现场实景标签 - 在中间分割线左侧 -->
|
||||||
@ -1824,10 +1824,10 @@ provide("triggerJump", (duration = 5, height = 30) => {
|
|||||||
|
|
||||||
.situational-awareness__sync-btn {
|
.situational-awareness__sync-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 40%;
|
left: 32%;
|
||||||
top: 133px;
|
top: calc(var(--sa-header-height));
|
||||||
height: 31px;
|
height: 31px;
|
||||||
transform: translateX(calc(-100% - vw(10)));
|
|
||||||
pointer-events: auto; // 恢复按钮的交互能力
|
pointer-events: auto; // 恢复按钮的交互能力
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user