|
@@ -0,0 +1,238 @@
|
|
|
|
+/**
|
|
|
|
+ * 创建者:王成
|
|
|
|
+ * 操作系统:MAC
|
|
|
|
+ * 创建日期:2022年12月29日
|
|
|
|
+ * 描述:动态扩散圆材质
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+/* 引入Cesium */
|
|
|
|
+import * as Cesium from 'cesium';
|
|
|
|
+
|
|
|
|
+class CircleMaterialProperty {
|
|
|
|
+ /**
|
|
|
|
+ * @param {JSON} options 配置项
|
|
|
|
+ * @param {Cesium.Viewer} options.viewer 着色器运行所需的视图
|
|
|
|
+ * @param {Cesium.Color} options.color [圆环的颜色,默认蓝色] 可选
|
|
|
|
+ * @param {Number} options.duration [循环时间 默认1000] 可选
|
|
|
|
+ * @param {Number} options.count [圆环的数量 可选 默认为1]
|
|
|
|
+ */
|
|
|
|
+ constructor(options) {
|
|
|
|
+ /* 着色器运行依赖的视图 */
|
|
|
|
+ this._viewer = options.viewer;
|
|
|
|
+ /* 变更事件 */
|
|
|
|
+ this._definitionChanged = new Cesium.Event();
|
|
|
|
+ this._color = undefined;
|
|
|
|
+ /* 扩算圆环的颜色 */
|
|
|
|
+ this.color = options.color || Cesium.Color.BLUE;
|
|
|
|
+ /* 扩散圆环的数量 */
|
|
|
|
+ this.count = options.count || 1.0;
|
|
|
|
+ /* 动态循环周期 */
|
|
|
|
+ this.duration = options.duration || 1000;
|
|
|
|
+ /* 默认时间 */
|
|
|
|
+ this._time = (new Date()).getTime();
|
|
|
|
+ /* 材质类型名称 */
|
|
|
|
+ this._materialTypeName = 'jtCircleMaterial'
|
|
|
|
+ /* 存储相关参数的属性 以便后期进行追踪修改 */
|
|
|
|
+ this._param = {
|
|
|
|
+ color: this.color._value.toCssColorString(),
|
|
|
|
+ duration: this.duration,
|
|
|
|
+ count: this.count,
|
|
|
|
+ }
|
|
|
|
+ /* 将材质加入缓存 以便重复利用 */
|
|
|
|
+ Cesium.Material._materialCache.addMaterial(this._materialTypeName, {
|
|
|
|
+ fabric: {
|
|
|
|
+ type: this._materialTypeName,
|
|
|
|
+ uniforms: {
|
|
|
|
+ time: 0,
|
|
|
|
+ color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
|
|
|
|
+ count: 1.0,
|
|
|
|
+ },
|
|
|
|
+ source: this._getCircleMaterial(),
|
|
|
|
+ },
|
|
|
|
+ translucent: function(material) {
|
|
|
|
+ /* 材质是否半透明 */
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取材质着色器Shader
|
|
|
|
+ */
|
|
|
|
+ _getCircleMaterial() {
|
|
|
|
+ //普通扩散
|
|
|
|
+ // let circleMaterial = "czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
|
|
|
|
+ // "{\n" +
|
|
|
|
+ // " czm_material material = czm_getDefaultMaterial(materialInput);\n" +
|
|
|
|
+ // " material.diffuse = 1.5 * color.rgb;\n" +
|
|
|
|
+ // " vec2 st = materialInput.st;\n" +
|
|
|
|
+ // " float dis = distance(st, vec2(0.5, 0.5));\n" +
|
|
|
|
+ // " float per = fract(time);\n" +
|
|
|
|
+ // " if(dis > per * 0.5) {\n" +
|
|
|
|
+ // " material.alpha = 0.0;\n" +
|
|
|
|
+ // " discard;\n" +
|
|
|
|
+ // " }else{\n" +
|
|
|
|
+ // " material.alpha = color.a * dis / per / 1.0;\n" +
|
|
|
|
+ // " }\n" +
|
|
|
|
+ // " return material;\n" +
|
|
|
|
+ // "}";
|
|
|
|
+ /* 从小到大 再 从大到小 扩散 */
|
|
|
|
+ // let circleMaterial = "czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
|
|
|
|
+ // "{\n" +
|
|
|
|
+ // " czm_material material = czm_getDefaultMaterial(materialInput);\n" +
|
|
|
|
+ // " material.diffuse = color.rgb;\n" +
|
|
|
|
+ // " vec2 st = materialInput.st;\n" +
|
|
|
|
+ // " float dis = distance(st, vec2(0.5, 0.5));\n" +
|
|
|
|
+ // " float per = fract(time);\n" +
|
|
|
|
+ // " if(per < 0.5){\n" +
|
|
|
|
+ // " if(dis > per) {\n" +
|
|
|
|
+ // " material.alpha = 0.0;\n" +
|
|
|
|
+ // " discard;\n" +
|
|
|
|
+ // " }else{\n" +
|
|
|
|
+ // " material.alpha = color.a * dis / per / 1.0;\n" +
|
|
|
|
+ // " }\n" +
|
|
|
|
+ // " }else{\n" +
|
|
|
|
+ // " if(dis > 1.0 - per) {\n" +
|
|
|
|
+ // " material.alpha = 0.0;\n" +
|
|
|
|
+ // " discard;\n" +
|
|
|
|
+ // " }else{\n" +
|
|
|
|
+ // " material.alpha = color.a * dis / (1.0 - per) / 1.0;\n" +
|
|
|
|
+ // " }\n" +
|
|
|
|
+ // " }\n" +
|
|
|
|
+ // " return material;\n" +
|
|
|
|
+ // "}";
|
|
|
|
+ // let circleMaterial = "czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
|
|
|
|
+ // "{\n" +
|
|
|
|
+ // " czm_material material = czm_getDefaultMaterial(materialInput);\n" +
|
|
|
|
+ // " material.diffuse = 1.5 * color.rgb;\n" +
|
|
|
|
+ // " vec2 st = materialInput.st;\n" +
|
|
|
|
+ // " float dis = distance(st, vec2(0.5, 0.5));\n" +
|
|
|
|
+ // " float per = fract(time);\n" +
|
|
|
|
+ // " float xdis = per * float(0.5);\n" +
|
|
|
|
+ // " if(dis > xdis && dis < xdis + 0.05) {\n" +
|
|
|
|
+ // " material.alpha = dis * (0.75/(xdis + 0.05 - xdis)) - 0.75*xdis/(xdis + 0.05 - xdis);\n" +
|
|
|
|
+ // " }else if(dis > xdis + 0.2 && dis < xdis + 0.2 + 0.05){\n" +
|
|
|
|
+ // " material.alpha = dis * (0.75/(xdis + 0.2 + 0.05 - xdis)) - 0.75*(xdis + 0.2)/(xdis + 0.2 + 0.05 - xdis);\n" +
|
|
|
|
+ // " }else{\n" +
|
|
|
|
+ // " material.alpha = 0.0;\n" +
|
|
|
|
+ // " discard;\n" +
|
|
|
|
+ // " }\n" +
|
|
|
|
+ // " return material;\n" +
|
|
|
|
+ // "}";
|
|
|
|
+
|
|
|
|
+ //真正意义上的圆环扩散
|
|
|
|
+ let circleMaterial = "czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
|
|
|
|
+ "{\n" +
|
|
|
|
+ " czm_material material = czm_getDefaultMaterial(materialInput);\n" +
|
|
|
|
+ " material.diffuse = 1.5 * color.rgb;\n" +
|
|
|
|
+ " vec2 st = materialInput.st;\n" +
|
|
|
|
+ " vec3 str = materialInput.str;\n" +
|
|
|
|
+ " float dis = distance(st, vec2(0.5, 0.5));\n" +
|
|
|
|
+ " float per = fract(time);\n" +
|
|
|
|
+ " if (abs(str.z) > 0.001)\n" +
|
|
|
|
+ " {\n" +
|
|
|
|
+ " //着色器渲染停止,不在绘制内容 \n" +
|
|
|
|
+ " discard;\n" +
|
|
|
|
+ " }\n" +
|
|
|
|
+ " if (dis > 0.5)\n" +
|
|
|
|
+ " {\n" +
|
|
|
|
+ " //超出半径范围时,着色器渲染停止 \n" +
|
|
|
|
+ " discard;\n" +
|
|
|
|
+ " } else {\n" +
|
|
|
|
+ " //把半径分成count份,每两份之间的间隔距离 \n" +
|
|
|
|
+ " float perDis = 0.5 / count;\n" +
|
|
|
|
+ " float disNum;\n" +
|
|
|
|
+ " float bl = 0.0;\n" +
|
|
|
|
+ " //循环,最多999个环 \n" +
|
|
|
|
+ " for (int i = 0; i <= 999; i++)\n" +
|
|
|
|
+ " {\n" +
|
|
|
|
+ " //判断是否属于数量内的环 \n" +
|
|
|
|
+ " if (float(i) <= count)\n" +
|
|
|
|
+ " {\n" +
|
|
|
|
+ " disNum = perDis * float(i) - dis + per / count;\n" +
|
|
|
|
+ " if (disNum > 0.0)\n" +
|
|
|
|
+ " {\n" +
|
|
|
|
+ " if (disNum < perDis)\n" +
|
|
|
|
+ " {\n" +
|
|
|
|
+ " bl = 1.0 - disNum / perDis;\n" +
|
|
|
|
+ " } else if (disNum - perDis < perDis) {\n" +
|
|
|
|
+ " bl = 1.0 - abs(1.0 - disNum / perDis);\n" +
|
|
|
|
+ " }\n" +
|
|
|
|
+ " material.alpha = color.a * pow(bl, 3.0);\n" +
|
|
|
|
+ " }\n" +
|
|
|
|
+ " }\n" +
|
|
|
|
+ " }\n" +
|
|
|
|
+ " }\n" +
|
|
|
|
+ " return material;\n" +
|
|
|
|
+ "}\n";
|
|
|
|
+ return circleMaterial;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 必须重写的方法
|
|
|
|
+ */
|
|
|
|
+Object.assign(CircleMaterialProperty.prototype, {
|
|
|
|
+ /**
|
|
|
|
+ * 重新获取类型方法
|
|
|
|
+ * @param {Cesium.JulianDate} time 时间
|
|
|
|
+ */
|
|
|
|
+ getType: function(time) {
|
|
|
|
+ return this._materialTypeName;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 重写获取值方法
|
|
|
|
+ * @param {Cesium.JulianDate} time
|
|
|
|
+ * @param {JSON} result
|
|
|
|
+ */
|
|
|
|
+ getValue: function(time, result) {
|
|
|
|
+ if (!Cesium.defined(result)) {
|
|
|
|
+ result = {};
|
|
|
|
+ }
|
|
|
|
+ result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.BLUE, result
|
|
|
|
+ .color);
|
|
|
|
+ result.count = this.count;
|
|
|
|
+ if (this.duration) {
|
|
|
|
+ result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
|
|
|
|
+ }
|
|
|
|
+ this._viewer.scene.requestRender();
|
|
|
|
+ return result;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 重写对比函数
|
|
|
|
+ * @param {Object} other 传入对比对象
|
|
|
|
+ */
|
|
|
|
+ equals: function(other) {
|
|
|
|
+ return (this === other || (other instanceof WallMaterialProperty && Cesium.Property.equals(this
|
|
|
|
+ ._color, other._color)));
|
|
|
|
+ }
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 默认属性
|
|
|
|
+ */
|
|
|
|
+Object.defineProperties(CircleMaterialProperty.prototype, {
|
|
|
|
+ /**
|
|
|
|
+ * 判断是否相等,返回false表示属性一直在变化中
|
|
|
|
+ */
|
|
|
|
+ isConstant: {
|
|
|
|
+ get: function() {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ /**
|
|
|
|
+ * 事件变更
|
|
|
|
+ */
|
|
|
|
+ definitionChanged: {
|
|
|
|
+ get: function() {
|
|
|
|
+ return this._definitionChanged;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ /* 颜色属性 */
|
|
|
|
+ color: Cesium.createPropertyDescriptor('color')
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+/* 导出 */
|
|
|
|
+export default CircleMaterialProperty;
|