CircleMaterialProperty.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /**
  2. * 创建者:王成
  3. * 操作系统:MAC
  4. * 创建日期:2022年12月29日
  5. * 描述:动态扩散圆材质
  6. */
  7. class CircleMaterialProperty {
  8. /**
  9. * 构造方法
  10. * @ignore 无需公开
  11. * @param {JSON} options 配置项
  12. * @param {Cesium.Viewer} options.viewer 着色器运行所需的视图
  13. * @param {Cesium.Color} options.color [圆环的颜色,默认蓝色] 可选
  14. * @param {Number} options.duration [循环时间 默认1000] 可选
  15. * @param {Number} options.count [圆环的数量 可选 默认为1]
  16. */
  17. constructor(options) {
  18. /* 着色器运行依赖的视图 */
  19. this._viewer = options.viewer;
  20. /* 变更事件 */
  21. this._definitionChanged = new Cesium.Event();
  22. this._color = undefined;
  23. /* 扩算圆环的颜色 */
  24. this.color = options.color || Cesium.Color.BLUE;
  25. /* 扩散圆环的数量 */
  26. this.count = options.count || 1.0;
  27. /* 动态循环周期 */
  28. this.duration = options.duration || 1000;
  29. /* 默认时间 */
  30. this._time = (new Date()).getTime();
  31. /* 材质类型名称 */
  32. this._materialTypeName = 'jtCircleMaterial'
  33. /* 存储相关参数的属性 以便后期进行追踪修改 */
  34. this._param = {
  35. color: this.color._value.toCssColorString(),
  36. duration: this.duration,
  37. count: this.count,
  38. }
  39. /* 将材质加入缓存 以便重复利用 */
  40. Cesium.Material._materialCache.addMaterial(this._materialTypeName, {
  41. fabric: {
  42. type: this._materialTypeName,
  43. uniforms: {
  44. time: 0,
  45. color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
  46. count: 1.0,
  47. },
  48. source: this._getCircleMaterial(),
  49. },
  50. translucent: function(material) {
  51. /* 材质是否半透明 */
  52. return true;
  53. }
  54. });
  55. }
  56. /**
  57. * @ignore 无需公开
  58. * 获取材质着色器Shader
  59. */
  60. _getCircleMaterial() {
  61. let circleMaterial = "czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
  62. "{\n" +
  63. " czm_material material = czm_getDefaultMaterial(materialInput);\n" +
  64. " material.diffuse = 1.5 * color.rgb;\n" +
  65. " vec2 st = materialInput.st;\n" +
  66. " vec3 str = materialInput.str;\n" +
  67. " float dis = distance(st, vec2(0.5, 0.5));\n" +
  68. " float per = fract(time);\n" +
  69. " if (abs(str.z) > 0.001)\n" +
  70. " {\n" +
  71. " //着色器渲染停止,不在绘制内容 \n" +
  72. " discard;\n" +
  73. " }\n" +
  74. " if (dis > 0.5)\n" +
  75. " {\n" +
  76. " //超出半径范围时,着色器渲染停止 \n" +
  77. " discard;\n" +
  78. " } else {\n" +
  79. " //把半径分成count份,每两份之间的间隔距离 \n" +
  80. " float perDis = 0.5 / count;\n" +
  81. " float disNum;\n" +
  82. " float bl = 0.0;\n" +
  83. " //循环,最多999个环 \n" +
  84. " for (int i = 0; i <= 999; i++)\n" +
  85. " {\n" +
  86. " //判断是否属于数量内的环 \n" +
  87. " if (float(i) <= count)\n" +
  88. " {\n" +
  89. " disNum = perDis * float(i) - dis + per / count;\n" +
  90. " if (disNum > 0.0)\n" +
  91. " {\n" +
  92. " if (disNum < perDis)\n" +
  93. " {\n" +
  94. " bl = 1.0 - disNum / perDis;\n" +
  95. " } else if (disNum - perDis < perDis) {\n" +
  96. " bl = 1.0 - abs(1.0 - disNum / perDis);\n" +
  97. " }\n" +
  98. " material.alpha = color.a * pow(bl, 3.0);\n" +
  99. " }\n" +
  100. " }\n" +
  101. " }\n" +
  102. " }\n" +
  103. " return material;\n" +
  104. "}\n";
  105. return circleMaterial;
  106. }
  107. }
  108. /**
  109. * @ignore 无需公开
  110. * 必须重写的方法
  111. */
  112. Object.assign(CircleMaterialProperty.prototype, {
  113. /**
  114. * 重新获取类型方法
  115. * @ignore 无需公开
  116. * @param {Cesium.JulianDate} time 时间
  117. */
  118. getType: function(time) {
  119. return this._materialTypeName;
  120. },
  121. /**
  122. * 重写获取值方法
  123. * @ignore 无需公开
  124. * @param {Cesium.JulianDate} time
  125. * @param {JSON} result
  126. */
  127. getValue: function(time, result) {
  128. if (!Cesium.defined(result)) {
  129. result = {};
  130. }
  131. result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.BLUE, result
  132. .color);
  133. result.count = this.count;
  134. if (this.duration) {
  135. result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
  136. }
  137. this._viewer.scene.requestRender();
  138. return result;
  139. },
  140. /**
  141. * 重写对比函数
  142. * @ignore 无需公开
  143. * @param {Object} other 传入对比对象
  144. */
  145. equals: function(other) {
  146. return (this === other || (other instanceof CircleMaterialProperty && Cesium.Property.equals(this
  147. ._color, other._color)));
  148. }
  149. })
  150. /**
  151. * 默认属性
  152. */
  153. Object.defineProperties(CircleMaterialProperty.prototype, {
  154. /**
  155. * 判断是否相等,返回false表示属性一直在变化中
  156. * @ignore 无需公开
  157. */
  158. isConstant: {
  159. get: function() {
  160. return false;
  161. }
  162. },
  163. /**
  164. * 事件变更
  165. * @ignore 无需公开
  166. */
  167. definitionChanged: {
  168. get: function() {
  169. return this._definitionChanged;
  170. }
  171. },
  172. /* 颜色属性 */
  173. color: Cesium.createPropertyDescriptor('color')
  174. })
  175. export default CircleMaterialProperty;