网上找了很多案例,但是在使用中报错
流动线Cannot add property PolylineTrailMaterialProperty, object is not extensible
电子围栏Cannot add property DynamicWallMaterialProperty, object is not extensible,
在绘制流动线时,通过githup上找到解决方法https://gist.github.com/onsummer/02ea3f43c944cba467be585d76a6bb52
效果图片
PolylineTrailLinkMaterialProperty.js
import { Color, defined, Event, Material, Property } from 'cesium'
const PolylineTrailLinkType = 'PolylineTrailLink'
//time用于控制时间,值越小,速度越快,colorImage控制纹理样式,
// vec4 sampledColor = texture2D(image, vec2(fract(3.0*st.s - time), st.t));
//3.0代表纹理个数,st.t纵向,st.s横向,-time代表逆时针,+time代表顺时针
const PolylineTrailLinkSource = /* glsl */`
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
vec4 sampledColor = texture2D(image, vec2(fract(3.0*st.s - time), st.t));
material.alpha = sampledColor.a * color.a;
material.diffuse = (sampledColor.rgb + color.rgb) / 2.0;
return material;
}
`
class PolylineTrailLinkMaterialProperty {
/**
* 构造方法
* @param {String} image 图片路径,确保为程序能访问到的正常 URL
* @param {Cesium.Color} [color] 颜色,默认白色
* @param {Number} [duration] 持续时间(毫秒),默认1000
*/
constructor(image, color = Color.WHITE, duration = 1000) {
this._definitionChanged = new Event()
this._color = undefined
this._colorSubscription = undefined
this.color = color
this.duration = duration
this._time = new Date().getTime()
this.image = image
Material._materialCache.addMaterial(PolylineTrailLinkType, {
fabric: {
type: PolylineTrailLinkType,
uniforms: {
color: color.withAlpha(0.5), // 设为半透明
image: image,
time: 0
},
source: PolylineTrailLinkSource
},
translucent: () => true
})
}
get isConstant() {
return false
}
get definitionChanged() {
return this._definitionChanged
}
getType(_) {
return PolylineTrailLinkType
}
getValue(time, result) {
if (!defined(result)) {
result = {}
}
result.color = Property.getValueOrClonedDefault(this._color, time, Color.WHITE, result.color)
result.image = this.image
result.time = (new Date().getTime() - this._time) % this.duration / this.duration
return result
}
equals(other) {
return this === other ||
(other instanceof PolylineTrailLinkMaterialProperty && Property.equals(this._color, other._color))
}
}
export default PolylineTrailLinkMaterialProperty
组件中引用
import * as Cesium from 'cesium'
import PolylineTrailLinkMaterialProperty from './PolylineTrailLinkMaterialProperty.js'
let line = viewer.entities.add({
name:'PolylineTrailLink',
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([
113.5,
34.5,
113.5,
34.6,
113.5,
34.7,
113.5,
34.8,
113.5,
34.9,
]),
width:5,
material: new PolylineTrailLinkMaterialProperty(
"/流动线.png",Cesium.Color.fromBytes(255,0,0).withAlpha(0.8),
1000
),
},
});
viewer.flyTo(line);
在设置电子围栏时,也报错Cannot add property DynamicWallMaterialProperty, object is not extensible,参照流动线对网上报错的案例进行修改
DynamicWallMaterialProperty.js
import { Color, defined, Event, Material, Property } from "cesium";
//定义材质对象及变量
const DynamicWallType = "DynamicWall";
const DynamicWallSource = /* glsl */ `czm_material czm_getMaterial(czm_materialInput materialInput)
{
float time = czm_frameNumber/100.0;
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
vec4 colorImage = texture2D(image, vec2(fract(1.0*st.t - time), st.t));
material.alpha = colorImage.a * color.a;
material.diffuse = (colorImage.rgb+color.rgb)/2.0;
return material;
}`; //由上到下
class DynamicWallMaterialProperty {
constructor(image,color = Color.WHITE, duration = 1000) {
this._definitionChanged = new Event();
this._color = undefined;
this._colorSubscription = undefined;
this._time = new Date().getTime();
this.image = image;
this.color = color;
this.duration = duration;
//添加自定义材质
Material._materialCache.addMaterial(DynamicWallType, {
fabric: {
//纹理类型
type: DynamicWallType,
//传递给着色器的外部属性
uniforms: {
color: color.withAlpha(0.5), // 设为半透明
image: image,
time: -20,
},
//纹理资源
source: DynamicWallSource,
// source: _getDirectionWallShader({
// get: true,
// count: 3.0,
// freely: 'vertical',
// direction: '-'
// })
},
//是否透明
translucent: function (material) {
return true;
},
});
}
get isConstant() {
return false;
}
get definitionChanged() {
return this._definitionChanged;
}
getType(_) {
return DynamicWallType;
}
getValue(time, result) {
if (!defined(result)) {
result = {};
}
result.color = Property.getValueOrClonedDefault(
this._color,
time,
Color.WHITE,
result.color
);
result.image = this.image;
result.time =
((new Date().getTime() - this._time) % this.duration) / this.duration;
return result;
}
equals(other) {
return (
this === other ||
(other instanceof DynamicWallMaterialProperty &&
Property.equals(this._color, other._color))
);
}
}
export default DynamicWallMaterialProperty;
组件引用
<template>
<div id="cesiumContainer" class="fullSize"></div>
</template>
<script setup>
import * as Cesium from "cesium";
import { onMounted } from "vue";
import DynamicWallMaterialProperty from "./DynamicWallMaterialProperty.js";
// 配置Cesium的访问令牌
Cesium.Ion.defaultAccessToken = "你的CesiumIon访问令牌";
let viewer;
const initMap = () => {
viewer = new Cesium.Viewer("cesiumContainer", {
animation: false,
baseLayerPicker: false,
fullscreenButton: false,
geocoder: false,
homeButton: true,
infoBox: true,
sceneModePicker: false,
selectionIndicator: false,
timeline: false,
shouldAnimate: true,
navigationHelpButton: false,
terrainProvider: Cesium.createWorldTerrain(),
});
viewer._cesiumWidget._creditContainer.style.display = "none";
const ett = viewer.entities.add({
name: "动态立体墙",
wall: {
positions: Cesium.Cartesian3.fromDegreesArray([117.154815, 31.853495, 117.181255, 31.854257, 117.182284, 31.848255, 117.184748, 31.840141, 117.180557, 31.835556, 117.180023, 31.833741, 117.166846, 31.833737, 117.155531, 31.833151, 117.154787, 31.835978, 117.151994, 31.839036, 117.150691, 31.8416, 117.151215, 31.844734, 117.154457, 31.848152, 117.154815, 31.853495]),
maximumHeights: [600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600],
minimumHeights: [43.9, 49.4, 38.7, 40, 54, 51, 66.7, 44.6, 41.2, 31.2, 50.1, 53.8, 46.9, 43.9],
material: new DynamicWallMaterialProperty('/电子围栏1.png', Cesium.Color.ORANGE, 2000)
}
});
viewer.flyTo(ett);
};
onMounted(() => {
initMap();
});
</script>
<style>
#cesiumContainer {
width: 100vw;
height: 100vh;
overflow: hidden;
}
</style>