cesium 开发中记录一下常见特效

538 阅读3分钟

记录一下开发cesium常用的方法以及示例 后续开发会慢慢记录 相当于总结

闪动空气墙

let alp = 1;
let num = 0;
function drawWall(viewer) {
  // 每次加载一次空气墙 都要清除上一次的空气墙
  viewer.entities.values.forEach(function (entity) {
    if (entity.layer === "drawWall") {
      viewer.entities.remove(entity);
    }
  });
  let line = ["经度", "纬度", "高度", "经度", "纬度", "高度"]; // positions类似这种格式
  viewer.entities.add({
    name: "空气墙闪动",
    layer: "drawWall",
    wall: {
      positions: Cesium.Cartesian3.fromDegreesArrayHeights(line),
      // 设置高度
      maximumHeights: new Array(line.length).fill(60),
      minimumHeights: new Array(line.length).fill(0),
      // 扩散墙材质
      material: new Cesium.ImageMaterialProperty({
        image: "你要的图片路径",
        color: new Cesium.CallbackProperty(function () {
          if (num % 2 === 0) {
            alp -= 0.005;
          } else {
            alp += 0.005;
          }

          if (alp <= 0.5) {
            num++;
          } else if (alp >= 1) {
            num++;
          }
          return Cesium.Color.WHITE.withAlpha(alp);
          //entity的颜色透明 并不影响材质,并且 entity也会透明
        }, false),
      }),
    },
  });
}

动态立体墙

1、先封装一个 WallDiffuseMaterialProperty.js 然后直接引入就能用 不想封装放在一个js文件也可以

class WallDiffuseMaterialProperty {
  constructor(options) {
      this._definitionChanged = new Cesium.Event();
      this._color = undefined;
      this.color = options.color;
  };

  get isConstant() {
      return false;
  }

  get definitionChanged() {
      return this._definitionChanged;
  }

  getType(time) {
      return Cesium.Material.WallDiffuseMaterialType;
  }

  getValue(time, result) {
      if (!Cesium.defined(result)) {
          result = {};
      }

      result.color = Cesium.Property.getValueOrDefault(this._color, time, Cesium.Color.RED, result.color);
      return result
  }

  equals(other) {
      return (this === other ||
          (other instanceof WallDiffuseMaterialProperty &&
              Cesium.Property.equals(this._color, other._color))
      )
  }
}

Object.defineProperties(WallDiffuseMaterialProperty.prototype, {
  color: Cesium.createPropertyDescriptor('color'),
})

Cesium.WallDiffuseMaterialProperty = WallDiffuseMaterialProperty;
Cesium.Material.WallDiffuseMaterialProperty = 'WallDiffuseMaterialProperty';
Cesium.Material.WallDiffuseMaterialType = 'WallDiffuseMaterialType';
Cesium.Material.WallDiffuseMaterialSource =
  `
  uniform vec4 color;
  czm_material czm_getMaterial(czm_materialInput materialInput){
  czm_material material = czm_getDefaultMaterial(materialInput);
  vec2 st = materialInput.st;
  material.diffuse = color.rgb * 2.0;
  
  // 以下四选一
  material.alpha = color.a * (1.0 - fract(st.t)) * 0.8; // 立体向上 
  material.alpha = color.a * (fract(st.t)) * 0.8; // 立体向下
  material.alpha = color.a * (fract(st.s)) * 0.8; // 水平逆时针
  material.alpha = color.a * (1.0 - fract(st.s)) * 0.8;// 水平顺时针
  return material;
  }
                                          
  `

Cesium.Material._materialCache.addMaterial(Cesium.Material.WallDiffuseMaterialType, {
  fabric: {
      type: Cesium.Material.WallDiffuseMaterialType,
      uniforms: {
          color: new Cesium.Color(1.0, 0.0, 0.0, 1.0),
      },
      source: Cesium.Material.WallDiffuseMaterialSource
  },
  translucent: function(material) {
      return true;
  }
})

2、调用封装的代码

function drawWall(viewer) {
  let line = ["经度", "纬度", "高度", "经度", "纬度", "高度"]; // positions类似这种格式
  viewer.entities.add({
    name: "立体墙效果",
    wall: {
      positions: line,
      // 设置高度
      maximumHeights: new Array(line.length).fill(50),
      minimunHeights: new Array(line.length).fill(0),
      // 扩散墙材质
      material: new Cesium.WallDiffuseMaterialProperty({
        color: new Cesium.Color(1.0, 1.0, 0.0, 1.0),
      }),
    },
  });
}

精灵穿梭路光效果

1、封装一个Spriteline1MaterialProperty.js代码

function Spriteline1MaterialProperty(duration, image) {
  this._definitionChanged = new Cesium.Event()
  this.duration = duration
  this.image = image
  this._time = performance.now()
}
Object.defineProperties(Spriteline1MaterialProperty.prototype, {
  isConstant: {
    get: function() {
      return false
    },
  },
  definitionChanged: {
    get: function() {
      return this._definitionChanged
    },
  },
  color: Cesium.createPropertyDescriptor('color'),
  duration: Cesium.createPropertyDescriptor('duration')
})
Spriteline1MaterialProperty.prototype.getType = function(time) {
  return 'Spriteline1'
}
Spriteline1MaterialProperty.prototype.getValue = function(
  time,
  result
) {
  if (!Cesium.defined(result)) {
    result = {}
  }
  result.image = this.image
  result.time =
      ((performance.now() - this._time) % this.duration) / this.duration
  return result
}
Spriteline1MaterialProperty.prototype.equals = function(e) {
  return (
    this === e ||
      (e instanceof Spriteline1MaterialProperty && this.duration === e.duration)
  )
}
Cesium.Spriteline1MaterialProperty = Spriteline1MaterialProperty
Cesium.Material.Spriteline1Type = 'Spriteline1'
Cesium.Material.Spriteline1Source = `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
vec4 colorImage = texture2D(image, vec2(fract(st.s - time), st.t));
material.alpha = colorImage.a;
material.diffuse = colorImage.rgb * 1.5 ;
return material;
}
`
// st :二维纹理坐标
// czm_material:保存可用于照明的材质信息
Cesium.Material._materialCache.addMaterial(Cesium.Material.Spriteline1Type, {
  fabric: {
    type: Cesium.Material.Spriteline1Type,
    uniforms: {
      color: new Cesium.Color(1, 0, 0, 0.5),
      image: '',
      transparent: true,
      time: 20,
    },
    source: Cesium.Material.Spriteline1Source,
  },
  translucent: function(material) {
    return true
  },
})

2、调用方法 实现效果

function drawWall(viewer) {
  let arr = []; // 经纬度
  geojson.features[0].geometry.coordinates[0][0].forEach((item) => {
    arr.push(item[0]);
    arr.push(item[1]);
  });
  let polygonEntity = new Cesium.Entity({
    polygon: {
      hierarchy: {
        positions: Cesium.Cartesian3.fromDegreesArray([
          60, 0, 60, 90, 160, 90, 160, 0,
        ]),
        holes: [
          {
            positions: Cesium.Cartesian3.fromDegreesArray(arr),
          },
        ],
      },
      material: Cesium.Color.fromCssColorString("#0c4a98").withAlpha(0.6),
    },

    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArray(arr),
      width: 3,
      material: new Cesium.Spriteline1MaterialProperty(
        2000,
        "图片材质路径"
      ),
    },
  });
  viewer.entities.add(polygonEntity);
}

线材质流动效果

1、先封装一个LaserPolylineTrailLinkMaterialProperty文件

// 激光材质类
export function LaserPolylineTrailLinkMaterialProperty(duration, color) {
    this._definitionChanged = new Cesium.Event();
    this._color = undefined;
    this._colorSubscription = undefined;
    this.color = color;
    this.duration = duration;
    this._time = new Date().getTime();
}

Object.defineProperties(LaserPolylineTrailLinkMaterialProperty.prototype, {
    isConstant: {
        get: function () {
            return false;
        },
    },
    definitionChanged: {
        get: function () {
            return this._definitionChanged;
        },
    },
    color: Cesium.createPropertyDescriptor("color"),
});

LaserPolylineTrailLinkMaterialProperty.prototype.getType = function (time) {
    return "PolylineTrailLink";
};

LaserPolylineTrailLinkMaterialProperty.prototype.getValue = function (
    time,
    result
) {
    if (!Cesium.defined(result)) {
        result = {};
    }
    result.color = Cesium.Property.getValueOrClonedDefault(
        this._color,
        time,
        Cesium.Color.WHITE,
        result.color
    );
    result.image = Cesium.Material.PolylineTrailLinkImage;
    console.log(this.duration);
    result.time =
        ((new Date().getTime() - this._time) % this.duration) / this.duration;
    return result;
};

LaserPolylineTrailLinkMaterialProperty.prototype.equals = function (other) {
    return (
        this === other ||
        (other instanceof LaserPolylineTrailLinkMaterialProperty &&
            Cesium.Property.equals(this._color, other._color))
    );
};

Cesium.LaserPolylineTrailLinkMaterialProperty = LaserPolylineTrailLinkMaterialProperty;
Cesium.Material.PolylineTrailLinkType = "PolylineTrailLink";
Cesium.Material.PolylineTrailLinkImage = "/img/roldline.png";
Cesium.Material.PolylineTrailLinkSource =
    "czm_material czm_getMaterial(czm_materialInput materialInput)\n\
   { czm_material material = czm_getDefaultMaterial(materialInput); vec2 st = materialInput.st;\n\
      vec4 colorImage = texture2D(image, vec2(fract(st.s - time), st.t));\n\
       material.alpha = colorImage.a * color.a;\n\
       material.diffuse = (colorImage.rgb + color.rgb) / 2.0;\n\
       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: 20,
            },
            source: Cesium.Material.PolylineTrailLinkSource,
        },
        translucent: function (material) {
            return true;
        },
    }
);

!!!!Cesium.Material.PolylineTrailLinkImage 这一块代码是给图片材质的

直接在你用的文件 引入 调用


viewer.entities.add({
  id: "line" + index,
  polyline: {
    positions: [
      Cesium.Cartesian3.fromDegrees(
        经度,
        纬度,
        高度
      ),
      Cesium.Cartesian3.fromDegrees(
        经度,
        纬度,
        高度
      ),
    ],
    width: 5,
    material: new Cesium.LaserPolylineTrailLinkMaterialProperty(
      1000,
      Cesium.Color.WHITE
    ),
  },
});