Cesium 8 ,在 Cesium 上實現雷達動畫和車輛動畫效果,并控制顯示和隱藏

?

目錄

?

?前言

一、功能背景

1.1 核心功能概覽

1.2 技術棧與工具

二、車輛動畫

2.1 模型坐標

2.2 組合渲染

2.3 顯隱狀態

2.4 模型文件

三、雷達動畫

3.1 創建元素

3.2 動畫解析

3.3?坐標聯動

3.4?交互事件

四、完整代碼

4.1 屬性參數

4.2 邏輯代碼

加載車輛動畫

控制車輛動畫

加載雷達動畫

控制雷達動畫

4.3 模擬展示

五、注意事項

5.1 資源加載與路徑問題

5.2 性能與內存管理

5.3 兼容性與調試

六、本文總結

七、更多操作

?

?

?前言

在《Cesium 7,在 Cesium 上實現高速道路渲染》中,我們完成了高速道路的三維建模與場景搭建。本文作為續篇,將聚焦于動態元素與交互邏輯的開發,在已構建的道路場景中疊加雷達動畫與車輛模型,實現 “靜態場景 + 動態實體” 的完整可視化方案。通過本文分享,你將學會如何在 Cesium 道路場景中集成動態交互元素,并掌握坐標轉換、動畫控制與狀態管理的核心技術。


?

一、功能背景

功能實現效果與技術架構

1.1 核心功能概覽

  1. 車輛模型系統:加載 GLB 格式 3D 車輛模型,附帶標簽文本與動態擴散波紋,模擬救援車輛的實時位置。
  2. 雷達動畫系統:基于 HTML+CSS 實現圓形波紋擴散效果,綁定經緯度坐標,支持點擊交互觸發事件彈窗。
  3. 交互控制:通過統一接口切換元素顯隱狀態,結合 Cesium 坐標轉換實現動畫元素與地圖視圖的動態聯動。

1.2 技術棧與工具

  • 框架:CesiumJS(三維渲染引擎)、JavaScript(邏輯控制)。
  • 資源格式:GLB(3D 模型)、CSS3(動畫樣式)。
  • 關鍵 API
    1. Cesium.Cartesian3.fromDegrees:經緯度轉笛卡爾坐標。
    2. viewer.entities.add:添加模型、標簽、波紋等實體。
    3. CallbackProperty:動態更新橢圓波紋的半徑與透明度。

?


?

二、車輛動畫

車輛模型動畫開發詳解

2.1 模型坐標

模型加載與坐標計算

代碼實現

loadVehicleModelAnime() {// 初始經緯度(車輛位置)const initLng = this.RealCarLonLat.lon;const initLat = this.RealCarLonLat.lat;// 移動距離與地球半徑(用于坐標偏移計算)const moveDistance = 20; // 20米const earthRadius = 6371000; // 地球半徑(米)// 計算偏移量(簡化版航向角為0°,僅水平移動)const deltaLat = (moveDistance / earthRadius) * Math.cos(0);const deltaLng = (moveDistance / (earthRadius * Math.cos(Cesium.Math.toRadians(initLat)))) * Math.sin(0);const newLat = initLat + Cesium.Math.toDegrees(deltaLat);const newLng = initLng + Cesium.Math.toDegrees(deltaLng);// 目標位置(笛卡爾坐標)const targetPosition = Cesium.Cartesian3.fromDegrees(newLng, newLat, 0);// ... 后續模型實體創建代碼
}

原理說明

  1. 坐標偏移邏輯:通過球面幾何公式計算車輛在平面地圖上的偏移量,deltaLat?和?deltaLng?分別對應緯度和經度方向的位移弧度,最終轉換為度數生成目標坐標。
  2. 航向角擴展:若需車輛朝向動態變化,可將?heading?參數與車輛實時航向數據綁定(如?vehicleHeading),通過?HeadingPitchRollQuaternion?動態更新模型朝向。

2.2 組合渲染

多實體組合渲染

組件拆解

實體類型技術實現關鍵屬性 / 配置
車輛模型viewer.entities.add?+?model?屬性uri: "/glb/8jc.glb"scale: 1
標簽文本label?實體紅色填充 + 白色描邊,pixelOffset: [0, -30]
擴散波紋3 層?ellipse?實體,通過?CallbackProperty?動態更新半徑與透明度semiMajorAxis/semiMinorAxis?隨時間線性增長

波紋動畫核心代碼

for (let i = 0; i < waveCount; i++) {const startTime = Date.now() + i * waveInterval; // 每層波紋延遲1秒啟動const waveEntity = viewer.entities.add({position: targetPosition,ellipse: {semiMajorAxis: new Cesium.CallbackProperty(() => {const elapsed = (Date.now() - startTime) % (waveCount * waveInterval);return 10 + 2000 * (elapsed / (waveCount * waveInterval)); // 從10米擴展到2010米}, false),material: new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(() => {const alpha = 1.0 - (Date.now() - startTime) / (waveCount * waveInterval);return Cesium.Color.RED.withAlpha(Math.max(0, alpha)); // 透明度線性衰減}, false))}});
}

2.3 顯隱狀態

顯隱狀態統一管理

toggleVehicleShowStatus() {if (!this.vehicleEntities || this.vehicleEntities.length === 0) return;this.vehicleVisible = !this.vehicleVisible;// 批量更新所有實體狀態this.vehicleEntities.forEach(entity => {entity.show = this.vehicleVisible;});
}
  • 設計模式:采用「實體數組管理」模式,將模型、標簽、波紋實體存入?vehicleEntities?數組,通過統一接口批量操作顯隱狀態,避免重復代碼。
  • 性能優化:隱藏時自動停止?CallbackProperty?的動態計算,減少無用渲染消耗。

2.4 模型文件

場景中加載的3D車輛模型文件,glb格式文件,見文章頂部。

?


?

三、雷達動畫

雷達動畫開發與交互邏輯

雷達動畫通過?HTML DOM 元素與?CSS3 關鍵幀動畫實現,具備輕量化、高性能的特點,可動態錨定地圖坐標并響應用戶交互。以下是基于代碼的詳細解析:

3.1 創建元素

基于 JavaScript 創建雷達容器與動畫元素

實現方式:通過?document.createElement?動態創建 HTML 元素,避免直接操作靜態 DOM,提升代碼動態性與可維護性。

DOM 結構生成邏輯

// 創建雷達容器(圓形定位容器)
const container = document.createElement("div");
container.className = "radar_container"; // 關聯CSS類
container.style.width = "200px";
container.style.height = "200px";
container.style.borderRadius = "50%"; // 圓形外觀
container.style.position = "absolute"; // 絕對定位,基于地圖視口坐標
container.style.zIndex = "999"; // 層級置頂,避免被地圖覆蓋

信息提示文本

const tip = document.createElement("div");
tip.innerText = `求助點位置:${this.realEventList.begMileageNo} - ${this.realEventList.endMileageNo}`;
tip.style.position = "absolute";
tip.style.bottom = "70%"; // 位于容器頂部
tip.style.left = "50%";
tip.style.transform = "translateX(-50%)"; // 水平居中
tip.style.color = "red";
tip.style.pointerEvents = "none"; // 允許鼠標事件穿透到地圖

實現效果,提示文本固定在雷達容器正上方,顯示事件位置信息,支持動態數據綁定(如?realEventList)。

雷達波紋元素

for (let i = 0; i < 3; i++) {const wave = document.createElement("div");wave.className = "radar_wave"; // 關聯CSS類// 基礎樣式:圓形邊框+陰影wave.style.width = "20px";wave.style.height = "20px";wave.style.border = "1px solid red";wave.style.borderRadius = "50%";wave.style.boxShadow = "inset 0 0 5px 1px red"; // 內陰影增強立體感// 定位與動畫設置wave.style.top = "50%";wave.style.left = "50%";wave.style.transformOrigin = "center center"; // 動畫中心點wave.style.animation = `radar_wave-animation 3s infinite`; // 引用關鍵幀動畫wave.style.animationDelay = `${i}s`; // 延遲啟動(0s/1s/2s),形成層次感
}

3.2 動畫解析

CSS 關鍵幀動畫解析

動畫定義方式:通過 JavaScript 動態向?head?標簽注入?<style>?標簽,避免全局樣式污染。

if (!document.getElementById("radar-wave-style")) {const style = document.createElement("style");style.id = "radar-wave-style";style.innerHTML = `@keyframes radar_wave-animation {0% {transform: translate(-50%, -50%) scale(0); /* 初始狀態:縮放為0,位于容器中心 */opacity: 1; /* 完全不透明 */}100% {transform: translate(-50%, -50%) scale(6); /* 最終狀態:縮放6倍,覆蓋容器范圍 */opacity: 0; /* 完全透明 */}}`;document.head.appendChild(style);
}

核心參數說明

屬性作用描述
transform: scale()控制波紋半徑擴展,scale(6)?表示從初始尺寸(20px)擴展至 120px(覆蓋 200px 容器)。
opacity實現波紋漸隱效果,避免動畫結束后殘留視覺痕跡。
animationDelay每層波紋延遲啟動,形成 “多層擴散” 的動態層次感(如第 1 層 0s 啟動,第 2 層 1s 啟動)。

3.3?坐標聯動

地圖坐標與屏幕坐標聯動

toggleRadarShowStatus() {if (this.radarVisible) {// 初始化坐標轉換this.radarPosition = Cesium.Cartesian3.fromDegrees(this.radarLonLat.lon, this.radarLonLat.lat);const canvasPos = viewer.scene.cartesianToCanvasCoordinates(this.radarPosition);// 定位DOM元素this.radarOverlayDom.style.left = `${canvasPos.x - 100}px`; // 水平居中(容器寬200px)this.radarOverlayDom.style.top = `${canvasPos.y - 100}px`;  // 垂直居中// 每幀更新位置(監聽場景預渲染事件)this.updateRadarPositionHandler = viewer.scene.preRender.addEventListener(() => {const pos = viewer.scene.cartesianToCanvasCoordinates(this.radarPosition);this.radarOverlayDom.style.left = `${pos.x - 100}px`;this.radarOverlayDom.style.top = `${pos.y - 100}px`;});} else {// 隱藏時移除監聽if (this.updateRadarPositionHandler) {viewer.scene.preRender.removeEventListener(this.updateRadarPositionHandler);this.updateRadarPositionHandler = null;}}
}

核心邏輯,通過?cartesianToCanvasCoordinates?將 Cesium 三維坐標轉換為瀏覽器視口坐標,確保雷達容器始終錨定在地圖指定位置,支持地圖縮放、平移時的實時跟隨。

3.4?交互事件

交互事件與信息展示

// 點擊雷達觸發事件彈窗
container.addEventListener("click", () => {this.EventDialogVisible = true; // 顯示Vue彈窗組件
});// 提示文本動態更新(示例)
const tip = document.createElement("div");
tip.innerText = `求助點坐標:${this.realEventList.begMileageNo} - ${this.realEventList.endMileageNo}`;

交互擴展,可結合 Vue/React 等前端框架實現彈窗數據綁定,展示事件詳情(如救援進度、預計到達時間)。

?


?

四、完整代碼

4.1 屬性參數

            // 雷達位置的經緯度坐標(地理坐標系)radarLonLat: {lon: 117.610995,lat: 34.399076,},// 雷達動畫顯示狀態控制radarVisible: false,// 雷達動畫的DOM容器引用(用于操作HTML元素)radarOverlayDom: null,// 雷達在Cesium中的三維坐標(笛卡爾坐標系)radarPosition: null,// 雷達位置更新事件句柄(用于綁定/移除渲染循環監聽)updateRadarPositionHandler: null,// 實際事件數據(存儲救援相關信息)// 救援車輛的初始經緯度坐標(地理坐標系)RealCarLonLat: {lon: 117.617227,lat: 34.324461,},

4.2 邏輯代碼

加載車輛動畫

        //? 加載車輛動畫,默認隱藏loadVehicleModelAnime() {// 獲取初始經緯度坐標const initLng = this.RealCarLonLat.lon;const initLat = this.RealCarLonLat.lat;// 車輛移動距離(米)const moveDistance = 20;// 地球半徑(米)const earthRadius = 6371000;// 初始朝向(0表示正北方向)const heading = 0;// 計算經緯度變化量(基于球面幾何)let deltaLat = (moveDistance / earthRadius) * Math.cos(heading);let deltaLng = (moveDistance / (earthRadius * Math.cos(this.Cesium.Math.toRadians(initLat)))) * Math.sin(heading);// 轉換為度數let newLat = initLat + this.Cesium.Math.toDegrees(deltaLat);let newLng = initLng + this.Cesium.Math.toDegrees(deltaLng);// 創建目標位置(Cartesian3坐標)const targetPosition = this.Cesium.Cartesian3.fromDegrees(newLng, newLat, 0);// 初始化車輛實體數組this.vehicleEntities = [];// 初始狀態為隱藏this.vehicleVisible = false;// 模型實體 - 加載3D車輛模型const vehicleModel = this.viewer.entities.add({name: "車輛模型",position: targetPosition,model: {uri: "/glb/8jc.glb", // 模型文件路徑scale: 1, // 初始縮放比例minimumPixelSize: 20, // 最小像素尺寸maximumScale: 40, // 最大縮放比例},// 設置模型朝向(航向角、俯仰角、滾轉角)orientation: this.Cesium.Transforms.headingPitchRollQuaternion(targetPosition,new this.Cesium.HeadingPitchRoll(this.Cesium.Math.toRadians(-170), // 航向角(-170度)this.Cesium.Math.toRadians(0),    // 俯仰角(0度)this.Cesium.Math.toRadians(0)     // 滾轉角(0度))),show: false // 初始不顯示});this.vehicleEntities.push(vehicleModel);// 標簽實體 - 顯示車輛名稱const labelEntity = this.viewer.entities.add({position: targetPosition,label: {text: "拯救車", // 標簽文字font: "14px sans-serif", // 字體樣式fillColor: this.Cesium.Color.RED, // 文字顏色outlineColor: this.Cesium.Color.WHITE, // 文字輪廓顏色outlineWidth: 1, // 輪廓寬度style: this.Cesium.LabelStyle.FILL_AND_OUTLINE, // 填充加輪廓樣式verticalOrigin: this.Cesium.VerticalOrigin.BOTTOM, // 文字垂直對齊底部pixelOffset: new this.Cesium.Cartesian2(0, -30), // 文字偏移量(向上偏移30像素)disableDepthTestDistance: Number.POSITIVE_INFINITY // 禁用深度測試},show: false // 初始不顯示});this.vehicleEntities.push(labelEntity);// 動態擴散波紋效果 - 創建多個波紋實體const waveCount = 3; // 波紋數量const waveInterval = 1000; // 波紋生成間隔(毫秒)for (let i = 0; i < waveCount; i++) {// 計算每個波紋的開始時間const startTime = Date.now() + i * waveInterval;const waveEntity = this.viewer.entities.add({position: targetPosition,ellipse: {// 動態橢圓長軸(隨時間變化)semiMajorAxis: new this.Cesium.CallbackProperty(() => {let elapsed = (Date.now() - startTime) % (waveCount * waveInterval);let scale = elapsed / (waveCount * waveInterval);return 10 + 2000 * scale; // 從10米逐漸擴大到2010米}, false),// 動態橢圓短軸(隨時間變化)semiMinorAxis: new this.Cesium.CallbackProperty(() => {let elapsed = (Date.now() - startTime) % (waveCount * waveInterval);let scale = elapsed / (waveCount * waveInterval);return 10 + 2000 * scale; // 從10米逐漸擴大到2010米}, false),// 動態顏色(透明度隨時間變化)material: new this.Cesium.ColorMaterialProperty(new this.Cesium.CallbackProperty(() => {let elapsed = (Date.now() - startTime) % (waveCount * waveInterval);let alpha = 1.0 - elapsed / (waveCount * waveInterval); // 從完全不透明到完全透明return this.Cesium.Color.RED.withAlpha(alpha); // 紅色漸變}, false)),height: 0, // 高度為0(貼地)outline: false, // 無輪廓classificationType: this.Cesium.ClassificationType.BOTH, // 貼地顯示},show: false // 初始不顯示});this.vehicleEntities.push(waveEntity);}},

控制車輛動畫

        // 控制車輛動畫顯示/隱藏狀態toggleVehicleShowStatus() {// 如果實體數組不存在或為空,則直接返回if (!this.vehicleEntities || this.vehicleEntities.length === 0) return;// 切換顯示狀態this.vehicleVisible = !this.vehicleVisible;// 遍歷所有車輛相關實體,統一設置顯示狀態this.vehicleEntities.forEach(entity => {entity.show = this.vehicleVisible;});},

這里的 loadVehicleModelAnime函數 用來創建車輛動畫,默認隱藏;toggleVehicleShowStatus函數 用來控制車輛動畫,首次執行,顯示車輛動畫,再次執行,隱藏車輛動畫,循環往復。

加載雷達動畫

        //? 創建雷達動畫,默認隱藏loadRadarLocationAnime() {// 如果雷達DOM已存在,則直接返回(避免重復創建)if (this.radarOverlayDom) return;// 創建雷達容器div(圓形居中布局)const container = document.createElement("div");container.className = "radar_container";// 設置樣式container.style.position = "absolute"; // 絕對定位container.style.width = "200px"; // 寬度container.style.height = "200px"; // 高度container.style.borderRadius = "50%"; // 圓形container.style.overflow = "visible"; // 允許內容溢出(顯示提示文字)container.style.pointerEvents = "auto"; // 允許鼠標事件container.style.zIndex = "999"; // 置于頂層container.style.display = "flex"; // 彈性布局container.style.alignItems = "center"; // 垂直居中container.style.justifyContent = "center"; // 水平居中container.style.cursor = "pointer"; // 鼠標懸停顯示手型container.style.margin = "auto"; // 自動外邊距container.style.border = "2px solid transparent"; // 默認透明邊框// 創建提示文字元素const tip = document.createElement("div");tip.innerText = `求助點位置:${this.realEventList.begMileageNo} - ${this.realEventList.endMileageNo}`; // 顯示求助點位置信息tip.style.textShadow = "2px 3px 1px black"; // 文字陰影效果tip.style.position = "absolute"; // 絕對定位tip.style.bottom = "70%"; // 放在容器底部上方tip.style.left = "50%"; // 水平居中tip.style.transform = "translateX(-50%)"; // 水平居中修正tip.style.padding = "2px 6px"; // 內邊距tip.style.font = "14pt"; // 字體大小tip.style.color = "red"; // 文字顏色tip.style.borderRadius = "4px"; // 圓角邊框tip.style.whiteSpace = "nowrap"; // 禁止換行tip.style.pointerEvents = "none"; // 不影響鼠標事件tip.style.userSelect = "none"; // 禁止文字選中tip.style.opacity = "1"; // 初始完全不透明tip.style.transition = "opacity 0.3s ease"; // 透明度過渡效果container.appendChild(tip); // 將提示文字添加到容器中// 添加點擊事件(點擊雷達顯示事件詳情對話框)container.addEventListener("click", () => {this.EventDialogVisible = true;});// 添加CSS關鍵幀動畫樣式(頁面只添加一次)if (!document.getElementById("radar-wave-style")) {const style = document.createElement("style");style.id = "radar-wave-style";style.innerHTML = `@keyframes radar_wave-animation {0% {transform: translate(-50%, -50%) scale(0); // 初始狀態:縮小到0opacity: 1; // 完全不透明}100% {transform: translate(-50%, -50%) scale(6); // 最終狀態:放大6倍opacity: 0; // 完全透明}}`;document.head.appendChild(style); // 將樣式添加到head中}// 創建3個雷達波紋div(依次延遲形成波紋效果)for (let i = 0; i < 3; i++) {const wave = document.createElement("div");wave.className = "radar_wave";// 設置波紋樣式wave.style.position = "absolute"; // 絕對定位wave.style.width = "20px"; // 寬度wave.style.height = "20px"; // 高度wave.style.border = "1px solid red"; // 紅色邊框wave.style.borderRadius = "50%"; // 圓形wave.style.boxShadow = "inset 0 0 5px 1px red"; // 內陰影效果wave.style.top = "50%"; // 垂直居中wave.style.left = "50%"; // 水平居中wave.style.transformOrigin = "center center"; // 變換中心點wave.style.transform = "translate(-50%, -50%) scale(0)"; // 初始縮小到0wave.style.animation = `radar_wave-animation 3s infinite`; // 應用動畫wave.style.animationDelay = `${i}s`; // 依次延遲(0s, 1s, 2s)container.appendChild(wave); // 將波紋添加到容器中}this.radarOverlayDom = container; // 緩存雷達DOMthis.viewer.container.appendChild(container); // 將雷達添加到Cesium容器中},

控制雷達動畫

        // 控制雷達動畫顯示/隱藏狀態toggleRadarShowStatus() {// 如果雷達DOM不存在,則先創建if (!this.radarOverlayDom) {this.loadRadarLocationAnime();}// 切換顯示狀態this.radarVisible = !this.radarVisible;if (this.radarVisible) {// 計算雷達對應的Cesium笛卡爾坐標(緩存)this.radarPosition = Cesium.Cartesian3.fromDegrees(this.radarLonLat.lon,this.radarLonLat.lat);// 首次設置雷達位置const canvasPos = this.viewer.scene.cartesianToCanvasCoordinates(this.radarPosition);if (canvasPos) {// 計算DOM位置(居中顯示)this.radarOverlayDom.style.left = `${canvasPos.x - 100}px`; // 寬度的一半this.radarOverlayDom.style.top = `${canvasPos.y - 100}px`; // 高度的一半this.radarOverlayDom.style.display = "flex"; // 顯示雷達}// 注冊渲染循環監聽(每幀更新雷達位置)this.updateRadarPositionHandler = this.viewer.scene.preRender.addEventListener(() => {const updatedCanvasPos = this.viewer.scene.cartesianToCanvasCoordinates(this.radarPosition);if (updatedCanvasPos) {// 實時更新DOM位置,保持與Cesium場景同步this.radarOverlayDom.style.left = `${updatedCanvasPos.x - 100}px`;this.radarOverlayDom.style.top = `${updatedCanvasPos.y - 100}px`;}});} else {// 隱藏雷達并移除渲染循環監聽this.radarOverlayDom.style.display = "none";if (this.updateRadarPositionHandler) {this.updateRadarPositionHandler(); // 移除監聽this.updateRadarPositionHandler = null; // 清空引用}}},

這里的 loadRadarLocationAnime函數 用來創建雷達動畫,默認隱藏;toggleRadarShowStatus函數 用來控制雷達動畫,首次執行,顯示雷達動畫,再次執行,隱藏雷達動畫,循環往復。

4.3 模擬展示

事件組件

// 發送事件通知其他組件需要顯示雷達和車輛動畫
// 參數1: true 表示需要顯示動畫
// 參數2: this.realEventList 當前事件數據(如求助點位置等信息)
this.$bus.$emit('brotherEvent1', true, this.realEventList);// 發送事件通知其他組件需要隱藏雷達和車輛動畫
// 參數1: false 表示需要隱藏動畫
// 參數2: 未傳遞(此時參數2為undefined)
this.$bus.$emit('brotherEvent1', false);

地圖組件

        // 事件推送和動畫顯示// 監聽名為 'brotherEvent1' 的事件(來自兄弟組件或其他模塊)this.$bus.$on('brotherEvent1', (res, data) => {// 如果事件返回 true,表示需要顯示雷達和車輛動畫if (res) {// 立即更新事件數據(不需要延遲)this.realEventList = data;// 延遲 1 秒后執行以下操作(確保 DOM 已更新)setTimeout(() => {// 加載雷達動畫(如果尚未加載)this.loadRadarLocationAnime();// 顯示雷達動畫this.toggleRadarShowStatus();// 加載車輛模型動畫(如果尚未加載)this.loadVehicleModelAnime();// 顯示車輛模型動畫this.toggleVehicleShowStatus();}, 1000); // 延遲 1 秒執行// 如果事件返回 false,表示需要隱藏雷達和車輛動畫} else if (res === false) {// 隱藏雷達動畫this.toggleRadarShowStatus();// 隱藏車輛模型動畫this.toggleVehicleShowStatus();}});

這里通過事件組件的 WebSocket 推流數據狀態和 EventBus 通信控制動畫顯示/隱藏:當收到?brotherEvent1(true, data)?時,更新事件數據并延遲1秒加載雷達和車輛動畫;收到?brotherEvent1(false)?時直接隱藏動畫;根據需求自行更改。

?


?

五、注意事項

注意事項與優化建議

5.1 資源加載與路徑問題

  • 模型路徑:確保 GLB 文件路徑正確(如?uri: "/static/glb/8jc.glb"),避免跨域問題(可配置服務器 CORS 或使用相對路徑)。本文代碼里的 uri: "/glb/8jc.glb", 模型文件是放在public文件下的。

5.2 性能與內存管理

  1. 實體清理:使用?viewer.entities.removeAll()?銷毀不再需要的車輛實體,避免內存泄漏。
  2. 動畫頻率:雷達波紋?waveInterval?建議設為 500-1000ms,過短會導致 CPU 占用過高;車輛波紋?waveCount?不建議超過 5 層。

5.3 兼容性與調試

  1. 瀏覽器支持:Cesium 依賴 WebGL 2.0,需確保用戶瀏覽器支持(可添加?webgl-lint?庫進行檢測)。
  2. 坐標調試:通過?console.log(canvasPos)?打印屏幕坐標,輔助定位雷達偏移問題;使用 Cesium 調試工具?viewer.scene.debugShowFramesPerSecond = true?監控幀率變化。

?


?

六、本文總結

本文總結與擴展方向

擴展方向

本文通過 Cesium 實體系統與 HTML 動畫結合,實現了車輛與雷達的動態交互效果。實際項目中可進一步擴展:

  1. 數據驅動:接入 WebSocket 實時更新車輛位置與雷達事件數據。
  2. 視覺增強:為車輛模型添加燈光效果(ModelStyle),雷達波紋支持多顏色漸變。
  3. 交互升級:實現鼠標懸停時車輛信息彈窗、雷達波紋點擊縮放等高級功能。

延伸閱讀

  • Cesium 7 原文鏈接(含高速道路完整代碼)
  • Cesium 官方模型加載文檔
  • CSS3 動畫性能優化指南

通過兩篇文章的結合,可構建從 “基礎場景→動態交互→業務邏輯” 的完整 Cesium 可視化能力,適用于智慧交通、數字孿生等復雜場景開發。

本文圍繞 Cesium 中動態元素的核心需求,詳細講解了車輛模型與雷達動畫的完整實現流程,涵蓋坐標計算、實體渲染、交互控制及性能優化。結合前篇道路場景開發,可構建 “靜態場景 + 動態交互” 的完整可視化方案,適用于智慧交通、應急救援等領域。完整項目代碼可通過留言、私信作者獲取,歡迎一起交流探討 Cesium 開發技巧!

?


?

七、更多操作

請看,CesiumJS Develop?個人專欄

CesiumJShttps://blog.csdn.net/weixin_65793170/category_12356611.html https://blog.csdn.net/weixin_65793170/category_12356611.html

?

?

?

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82264.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82264.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82264.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

相機--相機標定

教程 相機標定分類 相機標定分為內參標定和外參標定。 內參標定 目的 作用 原理 外參標定

JS手寫代碼篇---手寫類型判斷函數

9、手寫類型判斷函數 手寫完成這個函數&#xff1a;輸入一個對象(value)&#xff0c;返回它的類型 js中的數據類型&#xff1a; 值類型&#xff1a;String、Number、Boolean、Null、Undefied、Symbol引用類型&#xff1a;Object、Array、Function、RegExp、Date 使用typeOf…

量子物理:初步認識量子物理

核心特點——微觀世界與宏觀世界的差異 量子物理(又稱量子力學)是物理學中描述微觀世界(原子、電子、光子等尺度)基本規律的理論框架。它與我們熟悉的經典物理(牛頓力學、電磁學等)有根本性的不同,因為微觀粒子的行為展現出許多奇特且反直覺的現象。 簡單來說,量子物…

springboot配置cors攔截器與cors解釋

文章目錄 cors?代碼 cors? CORS&#xff08;跨域資源共享&#xff09;的核心機制是 由后端服務器&#xff08;bbb.com&#xff09;決定是否允許前端&#xff08;aaa.com&#xff09;的跨域請求 當瀏覽器訪問 aaa.com 的頁面&#xff0c;并向 bbb.com/list 發起請求時&#…

國芯思辰| 同步降壓轉換器CN2020應用于智能電視,替換LMR33620

在智能電視不斷向高畫質、多功能、智能化發展的當下&#xff0c;其內部電源管理系統的性能至關重要。同步降壓轉換器可以為智能電視提供穩定、高效的運行。 國芯思辰CN2020是一款脈寬調制式同步降壓轉換器。內部集成兩個功率MOS管&#xff0c;在4.5~18V寬輸入電壓范圍內可以持…

API 版本控制:使用 ABP vNext 實現版本化 API 系統

&#x1f680;API 版本控制&#xff1a;使用 ABP vNext 實現版本化 API 系統 &#x1f4da; 目錄 &#x1f680;API 版本控制&#xff1a;使用 ABP vNext 實現版本化 API 系統一、背景切入 &#x1f9ed;二、核心配置規則 &#x1f4cb;2.1 前置準備&#xff1a;NuGet 包與 usi…

Android高級開發第四篇 - JNI性能優化技巧和高級調試方法

文章目錄 Android高級開發第四篇 - JNI性能優化技巧和高級調試方法引言為什么JNI性能優化如此重要&#xff1f;第一部分&#xff1a;JNI性能基礎知識JNI調用的性能開銷何時使用JNI才有意義&#xff1f; 第二部分&#xff1a;核心性能優化技巧1. 減少JNI調用頻率2. 高效的數組操…

小白的進階之路系列之十----人工智能從初步到精通pytorch綜合運用的講解第三部分

本文將介紹Autograd基礎。 PyTorch的Autograd特性是PyTorch靈活和快速構建機器學習項目的一部分。它允許在一個復雜的計算中快速而簡單地計算多個偏導數(也稱為梯度)。這個操作是基于反向傳播的神經網絡學習的核心。 autograd的強大之處在于它在運行時動態地跟蹤你的計算,…

43. 遠程分布式測試實現

43. 遠程分布式測試實現詳解 一、遠程測試環境配置 1.1 遠程WebDriver服務定義 # Chrome瀏覽器遠程服務地址 chrome_url rhttp://localhost:5143# Edge瀏覽器遠程服務地址 edge_url rhttp://localhost:9438關鍵概念&#xff1a;每個URL對應一個獨立的WebDriver服務典型配置…

Python爬蟲(40)基于Selenium與ScrapyRT構建高并發動態網頁爬蟲架構:原理、實現與性能優化

目錄 一、引言二、技術背景1. 動態頁面處理痛點2. 架構設計目標 三、核心組件詳解1. Selenium Grid集群部署2. ScrapyRT服務化改造3. 智能等待策略 四、系統架構圖五、性能優化實踐1. 資源隔離策略2. 并發控制算法3. 監控體系 六、總結與展望&#x1f308;Python爬蟲相關文章&a…

【存儲基礎】SAN存儲基礎知識

文章目錄 1. 什么是SAN存儲&#xff1f;2. SAN存儲組網架構3. SAN存儲的主要協議SCSI光纖通道&#xff08;FC&#xff09;協議iSCSIFCoENVMe-oFIB 4. SAN存儲的關鍵技術Thin Provision&#xff1a;LUN空間按需分配Tier&#xff1a;分級存儲Cache&#xff1a;緩存機制QoS&#x…

TDengine 運維——巡檢工具(定期檢查)

背景 TDengine 在運行一段時間后需要針對運行環境和 TDengine 本身的運行狀態進行定期巡檢&#xff0c;本文檔旨在說明如何使用巡檢工具對 TDengine 的運行環境進行自動化檢查。 安裝工具使用方法 工具支持通過 help 參數查看支持的語法 Usage: taosinspect [OPTIONS]Check…

DHCP應用

一、DHCP介紹 在LAN(局域網)中我們常會遇到以下的情況&#xff1a; 1.不知道如何配置IP地址及相關信息的員工&#xff0c;無法上網&#xff1b;2.IP地址配置沖突&#xff0c;無法上網&#xff1b;3.來訪用戶因不熟悉公司網絡情況無法上網&#xff1b; 以上這些情況都是日常最…

LabVIEW多按鍵自動化檢測系統

LabVIEW開發一套高精度按鍵力與行程自動化檢測系統&#xff0c;針對傳統檢測設備自動化程度低、定位誤差大等痛點&#xff0c;實現多按鍵產品的全流程自動化測試。系統集成 6 軸工業機器人、高精度傳感器及實時數據處理模塊&#xff0c;滿足汽車電子、消費電子等領域對按鍵手感…

嵌入式硬件篇---蜂鳴器

蜂鳴器是一種常用的電子發聲元件&#xff0c;主要分為有源蜂鳴器和無源蜂鳴器兩類。它們在結構、工作原理、驅動方式、應用場景等方面存在顯著差異。以下是詳細介紹&#xff1a; 一、核心定義與結構差異 1. 有源蜂鳴器 定義&#xff1a; “有源” 指內部自帶振蕩電路&#x…

600+純CSS加載動畫一鍵獲取指南

CSS-Loaders.com 完整使用指南&#xff1a;600純CSS加載動畫庫 &#x1f3af; 什么是 CSS-Loaders.com&#xff1f; CSS-Loaders.com 是一個專門提供純CSS加載動畫的資源網站&#xff0c;擁有超過600個精美的單元素加載器。這個網站的最大特色是所有動畫都只需要一個HTML元素…

國內高頻混壓PCB廠家有哪些?

一、技術領先型廠商&#xff08;聚焦材料與工藝突破&#xff09; 獵板PCB 技術亮點&#xff1a;真空層壓工藝實現FR-4與羅杰斯高頻材料&#xff08;RO4350B/RO3003&#xff09;混壓&#xff0c;阻抗公差3%&#xff0c;支持64單元/板的5G天線模塊&#xff0c;插損降低15%。 應用…

volatile,synchronized,原子操作實現原理,緩存一致性協議

文章目錄 緩存一致性協議&#xff08;MESI&#xff09;volatile1. volatile 的作用2.volatile的底層實現3,volatile 實現單例模式的雙重鎖&#xff08;面手寫&#xff09; synchronized1,基本用法2,可重入性3,Java對象頭4,實現原理&#xff08;1&#xff09;代碼塊同步的實現&a…

webfuture:如何屏蔽后臺發文界面的保存為新文章按鈕?

問題描述&#xff1a; 如何屏蔽后臺發文界面的保存為新文章按鈕&#xff1f; 問題解決&#xff1a;修改這個文件 /Admin/Content/Base/css/base.css 定義這個的id saveAsNewItemSubmit #saveAsNewItemSubmit{display: none;}

SpringBoot集成第三方jar的完整指南

原文地址&#xff1a;https://blog.csdn.net/weixin_43826336/article/details/141640152?ops_request_misc%257B%2522request%255Fid%2522%253A%25227d4118ef2d572ba4428caf83f1d2bb28%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id7d4118…