| | |
| | | import * as Cesium from 'cesium' |
| | | /** |
| | | * 定义Cesium材质对象 |
| | | */ |
| | | class ImageTrailMaterial { |
| | | _definitionChanged: Cesium.Event<(...args: any[]) => void>; |
| | | _color: undefined; |
| | | _colorSubscription: undefined; |
| | | _speed: undefined; |
| | | _speedSubscription: undefined; |
| | | _image: undefined; |
| | | _imageSubscription: undefined; |
| | | _repeat: undefined; |
| | | _repeatSubscription: undefined; |
| | | color: any; |
| | | speed: any; |
| | | image: any; |
| | | repeat: Cesium.Cartesian2; |
| | | constructor (options : any = {}) { |
| | | this._definitionChanged = new Cesium.Event() |
| | | this._color = undefined |
| | | this._colorSubscription = undefined |
| | | this._speed = undefined |
| | | this._speedSubscription = undefined |
| | | this._image = undefined |
| | | this._imageSubscription = undefined |
| | | this._repeat = undefined |
| | | this._repeatSubscription = undefined |
| | | this.color = options.color || Cesium.Color.fromBytes(0, 0, 255, 255) |
| | | this.speed = options.speed || 1 |
| | | this.image = options.image |
| | | this.repeat = new Cesium.Cartesian2( |
| | | options.repeat?.x || 1, |
| | | options.repeat?.y || 1 |
| | | ) |
| | | } |
| | | import * as cesium from 'cesium' |
| | | |
| | | get isConstant () { |
| | | return false |
| | | } |
| | | const Cesium: any = cesium |
| | | |
| | | get definitionChanged () { |
| | | return this._definitionChanged |
| | | } |
| | | const getResource = (name: string) => { |
| | | return new URL(`/src/assets/icons/${name}`, import.meta.url).href |
| | | } |
| | | |
| | | getType () { |
| | | return Cesium.Material.ImageTrailMaterialType |
| | | } |
| | | const defaultColor = Cesium.Color.TRANSPARENT |
| | | const defaultImage = getResource('arrow-right.png') |
| | | const defaultImageimageW = 10 |
| | | const defaultAnimation = false |
| | | const defaultDuration = 3000 |
| | | |
| | | getValue (time: any, result: any) { |
| | | if (!result) { |
| | | result = {} |
| | | } |
| | | result.color = Cesium.Property?.getValueOrUndefined(this._color, time) |
| | | result.image = Cesium.Property?.getValueOrUndefined(this._image, time) |
| | | result.repeat = Cesium.Property?.getValueOrUndefined(this._repeat, time) |
| | | result.speed = this._speed |
| | | return result |
| | | } |
| | | function ImageTrailMaterial (this: any, opt: any = {}) { |
| | | opt = Cesium.defaultValue(opt, Cesium.defaultValue.EMPTY_OBJECT) |
| | | this._definitionChanged = new Cesium.Event() |
| | | // 自定义材质 |
| | | // 自定义图片颜色 |
| | | this._color = undefined |
| | | this._colorSubscription = undefined |
| | | // 自定义背景颜色 |
| | | this._backgroundColor = undefined |
| | | this._backgroundColorSubscription = undefined |
| | | // 图片 |
| | | this._image = undefined |
| | | this._imageSubscription = undefined |
| | | // 图片宽度 |
| | | this._imageW = undefined |
| | | this._imageWSubscription = undefined |
| | | // 是否开启动画 |
| | | this._animation = undefined |
| | | this._animationSubscription = undefined |
| | | // 动画持续时间 |
| | | this._duration = undefined |
| | | this._durationSubscription = undefined |
| | | |
| | | equals (other: this) { |
| | | return ( |
| | | this === other || |
| | | (other instanceof ImageTrailMaterial && |
| | | Cesium.Property.equals(this._color, other._color) && |
| | | Cesium.Property.equals(this._image, other._image) && |
| | | Cesium.Property.equals(this._repeat, other._repeat) && |
| | | Cesium.Property.equals(this._speed, other._speed)) |
| | | ) |
| | | // 变量初始化 |
| | | this.color = opt.color || defaultColor // 颜色 |
| | | this.backgroundColor = opt.backgroundColor || defaultColor // 颜色 |
| | | this._image = opt.image || defaultImage // 材质图片 |
| | | this.imageW = opt.imageW || defaultImageimageW |
| | | this.animation = opt.animation || defaultAnimation |
| | | this.duration = opt.duration || defaultDuration |
| | | this._time = undefined |
| | | } |
| | | |
| | | ImageTrailMaterial.prototype.getType = function () { |
| | | return Cesium.Material.ImageTrailMaterialType |
| | | } |
| | | |
| | | // 这个方法在每次渲染时被调用,result的参数会传入glsl中。 |
| | | ImageTrailMaterial.prototype.getValue = function ( |
| | | time: any, |
| | | result: { |
| | | color?: any |
| | | backgroundColor?: any |
| | | image?: any |
| | | imageW?: any |
| | | animation?: any |
| | | time?: any |
| | | }, |
| | | ) { |
| | | if (!Cesium.defined(result)) { |
| | | result = {} |
| | | } |
| | | // result.color = Cesium.Property.getValueOrClonedDefault( |
| | | // this._color, |
| | | // time, |
| | | // defaultColor, |
| | | // result.color, |
| | | // ) |
| | | // result.backgroundColor = Cesium.Property.getValueOrClonedDefault( |
| | | // this._backgroundColor, |
| | | // time, |
| | | // defaultColor, |
| | | // result.backgroundColor, |
| | | // ) |
| | | result.color = Cesium.Property.getValueOrUndefined(this._color, time) |
| | | result.backgroundColor = Cesium.Property.getValueOrUndefined(this._backgroundColor, time) |
| | | result.image = this._image |
| | | result.imageW = this._imageW |
| | | result.animation = this._animation |
| | | if (this._time === undefined) { |
| | | this._time = new Date().getTime() |
| | | } |
| | | result.time = |
| | | ((new Date().getTime() - this._time) % this._duration) / this._duration |
| | | return result |
| | | } |
| | | |
| | | ImageTrailMaterial.prototype.equals = function (other: { |
| | | _color: any |
| | | _backgroundColor: any |
| | | }) { |
| | | return ( |
| | | this === other || |
| | | (other instanceof ImageTrailMaterial && |
| | | Cesium.Property.equals(this._color, other._color) && |
| | | Cesium.Property.equals(this._backgroundColor, other._backgroundColor)) |
| | | ) |
| | | } |
| | | |
| | | Object.defineProperties(ImageTrailMaterial.prototype, { |
| | | isConstant: { |
| | | get: function get () { |
| | | return false |
| | | }, |
| | | }, |
| | | definitionChanged: { |
| | | get: function get () { |
| | | return this._definitionChanged |
| | | }, |
| | | }, |
| | | color: Cesium.createPropertyDescriptor('color'), |
| | | speed: Cesium.createPropertyDescriptor('speed'), |
| | | backgroundColor: Cesium.createPropertyDescriptor('backgroundColor'), |
| | | image: Cesium.createPropertyDescriptor('image'), |
| | | repeat: Cesium.createPropertyDescriptor('repeat'), |
| | | imageW: Cesium.createPropertyDescriptor('imageW'), |
| | | animation: Cesium.createPropertyDescriptor('animation'), |
| | | duration: Cesium.createPropertyDescriptor('duration'), |
| | | }) |
| | | // 材质类型 |
| | | Cesium.Material.ImageTrailMaterialType = 'PolylineImageTrail' |
| | | // 添加材质到缓冲区中 |
| | | Cesium.Material._materialCache.addMaterial( |
| | | Cesium.Material.ImageTrailMaterialType, |
| | | { |
| | | fabric: { |
| | | type: Cesium.Material.ImageTrailMaterialType, |
| | | // uniform变量 |
| | | uniforms: { |
| | | color: new Cesium.Color(1.0, 0.0, 0.0, 0.7), |
| | | image: Cesium.Material.DefaultImageId, |
| | | speed: 1, |
| | | repeat: new Cesium.Cartesian2(1, 1), |
| | | }, |
| | | // |
| | | source: ` |
| | | uniform sampler2D image; |
| | | uniform float speed; |
| | | uniform vec4 color; |
| | | uniform vec2 repeat; |
| | | |
| | | czm_material czm_getMaterial(czm_materialInput materialInput){ |
| | | czm_material material=czm_getDefaultMaterial(materialInput); |
| | | vec2 st=repeat * materialInput.st; |
| | | float time=fract(czm_frameNumber*speed/1000.); |
| | | // st.s是横轴方向运动,st.t是纵轴, |
| | | // vec2(fract(st.s-time),st.t)是横轴按照时间变化而变化,纵轴保持正常不变化 |
| | | vec4 colorImage=texture2D(image,vec2(fract(st.s-time),st.t)); |
| | | vec4 fragColor; |
| | | fragColor.rgb=color.rgb / 1.0; |
| | | if(color.a==0.){ |
| | | material.alpha=colorImage.a; |
| | | material.diffuse=colorImage.rgb; |
| | | }else{ |
| | | material.alpha=colorImage.a*color.a; |
| | | material.diffuse=max(color.rgb*material.alpha*3.,color.rgb); |
| | | } |
| | | return material; |
| | | } |
| | | ` |
| | | }, |
| | | translucent: function () { |
| | | return true |
| | | }, |
| | | } |
| | | ) |
| | | |
| | | export default ImageTrailMaterial |
| | | // 写到Cesium对象上,就可以像其他MaterialProperty一样使用了 |
| | | Cesium.Material.ImageTrailMaterialType = 'PolylineImageTrail' |
| | | |
| | | Cesium.Material._materialCache.addMaterial(Cesium.Material.ImageTrailMaterialType, { |
| | | fabric: { |
| | | type: 'ImageLine', |
| | | uniforms: { |
| | | // uniforms参数跟我们上面定义的参数以及getValue方法中返回的result对应,这里值是默认值 |
| | | color: new Cesium.Color(1, 0, 0, 1.0), |
| | | backgroundColor: new Cesium.Color(0, 0, 0, 0.0), |
| | | image: '', |
| | | imageW: 1, |
| | | animation: false, |
| | | duration: 30, |
| | | time: 0, |
| | | }, |
| | | // source编写glsl,可以使用uniforms参数,值来自getValue方法的result |
| | | source: ` |
| | | czm_material czm_getMaterial(czm_materialInput materialInput) |
| | | { |
| | | czm_material material = czm_getDefaultMaterial(materialInput); |
| | | vec2 st = materialInput.st; |
| | | float s = st.s/ (abs(fwidth(st.s)) * imageW * czm_pixelRatio); |
| | | if(animation==true){ |
| | | s = s-time;//增加运动效果 |
| | | } |
| | | float t = st.t; |
| | | vec4 colorImage = texture(image, vec2(fract(s), t)); |
| | | material.diffuse = colorImage.rgb; |
| | | material.emission = max(backgroundColor.rgb*material.alpha*1.,backgroundColor.rgb); |
| | | return material; |
| | | } |
| | | `, |
| | | }, |
| | | translucent: function translucent () { |
| | | return true |
| | | }, |
| | | }) |
| | | |
| | | export default (ImageTrailMaterial as any) |