基本思路
关键点在于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
}