動畫實現方式通過多個canvas實現,參考的https://www.yueyanshaosun.cn/ysCesium/views/5_geometricObj2_entityCanvas.html
探測效果實現步驟:
1、創建Cylinder圓錐體;
2、設置材質的貼圖為動態屬性,實現動態探測,但方向不變;
3、動態修改圓錐體長度length、位置position、朝向orientation,讓圓錐體沿着頂點動起來;
4、去掉底部的紋理貼圖,修改了cesium的源碼實現。
第4步請教cesiumlab群,圓錐體是包含底面的,沒有參數可以修改,只能動源碼了,涉及的類包括:Core/CylinderGeometry.js、DataSources/CylinderGraphics,js、DataSources/CylinderGeometryUpdater.js
實現代碼如下:
html部分:
1 <div id="cesiumContainer"></div> 2 <canvas id="canvas-a" width="400px" height="400px"></canvas> 3 <canvas id="canvas-b" width="400px" height="400px"></canvas> 4 <canvas id="canvas-c" width="400px" height="400px"></canvas>
三個canvas也可以通過js代碼創建。
js部分:
1 Cesium.Ion.defaultAccessToken = ‘your token'; 2 var viewer = new Cesium.Viewer('cesiumContainer'); 3 viewer._cesiumWidget._creditContainer.style.display = "none"; 4 viewer.scene.debugShowFramesPerSecond = true; 5 6 //通過3個畫布交替切換實現探測紋理動態 7 var changenum = 0; 8 var curCanvas = 'a'; 9 10 function readyCanvas(convasid, radius) { 11 var canvas = document.getElementById(convasid); 12 let cwidth = 400; 13 let cheight = 400; 14 var ctx = canvas.getContext("2d"); 15 ctx.clearRect(0, 0, cwidth, cheight); 16 ctx.fillStyle = 'rgba(255, 255, 255, 0)'; 17 ctx.fillRect(0, 0, cwidth, cheight); 18 19 for (let ii = 0; radius <= 200; ii++) { 20 ctx.lineWidth = 5; 21 //開始一個新的繪制路徑 22 ctx.beginPath(); 23 //設置弧線的顏色 24 var trans = 1.0 - (radius / 255); 25 ctx.strokeStyle = "rgba(255, 0, 255, " + trans + ")"; 26 var circle = { 27 x: 200, //圓心的x軸坐標值 28 y: 200, //圓心的y軸坐標值 29 r: radius //圓的半徑 30 }; 31 //以canvas中的坐標點(200,200)為圓心,繪制一個半徑為50px的圓形 32 ctx.arc(circle.x, circle.y, circle.r, 0, Math.PI * 2, true); 33 //按照指定的路徑繪制弧線 34 ctx.stroke(); 35 radius += 20; 36 } 37 } 38 readyCanvas("canvas-a", 5); 39 readyCanvas("canvas-b", 10); 40 readyCanvas("canvas-c", 15); 41 42 function drawCanvasImage(time, result) { 43 changenum++; 44 var canvas = document.getElementById("canvas-" + curCanvas); 45 if (changenum >= 20) { 46 changenum = 0; 47 if (curCanvas === 'a') 48 curCanvas = 'b'; 49 else if (curCanvas === 'b') 50 curCanvas = 'c'; 51 else 52 curCanvas = 'a'; 53 } 54 return canvas; 55 } 56 //初始位置 57 var lon = -118.760842; 58 var lat = 38.132073; 59 var planePosition = Cesium.Cartesian3.fromDegrees(lon, lat, 3000.0) 60 //改變圓錐體位置,循環畫矩形 61 function changePosition() { 62 if (lon > -118.755842 && lat < 38.138073) { 63 lat += 0.00001; 64 } else if (lat > 38.138073 && lon > -118.760842) { 65 lon -= 0.00001; 66 } else if (lon <= -118.760842 && lat > 38.132074) { 67 lat -= 0.00001 68 } else { 69 lon += 0.00001; 70 } 71 72 planePosition = Cesium.Cartesian3.fromDegrees(lon, lat, 3000.0) 73 return planePosition 74 } 75 //根據圓錐中心點位置動態計算朝向、圓錐體長度 76 var geoD = new Cesium.EllipsoidGeodesic(); 77 //頂點經緯度 78 var startPt = Cesium.Cartographic.fromDegrees(-118.760842, 38.132073, 0); 79 80 function changeOrientation() { 81 //計算經度方向的夾角 82 var endX = Cesium.Cartographic.fromDegrees(lon, 38.132073, 0); 83 geoD.setEndPoints(startPt, endX); 84 var innerS = geoD.surfaceDistance; 85 var angleX = Math.atan(innerS / halfLen); 86 87 //計算圓錐體長度 88 var end = Cesium.Cartographic.fromDegrees(lon, lat, 0); 89 geoD.setEndPoints(startPt, end); 90 innerS = geoD.surfaceDistance; 91 length = Math.sqrt(innerS * innerS + halfLen * halfLen); 92 93 //計算緯度方向的夾角 94 var endY = Cesium.Cartographic.fromDegrees(-118.760842, lat, 0); 95 geoD.setEndPoints(startPt, endY); 96 innerS = geoD.surfaceDistance; 97 var angleY = Math.asin(innerS / length); 98 99 //計算朝向 100 var hpr = new Cesium.HeadingPitchRoll(0.0, angleX, angleY); 101 var orientation = Cesium.Transforms.headingPitchRollQuaternion(planePosition, hpr); 102 103 return orientation 104 } 105 var halfLen = 1000.0 106 var length = 1000.0; 107 108 function changeLength() { 109 return 2 * length; 110 } 111 //創建圓錐實體 112 var cylinder = viewer.entities.add({ 113 name: 'Red cone', 114 position: new Cesium.CallbackProperty(changePosition, false), 115 orientation: new Cesium.CallbackProperty(changeOrientation, false), 116 cylinder: { 117 length: new Cesium.CallbackProperty(changeLength, false), 118 topRadius: 0.0, 119 bottomRadius: 300.0, 120 //topSurface: false, //新增參數,控制頂部是否渲染 121 bottomSurface: false, //新增參數,控制底部是否渲染 122 material: new Cesium.ImageMaterialProperty({ 123 image: new Cesium.CallbackProperty(drawCanvasImage, false), 124 transparent: true 125 }) 126 } 127 }); 128 129 //定位到圓錐體 130 var initialPosition = Cesium.Cartesian3.fromDegrees(-118.760842, 38.089073, 8000); //相機視角三要素:朝向(左右偏移),傾斜(上下偏移),翻滾角度(相機視錐體中軸線旋轉角度) 131 var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(1.27879878293835, -51.34390550872461, 0.0716951918898415); 132 viewer.scene.camera.setView({ 133 destination: initialPosition, 134 orientation: initialOrientation, 135 endTransform: Cesium.Matrix4.IDENTITY 136 });
創建圓錐體時,將121、124行注釋,顯示效果如下:
若設置為透明的,即啟用124行,效果如下:
注意箭頭標示的地方,圓錐底部也被渲染紋理,修改源碼增加了兩個參數topSurface、bottomSurface用於支持關閉底部的渲染,最后結果如下: