【可视化学习】41-手把手实现cesium实现智慧城市(二)
发表于:2023-09-09 |

前言

本文将使用react和cesium进行智慧城市的实现,本篇主要讲解项目中的效果修改

地图底色修改

  • src

修改地图底色方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
export default function modifyMap(viewer) {
// 获取地图影像图层
let baseLayer = viewer.imageryLayers.get(0);
//设置2个变量,用来判断是否进行颜色的翻转和过滤
baseLayer.invertColor = true;

baseLayer.filterRGB = [0, 50, 100]; //[255,255,255] = > [0,50,100]
// 更改底图着色器的代码
const baseFragmentShader =
viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources;
// console.log(baseFragmentShader);

// 循环修改着色器
for (let i = 0; i < baseFragmentShader.length; i++) {
// console.log(baseFragmentShader[i]);
const strS = "color = czm_saturation(color, textureSaturation);\n#endif\n";
let strT = "color = czm_saturation(color, textureSaturation);\n#endif\n";
if (baseLayer.invertColor) {
strT += `
color.r = 1.0 - color.r;
color.g = 1.0 - color.g;
color.b = 1.0 - color.b;
`;
}
if (baseLayer.filterRGB) {
strT += `
color.r = color.r*${baseLayer.filterRGB[0]}.0/255.0;
color.g = color.g*${baseLayer.filterRGB[1]}.0/255.0;
color.b = color.b*${baseLayer.filterRGB[2]}.0/255.0;
`;
}

baseFragmentShader[i] = baseFragmentShader[i].replace(strS, strT);
}
}

引入并使用

1
2
3
import modifyMap from "./cesium/modifyMap";
// 修改地图的底色
modifyMap(viewer);

效果图

建筑材质修改

切换较多建筑地

为了能够更好的修改我们的材质,我们需要找一个楼层比较高的地方,于是我找了环城银泰那附近的建筑

  • src/cesium/initView.js
    1
    2
    3
    4
    5
    6
    7
    8
    var postion = Cesium.Cartesian3.fromDegrees(
    // 经度
    121.57,
    // 纬度
    29.79,
    // 高度
    1500
    );
    效果图

绘制building材质

  • src/cesium/modeifyBuild.js

根据高度设置渐变色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
tiles3d.tileVisible.addEventListener(function (tile) {
// console.log(tile);
const cesium3DTileCon = tile.content;
const featuresLength = cesium3DTileCon.featuresLength;
// console.log(cesium3DTileCon);
for (let i = 0; i < featuresLength; i++) {
const model = cesium3DTileCon.getFeature(i).content._model;

// 修改模型的片元着色器
const fragmentShaderSource =
(model._rendererResources.sourceShaders[1] = `
varying vec3 v_positionEC;

void main()
{
czm_materialInput materialInput;
// 获取模型position信息
vec4 position = czm_inverseModelView * vec4(v_positionEC, 1.0);
// 根据高度来设置渐变颜色
float strength = position.z/200.0;
gl_FragColor = vec4(strength,0.3*strength,strength, 1.0);
}

`);

// 片元着色器已经修改,需要更新
model._shouldRegenerateShaders = true;
}
});

效果图

设置动态光环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 修改模型的片元着色器
const fragmentShaderSource =(model._rendererResources.sourceShaders[1] = `
varying vec3 v_positionEC;

void main(){
czm_materialInput materialInput;
// 获取模型position信息
vec4 position = czm_inverseModelView * vec4(v_positionEC, 1.0);
// 根据高度来设置渐变颜色
float strength = position.z/200.0;
gl_FragColor = vec4(strength,0.3*strength,strength, 1.0);
// 动态光环
// czm_frameNumber获取当前帧数(一秒60帧)
// fract(x),返回x的小数部分
float time = fract(czm_frameNumber/(60.0*2.0));
// 实现往返的操作
time = abs(time-0.5)*2.0;
// clamp(x, min, max),返回x在min和max之间的最小值
float diff = abs(clamp(position.z/500.0, 0.0, 1.0) - time) ;
// step(edge, x),如果x大于等于edge,返回1,否则返回0
diff = step(0.01, diff);
gl_FragColor.rgb += vec3(0.5)*(1.0-diff);
}

`);

添加光锥

光锥代码

安装gsap

1
npm i gsap

光锥代码

  • src/cesium/LightCone.js
  • 121.5494, 29.80739 这个经纬度可以根据你想让他出现在哪里替换,我这里是点击了一下展示区域的中间位置,然后根据右下角的经纬度替换
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    import * as Cesium from "cesium";
    import gsap from "gsap";

    export default class LightCone {
    constructor(viewer) {
    this.params = {
    height: 200,
    degress: 0,
    };
    // 设置模型位置矩阵
    this.modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
    // 位置
    Cesium.Cartesian3.fromDegrees(121.5494, 29.80739, this.params.height),
    // 模型旋转情况
    new Cesium.HeadingPitchRoll(this.params.degress, 0, 0)
    );
    // 添加模型
    this.model = viewer.scene.primitives.add(
    new Cesium.Model.fromGltf({
    url: "./model/pyramid.glb",
    show: true,
    // 设置模型的缩放比例
    scale: 200,
    minimumPixelSize: 12,
    maximumScale: 20000,
    debugShowBoundingVolume: false,
    debugWireframe: false,
    color: Cesium.Color.YELLOW.withAlpha(0.5),
    // 设置颜色的混合模式
    colorBlendMode: Cesium.ColorBlendMode.MIX,
    // 设置模型的位置矩阵
    modelMatrix: this.modelMatrix,
    })
    );
    this.animate();
    }
    animate() {
    gsap.to(this.params, {
    height: 300,
    degress: Math.PI,
    yoyo: true,
    repeat: -1,
    duration: 1,
    ease: "power1.inOut",
    onUpdate: () => {
    this.model.modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
    // 位置
    Cesium.Cartesian3.fromDegrees(121.5494, 29.80739, this.params.height),
    // 模型旋转情况
    new Cesium.HeadingPitchRoll(this.params.degress, 0, 0)
    );
    },
    });
    }
    }

引入并使用

1
2
3
import LightCone from "./cesium/LightCone";
// 添加动态的光锥特效
let lightCone = new LightCone(viewer);

添加区域飞线

安装依赖

@turf/turf这个包的作用是生成随机区域点

1
import * as turf from "@turf/turf";

飞线代码

  • src/cesium/RectFlyLight.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    import * as Cesium from "cesium";
    import * as turf from "@turf/turf";

    export default class RectFlyLight {
    constructor(viewer) {
    // 设置矩形区域(可以通过我们点击屏幕得到大概方位)
    this.bbox = [121.52, 29.79, 121.58, 29.85];
    // 创建随机点(300是数量)
    let points = turf.randomPoint(300, {
    bbox: this.bbox,
    });
    // console.log(points);
    // 通过生成的随机点生成线
    let features = points.features;
    features.forEach((item) => {
    // 获取点的经纬度
    let point = item.geometry.coordinates;
    // 根据点设置起始位置
    let start = Cesium.Cartesian3.fromDegrees(point[0], point[1], 0);
    // 根据点设置结束位置(这里设置了50-1050m的线)
    let end = Cesium.Cartesian3.fromDegrees(
    point[0],
    point[1],
    50 + Math.random() * 1000
    );
    // 创建线
    let flyLine = viewer.entities.add({
    polyline: {
    positions: [start, end],
    width: 2,
    material: Cesium.Color.RED.withAlpha(0.5),
    },
    });
    });
    }
    }

App.jsx引入并使用

1
2
3
import RectFlyLight from "./cesium/RectFlyLight";
// 添加区域飞线
let rectFlyLight = new RectFlyLight(viewer);

效果图

添加飞线自定义材质

  • src/cesium/PolylineTrailMaterial.js
    这里运用了前文讲解过的自定义materialProperty材质的知识,这里我不多阐述
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    import * as Cesium from "cesium";
    import gsap from "gsap";
    let typeNum = 0;
    export default class PolylineTrailMaterialProperty {
    constructor(color = new Cesium.Color(0.7, 0.6, 1.0, 1.0)) {
    this.color = color;
    typeNum++;
    this.num = typeNum;
    this.definitionChanged = new Cesium.Event();
    Cesium.Material._materialCache.addMaterial(
    "PolylineTrailMaterial" + this.num,
    {
    fabric: {
    type: "PolylineTrailMaterial" + typeNum,
    uniforms: {
    uTime: 0,
    color: this.color,
    },
    source: `
    czm_material czm_getMaterial(czm_materialInput materialInput)
    {
    // 生成默认的基础材质
    czm_material material = czm_getDefaultMaterial(materialInput);
    // 获取st
    vec2 st = materialInput.st;
    // 获取当前帧数,10秒内变化从0-1;
    float time = fract(czm_frameNumber / (60.0*10.0));
    time = time * (1.0 + 0.1);
    // 平滑过渡函数
    // smoothstep(edge0, edge1, value);
    // 参数1:边缘0,==8,
    // 参数2:边缘1,==10,
    // 参数3:当前值,==7 , result = 0
    // 参数3:当前值,==9 , result = 0.5
    // 参数3:当前值,==10 , result = 1
    float alpha = smoothstep(time-0.1,time, st.s) * step(-time,-st.s);
    alpha += 0.05;
    // 设置材质的透明度
    material.alpha = alpha;
    material.diffuse = color.rgb;

    return material;
    }

    `,
    },
    }
    );

    this.params = {
    uTime: 0,
    };
    gsap.to(this.params, {
    uTime: 1,
    duration: 2,
    repeat: -1,
    yoyo: true,
    });
    }
    getType() {
    // 返回材质类型
    return "PolylineTrailMaterial" + this.num;
    }
    getValue(time, result) {
    result.uTime = this.params.uTime;
    // 返回材质值
    return result;
    }
    equals(other) {
    // 判断两个材质是否相等
    return (
    other instanceof PolylineTrailMaterialProperty &&
    this.color === other.color
    );
    }
    }

引用

1
2
3
4
5
6
7
8
9
10
// 创建自定义线材质
let polylineTrailMaterialProperty = new PolylineTrailMaterialProperty();
// 创建线
let flyLine = viewer.entities.add({
polyline: {
positions: [start, end],
width: 2,
material: polylineTrailMaterialProperty,
},
});

添加道路流光

网站导出

通过网站http://datav.aliyun.com/portal/school/atlas/area_selector 来导出我们的道路数据

在边界生成器找到我们智慧城市的定位

边界生成器

绘制道路

绘制道路

导出数据

导出数据

我这里随便搞了几条线,追求完美的可以自己去绘制

道路流光配置

绘制流光折线

  • src/cesium/RoadLight.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import * as Cesium from "cesium";
    import SpritelineMaterialProperty from "./material/SpritelineMaterialProperty";
    export default class RoadLightLine {
    constructor(viewer) {
    let geoJsonPromise = Cesium.GeoJsonDataSource.load(
    "./geojson/roadline.geojson"
    );
    geoJsonPromise.then((dataSource) => {
    viewer.dataSources.add(dataSource);
    let entities = dataSource.entities.values;
    let spritelineMaterialProperty = new SpritelineMaterialProperty();
    entities.forEach((item) => {
    let polyline = item.polyline;
    polyline.material = spritelineMaterialProperty;
    });
    });
    }
    }

配置材质

  • src/cesium/material/SpritelineMaterialProperty.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    import * as Cesium from "cesium";
    import gsap from "gsap";
    export default class SpritelineMaterialProperty {
    constructor(name) {
    this.name = name;
    this.definitionChanged = new Cesium.Event();
    Cesium.Material._materialCache.addMaterial("SpritelineMaterial", {
    fabric: {
    type: "SpritelineMaterial",
    uniforms: {
    uTime: 0,
    image: "./texture/spriteline1.png",
    },
    source: `
    czm_material czm_getMaterial(czm_materialInput materialInput)
    {
    // 生成默认的基础材质
    czm_material material = czm_getDefaultMaterial(materialInput);
    // 获取st
    vec2 st = materialInput.st;
    // 根据uv采样颜色,fract(x)返回x的小数部分
    vec4 color = texture2D(image, vec2(fract(st.s-uTime) , st.t));
    // 设置材质的透明度
    material.alpha = color.a;
    material.diffuse = color.rgb;

    return material;
    }

    `,
    },
    });

    this.params = {
    uTime: 0,
    };
    gsap.to(this.params, {
    uTime: 1,
    duration: 1,
    repeat: -1,
    ease: "linear",
    });
    }
    getType() {
    // 返回材质类型
    return "SpritelineMaterial";
    }
    getValue(time, result) {
    result.uTime = this.params.uTime;
    // 返回材质值
    return result;
    }
    equals(other) {
    // 判断两个材质是否相等
    return (
    other instanceof SpritelineMaterialProperty && this.name === other.name
    );
    }
    }

引用

App.jsx引用

1
2
3
import RoadLightLine from "./cesium/RoadLight";
// 创建道路飞线
let roadLightLine = new RoadLightLine(viewer);

创建雷达

雷达代码

  • src/cesium/RadarLight.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import * as Cesium from "cesium";
    import RadarMaterialProperty from "./material/RadarMaterialProperty";

    export default class RadarLight {
    constructor(viewer) {
    // 121.57,29.79,
    // 设置雷达材质
    this.radarMaterial = new RadarMaterialProperty("radarMaterial");
    this.entity = viewer.entities.add({
    rectangle: {
    coordinates: Cesium.Rectangle.fromDegrees(
    121.548,
    29.794,
    121.553,
    29.799
    ),
    material: this.radarMaterial,
    },
    });
    }
    }

雷达材质

  • src/cesium/material/RadarMaterialProperty.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    import * as Cesium from "cesium";
    import gsap from "gsap";
    export default class RadarMaterialProperty {
    constructor(name) {
    this.name = name;
    this.definitionChanged = new Cesium.Event();
    Cesium.Material._materialCache.addMaterial("RadarMaterial", {
    fabric: {
    type: "RadarMaterial",
    uniforms: {
    uTime: 0,
    },
    source: `
    czm_material czm_getMaterial(czm_materialInput materialInput)
    {
    // 生成默认的基础材质
    czm_material material = czm_getDefaultMaterial(materialInput);
    // 旋转uv
    vec2 newSt = mat2(
    cos(uTime),-sin(uTime),
    sin(uTime),cos(uTime)
    )*(materialInput.st-0.5);

    newSt = newSt+0.5;

    // 获取st
    vec2 st = newSt;

    // 设置圆,外部透明,内部不透明
    float alpha = 1.0 - step(0.5,distance(st,vec2(0.5))) ;

    // 按照角度来设置强弱
    float angle = atan(st.x-0.5,st.y-0.5);
    // angle是从-pi到pi的,所以如果要设置从0-1的转变,需要加上pi
    float strength = (angle+3.1416)/6.2832;

    // 将强弱与透明度结合
    alpha = alpha*strength;
    material.alpha = alpha;
    material.diffuse = vec3(st.x,st.y,1.0);
    return material;
    }

    `,
    },
    });

    this.params = {
    uTime: 0,
    };
    gsap.to(this.params, {
    uTime: 6.28,
    duration: 1,
    repeat: -1,
    ease: "linear",
    });
    }
    getType() {
    // 返回材质类型
    return "RadarMaterial";
    }
    getValue(time, result) {
    result.uTime = this.params.uTime;
    // 返回材质值
    return result;
    }
    equals(other) {
    // 判断两个材质是否相等
    return other instanceof RadarMaterialProperty && this.name === other.name;
    }
    }

引用

App.jsx引用

1
2
3
import RadarLight from "./cesium/RadarLight";
// 创建雷达
let radarLight = new RadarLight(viewer);

创建光波特效

光波代码

  • src/cesium/LightSpread.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    import * as Cesium from "cesium";
    import LightSpreadMaterialProperty from "./material/LightSpreadMaterialProperty";
    import gsap from "gsap";

    export default class LightSpread {
    constructor(viewer) {
    // 121.57,29.79,
    // 113.3191,23.109,
    // 设置雷达材质
    this.LightSpreadMaterial = new LightSpreadMaterialProperty(
    "LightSpreadMaterial"
    );
    this.params = {
    minlot: 121.555,
    minLat: 29.81,
    maxlot: 121.56,
    maxLat: 29.815,
    };
    this.entity = viewer.entities.add({
    rectangle: {
    coordinates: Cesium.Rectangle.fromDegrees(
    121.555,
    29.81,
    121.56,
    29.815
    ),
    material: this.LightSpreadMaterial,
    },
    });
    gsap.to(this.params, {
    minlot: 121.56,
    minLat: 29.795,
    maxlot: 121.565,
    maxLat: 29.805,
    duration: 5,
    repeat: -1,
    // yoyo: true,
    ease: "linear",
    onUpdate: () => {
    this.entity.rectangle.coordinates = Cesium.Rectangle.fromDegrees(
    this.params.minlot,
    this.params.minLat,
    this.params.maxlot,
    this.params.maxLat
    );
    },
    });
    }
    }

光波材质

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import * as Cesium from "cesium";
import gsap from "gsap";
export default class LightSpreadMaterialProperty {
constructor(name) {
this.name = name;
this.definitionChanged = new Cesium.Event();
Cesium.Material._materialCache.addMaterial("LightSpreadMaterial", {
fabric: {
type: "LightSpreadMaterial",
uniforms: {
uTime: 0,
image: "./texture/hexagon.png",
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
// 生成默认的基础材质
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
// 根据uv采样颜色
vec4 color = texture2D(image, st);
material.diffuse = color.rgb;
material.alpha = color.a;
return material;
}

`,
},
});

this.params = {
uTime: 0,
};
gsap.to(this.params, {
uTime: 6.28,
duration: 1,
repeat: -1,
ease: "linear",
});
}
getType() {
// 返回材质类型
return "LightSpreadMaterial";
}
getValue(time, result) {
result.uTime = this.params.uTime;
// 返回材质值
return result;
}
equals(other) {
// 判断两个材质是否相等
return (
other instanceof LightSpreadMaterialProperty && this.name === other.name
);
}
}

引用

App.jsx引用

1
2
3
import LightSpread from "./cesium/LightSpread";
// 6边形光波扩散特效
let lightSpread = new LightSpread(viewer);

光墙特效

光墙实现

  • src/cesium/LightWall.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    import * as Cesium from "cesium";
    import LightWallMaterialProperty from "./material/LightWallMaterialProperty";

    export default class LightWall {
    constructor(viewer) {
    // 设置雷达材质
    this.LightWallMaterial = new LightWallMaterialProperty("LightWallMaterial");
    this.entity = viewer.entities.add({
    name: "lightWall",
    position: Cesium.Cartesian3.fromDegrees(121.55, 29.8, 200.0,),
    wall: {
    positions: Cesium.Cartesian3.fromDegreesArrayHeights([
    121.545, 29.8, 200.0,
    121.555, 29.8, 200.0,
    121.555, 29.81, 200.0,
    121.545, 29.81, 200.0,
    121.545, 29.8, 200.0,
    ]),
    material: this.LightWallMaterial,
    // outline: true,
    },
    label: {
    text: "科技园光墙",
    font: "16px sans-serif",
    style: Cesium.LabelStyle.FILL_AND_OUTLINE,
    // outlineWidth: 2,
    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
    pixelOffset: new Cesium.Cartesian2(0, -20),
    fillColor: Cesium.Color.WHITE,
    // outlineColor: Cesium.Color.BLACK,
    },
    });
    }
    }

光墙材质

  • src/cesium/material/LightWallMaterialProperty.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    import * as Cesium from "cesium";
    import gsap from "gsap";
    export default class LightWallMaterialProperty {
    constructor(name) {
    this.name = name;
    this.definitionChanged = new Cesium.Event();
    Cesium.Material._materialCache.addMaterial("LightWallMaterial", {
    fabric: {
    type: "LightWallMaterial",
    uniforms: {
    uTime: 0,
    image: "./texture/spriteline2.png",
    },
    source: `
    czm_material czm_getMaterial(czm_materialInput materialInput)
    {
    // 生成默认的基础材质
    czm_material material = czm_getDefaultMaterial(materialInput);
    vec2 st = materialInput.st;
    // 根据uv采样颜色,fract函数,保留小数部分
    // vec4 color = texture2D(image, vec2(fract(st.x-uTime) , st.y));
    vec4 color = texture2D(image, vec2(fract(st.y+uTime) , st.x ));
    material.diffuse = color.rgb;
    material.alpha = color.a;
    return material;
    }

    `,
    },
    });

    this.params = {
    uTime: 0,
    };
    gsap.to(this.params, {
    uTime: 1,
    duration: 1,
    repeat: -1,
    ease: "linear",
    });
    }
    getType() {
    // 返回材质类型
    return "LightWallMaterial";
    }
    getValue(time, result) {
    result.uTime = this.params.uTime;
    // 返回材质值
    return result;
    }
    equals(other) {
    // 判断两个材质是否相等
    return (
    other instanceof LightWallMaterialProperty && this.name === other.name
    );
    }
    }

引用

App.jsx引用

1
2
3
import LightWall from "./cesium/LightWall";
// 光墙特效
let lightWall = new LightWall(viewer);

烟花粒子特效

  • src/cesium/ParticleLight.js

烟花粒子代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import * as Cesium from "cesium";

export default class ParticleLight {
constructor(viewer, color = Cesium.Color.WHITE) {
// 创建 box entity
this.boxEntity = viewer.entities.add({
name: "box",
position: Cesium.Cartesian3.fromDegrees( // 经度
121.53,
// 纬度
29.82,
100),
box: {
dimensions: new Cesium.Cartesian3(100.0, 100.0, 100),
material: Cesium.Color.RED.withAlpha(0),
},
});

var particleSystem = new Cesium.ParticleSystem({
// 粒子纹理
image: "./texture/smoke.png",
// 粒子图像大小
// imageSize: new Cesium.Cartesian2(20, 20),
// 粒子图像大小随机
minimumImageSize: new Cesium.Cartesian2(10, 10),
maximumImageSize: new Cesium.Cartesian2(30, 30),
// 设置开始的颜色
startColor: color,
// 设置结束的颜色
endColor: Cesium.Color.WHITE.withAlpha(0),
// 开始的时候粒子的大小
startScale: 0.1,
// 结束的时候粒子的大小
endScale: 2.0,
// 速度,米/秒
// speed: 5.0,
// 随机的发射速度
minimumSpeed: 1.0,
maximumSpeed: 10.0,
// 设置发射器
// emitter: new Cesium.CircleEmitter(1000),
emitter: new Cesium.BoxEmitter(new Cesium.Cartesian3(250, 250, 100)),
// 发射率,设置每秒产生粒子数量
emissionRate: 3,
// 粒子的生命周期,秒
lifetime: 5.0,
// 设置粒子发射的位置
modelMatrix: this.boxEntity.computeModelMatrix(
viewer.clock.currentTime,
new Cesium.Matrix4()
),
});
viewer.scene.primitives.add(particleSystem);
}
}

引入

在App.jsx中

1
2
3
4
5
import ParticleLight from "./cesium/ParticleLight";
// particleLight,创建烟花粒子
let particleLight = new ParticleLight(viewer, Cesium.Color.RED);
let particleLight1 = new ParticleLight(viewer, Cesium.Color.AQUA);
let particleLight2 = new ParticleLight(viewer, Cesium.Color.GREEN);

结语

好了,cesium这一块就暂时告一段落了,我把代码放在了https://gitee.com/guJyang/smart-city-cesium,再见

上一篇:
npm包的发布(二)
下一篇:
【可视化学习】40-手把手实现cesium实现智慧城市(一)