效果:
核心代码:
/**
* @desc 通过圆心和半径绘制圆墙
* @param {Object} options
* {
dataSourceName: 'fence',//围栏source名
type: 'fence',//围栏类型
name: "ellipWall",//围栏名称
id:1,//围栏id
x:113.97012095140055,//围栏经度 +-180~
y:22.52298214113242,//围栏纬度 +-90~
// r:50,//围栏半径 默认为50米
// height: 15//围栏高度 默认为15
}
* @returns
*/
function createEllipWallGraphic(options={}){
let dataSource = new Cesium.CustomDataSource(options.dataSourceName || 'dataName');
let lineFlowMaterial = new LineFlowMaterial({//动画线材质
color: new Cesium.Color.fromCssColorString("#ff0000"),
duration: 2000, //时长,控制速度
url: 'map/textures/fence.png',
axisY: true
});
var ellipse = new Cesium.EllipseOutlineGeometry({
center : Cesium.Cartesian3.fromDegrees(options.x||113.97012095140055,options.y||22.52298214113242),
semiMajorAxis : options.r||50,
semiMinorAxis : options.r||50,
// granularity:0.5
// rotation : Cesium.Math.toRadians(60.0)
});
var geometry = Cesium.EllipseOutlineGeometry.createGeometry(ellipse);
var circlepoints =[];
var values = geometry.attributes.position.values;
if (!values) return;
var ilen = values.length / 3; //数组中以笛卡尔坐标进行存储 每3个值一个坐标
for (var i = 0; i < ilen; i++) {
var xyz = new Cesium.Cartesian3(values[i * 3], values[i * 3 + 1], values[i * 3 + 2]); //笛卡尔
circlepoints.push(xyz);
}
circlepoints.push(circlepoints[0])
let maximumHeights=[]
let minimumHeights=[]
circlepoints.forEach(item=>{
maximumHeights.push(options.height||15)
minimumHeights.push(0)
})
dataSource.entities.add(
{
name: options.name||"fence",
prop: options,
id: `${options.type||"fence"}_${options.id}`,
wall: {
positions: circlepoints,
maximumHeights: maximumHeights,
minimumHeights: minimumHeights,
material: lineFlowMaterial
},
});
viewer.dataSources.add(dataSource);
}
使用:
createEllipWallGraphic(
{
dataSourceName: 'fence',//围栏source名
type: 'fence',//围栏类型
name: "ellipWall",//围栏名称
id:1,//围栏id
x:113.97012095140055,//围栏经度 +-180~
y:22.52298214113242,//围栏纬度 +-90~
// r:50,//围栏半径 默认为50米
// height: 15//围栏高度 默认为15
}
)
核心代码解释:
EllipseOutlineGeometry 先绘制一个线性圆 获取坐标点
Cartesian3 数组中以笛卡尔坐标进行存储 每3个值一个坐标
circlepoints.push(circlepoints[0]) 获取的geom数组不是闭合的(首尾坐标不一样) 需要手动闭合,将最后一个坐标手动填充
最大高度和最低高度:个数需要与笛卡尔坐标数组一一对应 比如有五个点组成的闭合矩形 则需要五个最高和最低的数组 例如maximumHeights:[15,15,15,15,15]
来源:
所以这里我们需要循环添加最大和最小高度:
circlepoints.forEach(item=>{
maximumHeights.push(options.height||15)
minimumHeights.push(0)
})
======================================
LineFlowMaterial 代码
var createClass = function() {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}()
var defaultColor = new Cesium.Color(0, 0, 0, 0);
var defaultBgColor = new Cesium.Color(1, 1, 1);
var LineFlowMaterial = function () {
//========== 构造方法 ==========
function LineFlowMaterial(options) {
options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);
this._definitionChanged = new Cesium.Event();
this._color = undefined;
this._colorSubscription = undefined;
this.color = Cesium.defaultValue(options.color, defaultColor); //颜色
this.url = Cesium.defaultValue(options.url, undefined); //背景图片颜色
if (!this.url) return;
this.axisY = Boolean(options.axisY);
this.bgUrl = Cesium.defaultValue(options.bgUrl, undefined); //背景图片颜色
this.bgColor = Cesium.defaultValue(options.bgColor, defaultBgColor); //背景图片颜色
this._duration = options.duration || 1000; //时长
var _material = getImageMaterial(this.url, this.bgUrl, options.repeat, Boolean(options.axisY), this.bgColor);
this._materialType = _material.type; //材质类型
this._materialImage = _material.image; //材质图片
this._time = undefined;
}
//========== 对外属性 ==========
createClass(LineFlowMaterial, [{
key: "getType",
//========== 方法 ==========
/**
* Gets the {@link Cesium.Material} type at the provided time.
*
* @param {JulianDate} time The time for which to retrieve the type.
* @returns {String} The type of material.
*/
value: function getType(time) {
return this._materialType;
}
/**
* Gets the value of the property at the provided time.
*
* @param {JulianDate} time The time for which to retrieve the value.
* @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned.
* @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied.
*/
}, {
key: "getValue",
value: function getValue(time, result) {
if (!Cesium.defined(result)) {
result = {};
}
result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color);
result.image = this._materialImage;
if (this._time === undefined) {
this._time = new Date().getTime();
}
result.time = (new Date().getTime() - this._time) / this._duration;
return result;
}
/**
* Compares this property to the provided property and returns
* <code>true</code> if they are equal, <code>false</code> otherwise.
*
* @param {Cesium.Property} [other] The other property.
* @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise.
*/
}, {
key: "equals",
value: function equals(other) {
return this === other || //
other instanceof LineFlowMaterial && Cesium.Property.equals(this._color, other._color);
}
}, {
key: "isConstant",
get: function get() {
return false;
}
}, {
key: "definitionChanged",
get: function get() {
return this._definitionChanged;
}
}]);
return LineFlowMaterial;
}();
Object.defineProperties(LineFlowMaterial.prototype, {
/**
* Gets or sets the Cesium.Property specifying the {@link Cesium.Color} of the line.
* @memberof PolylineGlowMaterialProperty.prototype
* @type {Cesium.Property}
*/
color: Cesium.createPropertyDescriptor('color')
});
//静态方法,处理材质
var cacheIdx = 0;
var nameEx = "AnimationLine";
function getImageMaterial(imgurl, bgUrl, repeat, axisY, bgColor) {
cacheIdx++;
var typeName = nameEx + cacheIdx + "Type";
var imageName = nameEx + cacheIdx + "Image";
Cesium.Material[typeName] = typeName;
Cesium.Material[imageName] = imgurl;
let source1 = `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = repeat * materialInput.st;
vec4 colorImage = texture2D(image, vec2(fract((axisY?st.t:st.s) - time), st.t));
if(color.a == 0.0)
{
material.alpha = colorImage.a;
material.diffuse = colorImage.rgb;
}
else
{
material.alpha = colorImage.a * color.a;
material.diffuse = max(color.rgb * material.alpha * 3.0, color.rgb);
}
vec4 colorBG = texture2D(image2,materialInput.st);
if(colorBG.a>0.5){
material.diffuse = bgColor.rgb;
}
return material;
}
`
let source2 = `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = repeat * materialInput.st;
vec4 colorImage = texture2D(image, vec2(fract((axisY?st.t:st.s) - time), st.t));
if(color.a == 0.0)
{
material.alpha = colorImage.a;
material.diffuse = colorImage.rgb;
}
else
{
material.alpha = colorImage.a * color.a;
material.diffuse = max(color.rgb * material.alpha * 3.0, color.rgb);
}
return material;
}
`
if (bgUrl) {
//存在2张url的,用叠加融合的效果
Cesium.Material._materialCache.addMaterial(Cesium.Material[typeName], {
fabric: {
type: Cesium.Material.PolylineArrowLinkType,
uniforms: {
color: new Cesium.Color(1, 0, 0, 1.0),
image: Cesium.Material[imageName],
time: 0,
repeat: repeat || new Cesium.Cartesian2(1.0, 1.0),
axisY: axisY,
image2: bgUrl,
bgColor: bgColor
},
source: source1
},
translucent: function translucent() {
return true;
}
});
} else {
Cesium.Material._materialCache.addMaterial(Cesium.Material[typeName], {
fabric: {
type: typeName,
uniforms: {
color: new Cesium.Color(1, 0, 0, 1.0),
image: Cesium.Material[imageName],
time: 0,
repeat: repeat || new Cesium.Cartesian2(1.0, 1.0),
axisY: axisY
},
source: source2
},
translucent: function translucent() {
return true;
}
});
}
return {
type: Cesium.Material[typeName],
image: Cesium.Material[imageName]
};
}
export {
LineFlowMaterial
}
图片: