一、源码
import type { Viewer, Primitive, Material } from "cesium";const cesiumUtils = {viewer: <Viewer | null>null,rainPrimitive: <Primitive | null>null,interValIndex: 0,playIndex: 1,//播放材质索引isPlayIng: false,isPauseIng: false,setStatus: (options: any): void => { },imgArr: <Array<string>>[],m4DataArr: <Array<Array<string>>>[],gridmaterial: new Cesium.Material({fabric: {type: Cesium.Material.GridType,uniforms: {color: new Cesium.Color(0.0, 1.0, 1.0, 1.0),cellAlpha: 0.1,lineCount: new Cesium.Cartesian2(8.0, 8.0),lineThickness: new Cesium.Cartesian2(1.0, 1.0),lineOffset: new Cesium.Cartesian2(0.0, 0.0),},},}),gradientColors: ["#FF0000", // 红色"#FF3333","#FF6666","#FF9999","#FFCCCC","#CCFFFF", // 淡蓝色"#99CCFF","#6699FF","#3366FF","#0000FF", // 蓝色 ],gradientColors2: ["rgba(0,0,255,0.1)","rgba(0,0,255,0.21)","rgba(0,0,255,0.3)","rgba(0,0,255,0.3)","rgba(0,255,255,0.9)","rgba(0,255,255,1)","rgba(0,255,255,1)","rgba(0,255,255,1)","rgba(0,255,255,0.1)","rgba(0,0,255,0.1)",],drawMesh(dataArr: Array<string>) {const baseInfo = dataArr[0].split(" ");const width = Number(baseInfo[16]) - 1;const height = Number(baseInfo[17]) - 1;let startLon = Number(baseInfo[12]);let endLon = Number(baseInfo[13]);let startLat = Number(baseInfo[14]);let endLat = Number(baseInfo[15]);let isNumber = 2;const canvas = document.createElement("canvas");canvas.width = width * isNumber;canvas.height = height * isNumber;let ctx = canvas.getContext("2d") as CanvasRenderingContext2D;this.imgArr = []for (let i = 0; i < width; i++) {for (let j = 0; j < height; j++) {const startX = i * isNumber;const startY = j * isNumber;let color = "rgba(128,128,128,0.3)"if (Math.random() < 0.95) {color = "rgba(128,128,128,0.3)"} else {color = "rgba(128,128,128,1)"}// this.gradientColors[Number((Math.sin(index)).toFixed(0))];ctx.fillStyle = color;ctx.fillRect(startX, startY, isNumber, isNumber);}}let img = canvas.toDataURL("image/png");this.imgArr.push(img)let instance = new Cesium.GeometryInstance({geometry: new Cesium.RectangleGeometry({rectangle: Cesium.Rectangle.fromDegrees(startLon,startLat,endLon,endLat),vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,}),});let rectangleAppearance = new Cesium.EllipsoidSurfaceAppearance({material: Cesium.Material.fromType("Image", {image: img,}),});let viewer = this.viewer as Viewerthis.rainPrimitive = viewer.scene.primitives.add(new Cesium.GroundPrimitive({geometryInstances: instance,appearance: rectangleAppearance,}));},setMateiral(dataArr: Array<string>) {const baseInfo = dataArr[0].split(" ");const width = Number(baseInfo[16]) - 1;const height = Number(baseInfo[17]) - 1;let isNumber = 2;const canvas = document.createElement("canvas");canvas.width = width * isNumber;canvas.height = height * isNumber;let ctx = canvas.getContext("2d") as CanvasRenderingContext2D;for (let i = 0; i < width; i++) {for (let j = 0; j < height; j++) {const startX = i * isNumber;const startY = j * isNumber;let color = "rgba(128,128,128,0.3)"if (Math.random() < 0.95) {color = "rgba(128,128,128,0.3)"} else {color = "rgba(128,128,128,1)"}// this.gradientColors[Number((Math.sin(index)).toFixed(0))];ctx.fillStyle = color;ctx.fillRect(startX, startY, isNumber, isNumber);}}let img = canvas.toDataURL("image/png");this.imgArr.push(img);},setPrimitive(dataArr: Array<string>, firstFrame: string) {const baseInfo = dataArr[0].split(" ");let startLon = Number(baseInfo[12]);let endLon = Number(baseInfo[13]);let startLat = Number(baseInfo[14]);let endLat = Number(baseInfo[15]);let instance = new Cesium.GeometryInstance({geometry: new Cesium.RectangleGeometry({rectangle: Cesium.Rectangle.fromDegrees(startLon,startLat,endLon,endLat),vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,}),});let rectangleAppearance = new Cesium.MaterialAppearance({material: new Cesium.Material({fabric: {type: 'Image',uniforms: {image: firstFrame}}}),})let viewer = this.viewer as Viewerthis.rainPrimitive = viewer.scene.primitives.add(new Cesium.GroundPrimitive({geometryInstances: instance,appearance: rectangleAppearance,}));},updateMaterial(material: any) {let primitive = this.rainPrimitive as Primitiveprimitive.appearance.material.uniforms['image'] = material},startPlay(setStatus: (options: any) => void) {let that = this;this.isPlayIng = trueconsole.log(that.imgArr.length);if (this.imgArr.length > 0 && this.rainPrimitive != null) {this.interValIndex = setInterval(() => {const material = that.imgArr[that.playIndex];that.updateMaterial(material)that.playIndex = that.playIndex + 1console.log(that.playIndex);let options = {step: that.playIndex / that.imgArr.length,isPlayIng: this.isPlayIng,isPauseIng: this.isPauseIng}setStatus(options)this.setStatus = setStatusif (that.playIndex == that.imgArr.length) {clearInterval(this.interValIndex)}}, 3000)}},pauseOrPlay() {if (this.isPlayIng &&this.playIndex!=this.imgArr.length) {if (!this.isPauseIng) {clearInterval(this.interValIndex)this.isPauseIng = true;let options = {step: this.playIndex / this.imgArr.length,isPlayIng: this.isPlayIng,isPauseIng: this.isPauseIng}this.setStatus(options)} else {this.isPauseIng = falsethis.startPlay(this.setStatus)}}},async setM4Data(urlArr: Array<string>) {this.m4DataArr = [];for (let i = 0; i < urlArr.length; i++) {const element = urlArr[i];let m4Data = await getM4Data(element);this.m4DataArr.push(m4Data)}},async initBaseData(urlArrr: Array<string>, viewer: Viewer) {this.viewer = viewerawait this.setM4Data(urlArrr)this.m4DataArr.forEach(x => {this.setMateiral(x)})this.setPrimitive(this.m4DataArr[0], this.imgArr[0])return true;},restorePlay() {clearInterval(this.interValIndex);this.playIndex = 1this.isPlayIng = false;this.isPauseIng = falseif (this.rainPrimitive != null) {this.viewer?.scene.primitives.remove(this.rainPrimitive)this.rainPrimitive = null}this.setStatus({isPauseIng: false,isPlayIng: false,step: 0})} };//获取最大值 function geRenderData(dataArr: any) {let maxValue = 0;let renderData = []for (let i = 1; i < dataArr.length; i++) {const element = dataArr[i];const tmpArr = element.trim().split(" ")let rowArr = []for (let j = 0; j < tmpArr.length; j++) {const res = Number(tmpArr[j]);if (res > maxValue) {maxValue = res}rowArr.push(res)}renderData.push(rowArr)}return {maxValue,renderData} } //获取数据 async function getM4Data(url: string) {const fetchData = await fetch(url);const data = await fetchData.text();const dataArr = data.split("\n");return dataArr; }export { getM4Data, cesiumUtils };