Cesium 流动飞线运动教程

📅 2026/7/12 9:59:45
Cesium 流动飞线运动教程
流动飞线运动 ·Flowing Line· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么Cesium Entity 高层实体 API效果说明本案例演示流动飞线运动效果基于 WebGL 实现「流动飞线运动」可视化效果附完整可运行源码核心用到 Cesium。建议先打开文首在线案例查看动态画面再对照下方源码逐步理解。核心概念Viewer聚合 Scene、Camera、Clock 与渲染循环是 Cesium 应用入口。Entity面向点线面/模型/标签的高层 API与 Primitive 相比更适合交互与属性驱动。阅读下方完整源码时建议从init/load/animate三条主线入手再深入 shader 与工具函数。实现步骤创建 Viewer配置地形/影像若案例需要并设置初始相机在requestAnimationFrame循环中更新状态并 renderCesium 为viewer.render或自动渲染代码要点import * as Cesium from cesiumimport { Color, defined, Event, Material, Property } from cesiumconst box document.getElementById(box)const viewer new Cesium.Viewer(box, {animation: false,//是否创建动画小器件左下角仪表baseLayerPicker: false,//是否显示图层选择器右上角图层选择按钮baseLayer: Cesium.ImageryLayer.fromProviderAsync(Cesium.ArcGisMapServerImageryProvider.fromUrl(GLOBAL_CONFIG.getLayerUrl())),fullscreenButton: false,//是否显示全屏按钮右下角全屏选择按钮timeline: false,//是否显示时间轴infoBox: false,//是否显示信息框})viewer._cesiumWidget._creditContainer.style.display noneviewer.clock.shouldAnimate true//定位北京 viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(116.41, 36.91, 10000000),orientation: {heading: Cesium.Math.toRadians(0),pitch: Cesium.Math.toRadians(-90),roll: 0}})/飞线材质类/ class PolylineTrailLinkMaterialProperty {constructor(image, color Color.WHITE, duration 1000) {this._definitionChanged new Event()this._color undefinedthis.color colorthis.duration durationthis._time new Date().getTime()this.image imageMaterial._materialCache.addMaterial(PolylineTrailLink, {fabric: {type: PolylineTrailLink,uniforms: {color: color.withAlpha(1.0),image: image,time: 0},source:czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material czm_getDefaultMaterial(materialInput); vec2 st materialInput.st; vec4 sampledColor texture(image, vec2(fract(3.0*st.s - time), st.t)); material.alpha sampledColor.a * color.a; material.diffuse (sampledColor.rgb color.rgb) / 2.0; return material; }},translucent: () true})}get isConstant() { return false }get definitionChanged() { return this._definitionChanged }getType(_) { return PolylineTrailLink }getValue(time, result) {if (!defined(result)) result {}result.color Property.getValueOrClonedDefault(this._color, time, Color.WHITE, result.color)result.image this.imageresult.time (new Date().getTime() - this._time) % this.duration / this.durationreturn result}equals(other) { return this other || Property.equals(this._color, other._color) }}// 生成一组飞线动画 [ [[116.41, 36.91], [130.40, 45.39]], [[116.41, 36.91], [114.11, 39.44]], [[116.41, 36.91], [109.62, 25.72]], [[116.41, 36.91], [121.48, 31.22]], [[116.41, 36.91], [13.78, 12.31]], [[116.41, 36.91], [74.12, 33.50]], ].forEach(([p1, p2]) createPlaneCurve(p1, p2))// 组合 function createPlaneCurve(p1, p2) {const { curvePoints } getGenerateCurve(p1, p2, { maxHeight: 100000 })setEntityAnimate(viewer, viewer.entities.add({model: {uri: FILE_HOST models/glb/plane.glb,minimumPixelSize: 40,maximumScale: 100}}), curvePoints)viewer.entities.add({polyline: {positions: curvePoints,width: 8,material: new PolylineTrailLinkMaterialProperty(FILE_HOST images/channels/line.webp, Cesium.Color.RED, 2000)}})}/生成曲线/ function getGenerateCurve(start, end, params {}) {const [startLongitude, startLatitude] startconst [endLongitude, endLatitude] endconst startCartographic Cesium.Cartographic.fromDegrees(startLongitude, startLatitude)const endCartographic Cesium.Cartographic.fromDegrees(endLongitude, endLatitude)const geodesic new Cesium.EllipsoidGeodesic(startCartographic, endCartographic)const curvePoints []for (let t 0; t 1; t (params.step || 0.01)) {const pointCartographic geodesic.interpolateUsingFraction(t)pointCartographic.height (params.maxHeight || 400000)Math.sin(Math.PIt)const pointCartesian Cesium.Cartographic.toCartesian(pointCartographic)curvePoints.push(pointCartesian)}endCartographic.height 0const endPointCartesian Cesium.Cartographic.toCartesian(endCartographic)curvePoints.push(endPointCartesian)function getCurvePointAtTime(t) {const pointCartographic geodesic.interpolateUsingFraction(t)pointCartographic.height (params.maxHeight || 400000)Math.sin(Math.PIt)return Cesium.Cartographic.toCartesian(pointCartographic)}return { curvePoints, getCurvePointAtTime }}/飞行动画/ function setEntityAnimate(viewer, entity, curvePoints, params {}) {const start Cesium.JulianDate.fromDate(new Date()) // 设置起始时间const speedFactor params.speed || 20; // 增大这个值会让飞机飞得更快减小这个值会让飞机飞得更慢let stop Cesium.JulianDate.addSeconds(start, curvePoints.length / speedFactor, new Cesium.JulianDate())function setProperty(t1, t2) {const property new Cesium.SampledPositionProperty()for (let i 0; i curvePoints.length; i) property.addSample(Cesium.JulianDate.addSeconds(t1, i / speedFactor, new Cesium.JulianDate()), curvePoints[i])entity.position propertyentity.orientation new Cesium.VelocityOrientationProperty(property)entity.availability new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: t1, stop: t2 })])}setProperty(start, stop)// 监听飞机的位置属性当飞机到达终点时重新设置位置属性 viewer.clock.onTick.addEventListener(function (clock) {if (Cesium.JulianDate.compare(clock.currentTime, stop) 0) {const newStart Cesium.JulianDate.clone(stop);stop Cesium.JulianDate.addSeconds(newStart, curvePoints.length / speedFactor, new Cesium.JulianDate());setProperty(newStart, stop)}})}完整源码GitHub小结本文提供流动飞线运动完整 Cesium.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Cesium.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库