浏览代码

no message

不会爬树的猴 2 年之前
父节点
当前提交
121308176d
共有 1 个文件被更改,包括 238 次插入0 次删除
  1. 238 0
      src/components/CrMap/CircleMaterialProperty_back.js

+ 238 - 0
src/components/CrMap/CircleMaterialProperty_back.js

@@ -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;