cesium实现水波纹扩散效果


Cesium实战系列文章总目录传送门

1.实现效果

在这里插入图片描述

2.实现方法

2.1调用方法

引入类js文件后,设置水波扩散的名称、中心点坐标、颜色、半径、持续时间等参数即可。

 // 水波纹扩散
 let circleWave = new CircleWave(viewer, "cirCleWave1");
 circleWave.add([113.940, 22.512, 0], '#1FA8E3', 500, 3000);

2.2实现代码

参考gitee上的开源ts代码,这里将水波纹的材质和类写在一个js文件中。

点效果Effect父类可参考上篇博客:传送门

/**
 * 水波纹扩散材质
 * 
 * 
 * @param {*} color  颜色
 * @param {*} duration 持续时间 毫秒
 * @param {*} count  波浪数量
 * @param {*} gradient 渐变曲率
 */
function CircleWaveMaterialProperty(ob) {
    this._definitionChanged = new Cesium.Event()
    this._color = undefined
    this._colorSubscription = undefined
    this.color = ob.color
    this.duration = Cesium.defaultValue(ob.duration, 1000)
    this.count = Cesium.defaultValue(ob.count, 2)
    if (this.count <= 0) {
        this.count = 1
    }
    this.gradient = Cesium.defaultValue(ob.gradient, 0.1)
    if (this.gradient === 0) {
        this.gradient = 0
    }
    if (this.gradient > 1) {
        this.gradient = 1
    }
    this._time = new Date().getTime()
}
Object.defineProperties(CircleWaveMaterialProperty.prototype, {
    isConstant: {
        get: function() {
            return false
        },
    },
    definitionChanged: {
        get: function() {
            return this._definitionChanged
        },
    },
    color: Cesium.createPropertyDescriptor('color'),
    duration: Cesium.createPropertyDescriptor('duration'),
    count: Cesium.createPropertyDescriptor('count'),
})
CircleWaveMaterialProperty.prototype.getType = function(_time) {
    return Cesium.Material.CircleWaveMaterialType
}
CircleWaveMaterialProperty.prototype.getValue = function(
    time,
    result
) {
    if (!Cesium.defined(result)) {
        result = {}
    }
    result.color = Cesium.Property.getValueOrClonedDefault(
        this._color,
        time,
        Cesium.Color.WHITE,
        result.color
    )
    result.time =
        ((new Date().getTime() - this._time) % this.duration) / this.duration
    result.count = this.count
    result.gradient = 1 + 10 * (1 - this.gradient)
    return result
}
CircleWaveMaterialProperty.prototype.equals = function(other) {
    const reData = (
        this === other ||
        (other instanceof CircleWaveMaterialProperty &&
            Cesium.Property.equals(this._color, other._color))
    )
    return reData
}
Cesium.CircleWaveMaterialProperty = CircleWaveMaterialProperty
Cesium.Material.CircleWaveMaterialType = 'CircleWaveMaterial'
Cesium.Material.CircleWaveSource = `
                                    czm_material czm_getMaterial(czm_materialInput materialInput) {
                                      czm_material material = czm_getDefaultMaterial(materialInput);
                                      material.diffuse = 1.5 * color.rgb;
                                      vec2 st = materialInput.st;
                                      vec3 str = materialInput.str;
                                      float dis = distance(st, vec2(0.5, 0.5));
                                      float per = fract(time);
                                      if (abs(str.z) > 0.001) {
                                        discard;
                                      }
                                      if (dis > 0.5) {
                                        discard;
                                      } else {
                                        float perDis = 0.5 / count;
                                        float disNum;
                                        float bl = .0;
                                        for (int i = 0; i <= 9; i++) {
                                          if (float(i) <= count) {
                                            disNum = perDis *float(i) - dis + per / count;
                                            if (disNum > 0.0) {
                                              if (disNum < perDis) {
                                                bl = 1.0 - disNum / perDis;
                                              } else if(disNum - perDis < perDis) {
                                                bl = 1.0 - abs(1.0 - disNum / perDis);
                                              }
                                              material.alpha = pow(bl, gradient);
                                            }
                                          }
                                        }
                                      }
                                      return material;
                                    }
                                    `
Cesium.Material._materialCache.addMaterial(
    Cesium.Material.CircleWaveMaterialType, {
        fabric: {
            type: Cesium.Material.CircleWaveMaterialType,
            uniforms: {
                color: new Cesium.Color(1, 0, 0, 1),
                time: 1,
                count: 1,
                gradient: 0.1,
            },
            source: Cesium.Material.CircleWaveSource,
        },
        translucent: function(material) {
            return true
        },
    }
)

// 水波纹
class CircleWave extends Effect {
    count;
    constructor(viewer, id) {
        super(viewer, id)
    }
    change_duration(d) {
        super.change_duration(d)
        const curEntity = this.viewer.entities.getById(this.id)
        curEntity._ellipse._material.duration = d
    }
    change_waveCount(d) {
        const curEntity = this.viewer.entities.getById(this.id)
        curEntity._ellipse._material.count = d
    }
    add(position, color, maxRadius, duration, isedit = false, count = 3) {
        super.add(position, color, maxRadius, duration, isedit)
        const _this = this
        this.count = count
        this.viewer.entities.add({
            id: _this.id,
            position: Cesium.Cartesian3.fromDegrees(
                position[0],
                position[1],
                position[2]
            ),
            ellipse: {
                // height: position[2],
                semiMinorAxis: new Cesium.CallbackProperty(function(n) {
                    return _this.maxRadius
                }, false),
                semiMajorAxis: new Cesium.CallbackProperty(function(n) {
                    return _this.maxRadius
                }, false),
                material: new Cesium.CircleWaveMaterialProperty({
                    duration: duration,
                    gradient: 0,
                    color: new Cesium.Color.fromCssColorString(color),
                    count: count,
                }),
            },
        })
    }
}
  • 7
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

右弦GISer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值