Appearance
概述
粒子系统可以与前面的运动轨迹相互结合。
javascript
<script setup>
import { onMounted } from 'vue'
import * as Cesium from 'cesium'
import smoke from './assets/smoke.png'
window.CESIUM_BASE_URL = '/Cesium'
Cesium.Ion.defaultAccessToken = ''
const GD_TOKEN = ''
const origin = '116.310003,39.991957'
const destination = '116.434446,39.90816'
const url = `https://restapi.amap.com/v5/direction/driving?key=${GD_TOKEN}&origin=${origin}&destination=${destination}&show_fields=polyline`
const drivingData = []
onMounted(async () => {
const viewer = new Cesium.Viewer('cesiumContainer')
const response = await fetch(url)
const data = await response.json()
data.route.paths[0].steps.forEach((step) => {
const result = step.polyline.split(';').map((item) => {
const [lng, lat] = item.split(',')
return {
longitude: Number(lng),
latitude: Number(lat),
height: 0
}
})
drivingData.push(...result)
})
// console.log(drivingData)
const timeStepInSeconds = 30
const totalSeconds = timeStepInSeconds * (drivingData.length - 1)
const start = Cesium.JulianDate.fromIso8601("2020-03-09T23:10:00Z")
const stop = Cesium.JulianDate.addSeconds(start, totalSeconds, new Cesium.JulianDate())
viewer.clock.startTime = start.clone()
viewer.clock.stopTime = stop.clone()
viewer.clock.currentTime = start.clone()
viewer.timeline.zoomTo(start, stop)
viewer.clock.multiplier = 20
viewer.clock.shouldAnimate = true // 也可以在配置中设置shouldAnimate
const positionProperty = new Cesium.SampledPositionProperty()
for (let i = 0; i < drivingData.length; i++) {
const dataPoint = drivingData[i]
const time = Cesium.JulianDate.addSeconds(start, i * timeStepInSeconds, new Cesium.JulianDate())
const position = Cesium.Cartesian3.fromDegrees(dataPoint.longitude, dataPoint.latitude, dataPoint.height)
positionProperty.addSample(time, position)
}
const airplaneEntity = viewer.entities.add({
availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: start, stop: stop })]),
position: positionProperty,
model: {
uri: '/models/plane2.glb',
scale: 1,
},
// 自动朝向前进方向
orientation: new Cesium.VelocityOrientationProperty(positionProperty),
path: new Cesium.PathGraphics({ width: 3 }),
viewFrom: new Cesium.Cartesian3(0, -2000, 2000)
})
viewer.trackedEntity = airplaneEntity
const emitterModelMatrix = new Cesium.Matrix4()
const translation = new Cesium.Cartesian3()
const rotation = new Cesium.Quaternion()
let hpr = new Cesium.HeadingPitchRoll()
const trs = new Cesium.TranslationRotationScale()
function computeEmitterModelMatrix() {
hpr = Cesium.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, hpr)
trs.translation = Cesium.Cartesian3.fromElements(-10.0, 0.0, 1.4, translation)
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr, rotation)
return Cesium.Matrix4.fromTranslationRotationScale(trs, emitterModelMatrix)
}
const particleSystem = viewer.scene.primitives.add(
new Cesium.ParticleSystem({
image: smoke,
imageSize: new Cesium.Cartesian2(5.0, 5.0),
emissionRate: 5.0,
minimumParticleLife: 3.2,
maximumParticleLife: 8.2,
minimumSpeed: 1,
maximumSpeed: 4,
startScale: 1.0,
endScale: 5.0,
emitter: new Cesium.CircleEmitter(2.0),
emitterModelMatrix: computeEmitterModelMatrix(),
lifetime: 16.0,
})
)
viewer.scene.preUpdate.addEventListener(function (scene, time) {
particleSystem.modelMatrix = airplaneEntity.computeModelMatrix(time, new Cesium.Matrix4())
particleSystem.emitterModelMatrix = computeEmitterModelMatrix()
})
})
</script>
<template>
<div id="cesiumContainer"></div>
</template>
<style scoped>
#cesiumContainer {
position: absolute;
inset: 0;
}
</style>