基本思路

关键点在于shader的编写

实现

通过按帧号的方式去计算采样的点位

js 复制代码
vec4 colorImage = texture(image, vec2(fract(st.s * 50.0 - speed * czm_frameNumber * 50.0 * 0.01), st.t));

被采样的贴图会被绘制到折线上。

js 复制代码
import * as Cesium from 'cesium';

/*
流动纹理线
 color 颜色
 duration 持续时间 毫秒
*/
function PolylineTrailLinkMaterialProperty (color, speed, duration, imageUrl) {
  this._definitionChanged = new Cesium.Event()
  this._color = undefined
  this._colorSubscription = undefined
  this.color = color
  this.speed = speed
  this.duration = duration
  this._time = new Date().getTime()
  this.imageUrl = imageUrl
}
Object.defineProperties(PolylineTrailLinkMaterialProperty.prototype, {
  isConstant: {
    get: function () {
      return false
    }
  },
  definitionChanged: {
    get: function () {
      return this._definitionChanged
    }
  },
  color: Cesium.createPropertyDescriptor('color')
})
PolylineTrailLinkMaterialProperty.prototype.getType = function (time) {
  return 'PolylineTrailLink'
}
PolylineTrailLinkMaterialProperty.prototype.getValue = function (time, result) {
  // debugger
  if (!Cesium.defined(result)) {
    result = {}
  }
  result.color = Cesium.Property.getValueOrClonedDefault(
    this._color,
    time,
    Cesium.Color.WHITE,
    result.color
  )
  result.image = this.imageUrl ? this.imageUrl : Cesium.Material.PolylineTrailLinkImage
  result.time = ((new Date().getTime() - this._time) % this.duration) / this.duration
  result.speed = this.speed
  return result
}
PolylineTrailLinkMaterialProperty.prototype.equals = function (other) {
  return (
    this === other ||
    (other instanceof PolylineTrailLinkMaterialProperty &&
      Property.equals(this._color, other._color))
  )
}
// Cesium.PolylineTrailLinkMaterialProperty = PolylineTrailLinkMaterialProperty
Cesium.Material.PolylineTrailLinkType = 'PolylineTrailLink'
Cesium.Material.PolylineTrailLinkImage = '/fire.png'
Cesium.Material.PolylineTrailLinkSource =
  `czm_material czm_getMaterial(czm_materialInput materialInput)
    {
        czm_material material = czm_getDefaultMaterial(materialInput);
        vec2 st = materialInput.st;
        vec4 colorImage = texture(image, vec2(fract(st.s * 50.0 - speed * czm_frameNumber * 50.0 * 0.01), st.t));
        material.alpha = colorImage.a * color.a;
        material.diffuse = (colorImage.rgb+color.rgb)/2.0;
        return material;
    }`
Cesium.Material._materialCache.addMaterial(
  Cesium.Material.PolylineTrailLinkType,
  {
    fabric: {
      type: Cesium.Material.PolylineTrailLinkType,
      uniforms: {
        color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
        image: Cesium.Material.PolylineTrailLinkImage,
        time: 0,
        speed: 0.008
      },
      source: Cesium.Material.PolylineTrailLinkSource
    },
    translucent: function (material) {
      return true
    }
  }
)

class FlowLine {
    
    constructor(viewer, options) {
        this.options = options
        this.viewer = viewer

        this.id = Cesium.Math.nextRandomNumber()
        if (options.id) {
          this.id = options.id
        }
    }

    play() {
        this.loopMaterial = new PolylineTrailLinkMaterialProperty(
            defaults(this.options.color, Cesium.Color.WHITE.withAlpha(0.5)),
            defaults(this.options.speed, 0.001),
            defaults(this.options.duration, 1750),
            defaults(this.options.image, "/guangpu.png") 
          )
        this.line = this.viewer.entities.add({
            name:  "flowline_" + this.id,
            polyline: {
                positions: this.options.positions,
                width: defaults(this.options.width, 10),
                material: this.loopMaterial //修改抛物线材质
            }
        })

    }

    destroy() {
      if (this.line) {
        this.viewer.entities.remove(this.line)
      }
  }
}

function defaults(value, defaultData) {
  return value ? value : defaultData
}

export {
    FlowLine
}