目录
一、第一种方式
二、第二种方式
1.安装gsap
2.引入
一、第一种方式
使用viewer.clock
Clock文档
viewer.clock文档
vec4 colorImage = texture2D(image, vec2(fract(st.s - time), st.t));这里,因为使用的是高版本的cesium1.108,直接写texture2D会报错:
报错原因:Cesium 自 1.102.0 开始,为了更好支持跨平台,尤其是移动端,Cesium 默认使用 WebGL2 上下文,如果想使用 WebGL1 上下文,需要在地球初始化的时候设置相应的参数。为了在 WebGL2 上下文中工作,任何自定义材质、自定义图元和自定义着色器都需要升级到使用 GLSL 300。
1. 初始化地球时(不推荐),传入参数,使用 WebGL1 上下文
const viewer = new Viewer("cesiumContainer", {
// 指定上下文
contextOptions: {
requestWebgl1: true,
},
});
2. 修正 GLSL 代码(推荐)
错误代码(texture2D)
vec4 colorImage = texture2D(image, vec2(fract(st.s - time), st.t))
修正为:
vec4 colorImage = texture(image, vec2(fract(st.s - time), st.t));
Cesium 对象已经被其他库或代码修改为不可扩展,导致你无法向它添加新的属性或方法。为了解决这个问题,可以考虑使用另一个对象来替代 Cesium 对象,并向它添加你需要的属性和方法,就可以了
import * as Cesium from "cesium";
// 创建一个新对象,包含所有原始的 Cesium 属性和方法
const CesiumExtensions = Object.assign({}, Cesium);
// 向该对象添加新的属性和方法
CesiumExtensions.myCustomMethod = function() {
// ...
};
// 将原始的 Cesium 对象替换为新的对象
window.Cesium = CesiumExtensions;
首先需要使用import("./data/基础管线.json").then(res=>{})异步加载json文件,其次依次遍历,使用Cesium.Cartesian3.fromDegreesArray()方法将经纬度坐标转换为笛卡尔坐标,设置geometry的默认颜色、线宽,Cesium.PolylineGeometry创建线段的几何实例,创建一个新的Cesium.Material对象,并设置其fabric属性,用于定义材质的外观和行为。
在czm_material czm_getMaterial(czm_materialInput materialInput)函数中,使用texture()函数获取当前时间下的纹理颜色,并将其作为材质的漫反射颜色。再将纹理颜色的alpha值设置为材质的透明度。最后,同时将材质返回给Cesium进行渲染。然后将单个geometry合并一次传输,提高渲染效率。最后通过CesiumViewer.clock.onTick事件,根据当前时间更新材质中的time属性。这个属性用于控制纹理的平移,从而实现流动线的效果。
viewer.clock.onTick.addEventListener(function (clock) {
const startTime = Cesium.JulianDate.toDate(
viewer.clock.startTime
).getTime();
const currentTime = Cesium.JulianDate.toDate(
clock.currentTime
).getTime();
const elapsedTime = (currentTime - startTime) / 1000.0;
material.uniforms.time = elapsedTime;
});
DrawGaspAnimatGroundPolylinePrimitiveFun4() {
import("./data/基础管线.json").then((res) => {
console.log("res", res);
let InitXList = [];
let InitYList = [];
this.primitiveCollection = new Cesium.PrimitiveCollection();
let instanceList = [];
res.Response.Pipe.map((ele, index) => {
let PipeLists = [];
ele.map((el) => {
PipeLists.push(+el.X, +el.Y);
InitXList.push(+el.X);
InitYList.push(+el.Y);
});
const polyline = new Cesium.PolylineGeometry({
positions: Cesium.Cartesian3.fromDegreesArray(PipeLists),
width: 2,
vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT,
});
const polygon = new Cesium.GeometryInstance({
geometry: polyline,
id: index + Math.random(new Date()),
});
instanceList.push(polygon);
});
/* ********************** */
let imageUrl = require("./data/Water_1_M_Flow3.jpg");
const material = new Cesium.Material({
fabric: {
type: "Spriteline1",
uniforms: {
color: Cesium.Color.WHITE,
image: imageUrl,
transparent: true,
time: 0,
},
source: `
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 - time), st.t));
material.alpha = colorImage.a;
material.diffuse = colorImage.rgb / 2.0;
return material;
}
`,
},
});
this.primitiveCollection.add(
new Cesium.Primitive({
geometryInstances: instanceList,
appearance: new Cesium.PolylineMaterialAppearance({
flat: true,
material: material,
}),
})
);
viewer.scene.primitives.add(this.primitiveCollection);
let XList = InitXList.sort((a, b) => a - b);
let YList = InitYList.sort((a, b) => a - b);
viewer.camera.setView({
destination: Cesium.Rectangle.fromDegrees(
XList[0],
YList[0],
XList[XList.length - 1],
YList[YList.length - 1]
),
});
viewer.clock.onTick.addEventListener(function (clock) {
const startTime = Cesium.JulianDate.toDate(
viewer.clock.startTime
).getTime();
const currentTime = Cesium.JulianDate.toDate(
clock.currentTime
).getTime();
const elapsedTime = (currentTime - startTime) / 1000.0;
material.uniforms.time = elapsedTime;
});
/* ********************** */
});
},
二、第二种方式
1.安装gsap
npm install gsap
2.引入
import gsap from "gsap";
DrawGaspAnimatGroundPolylinePrimitiveFun3() {
import("./data/基础管线.json").then((res) => {
console.log("res", res);
let InitXList = [];
let InitYList = [];
this.primitiveCollection = new Cesium.PrimitiveCollection();
let instanceList = [];
res.Response.Pipe.map((ele, index) => {
let PipeLists = [];
ele.map((el) => {
PipeLists.push(+el.X, +el.Y);
InitXList.push(+el.X);
InitYList.push(+el.Y);
});
const polyline = new Cesium.PolylineGeometry({
positions: Cesium.Cartesian3.fromDegreesArray(PipeLists),
width: 2,
vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT,
});
const polygon = new Cesium.GeometryInstance({
geometry: polyline,
id: `Polyline${index}`,
});
instanceList.push(polygon);
});
/* ********************** */
let imageUrl = require("./data/Water_1_M_Flow3.jpg");
const material = new Cesium.Material({
// fabric: {
// type: "Color",
// uniforms: {
// color: new Cesium.Color(0.0, 1.0, 0.0, 1.0),
// },
// },
fabric: {
//type: "Spriteline1",
uniforms: {
color: Cesium.Color.BLACK,
transparent: true,
uTime: 0,
uImg: imageUrl,
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
// 生成默认的基础材质
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
// 定义动画持续时间,从0到1
float durationTime = 1.0;
// 获取当前帧数,fract(x) 返回x的小数部分
float time = fract(czm_frameNumber / (60.0 * durationTime));
// 根据uv采样颜色
vec4 color = texture(uImg,vec2(fract(st.s - time),st.t));
material.alpha = color.a;
material.diffuse = color.rgb;
return material;
}
`,
},
});
/* ********************** */
//使用gasp实现补间动画,完成动画效果
gsap.to(material.uniforms, {
uTime: 1,
duration: 0.1,
repeat: -1,
ease: "linear",
yoyo: false,
});
/* ********************** */
this.primitiveCollection.add(
new Cesium.Primitive({
geometryInstances: instanceList,
appearance: new Cesium.PolylineMaterialAppearance({
flat: true,
material: material,
}),
})
);
viewer.scene.primitives.add(this.primitiveCollection);
let XList = InitXList.sort((a, b) => a - b);
let YList = InitYList.sort((a, b) => a - b);
viewer.camera.setView({
destination: Cesium.Rectangle.fromDegrees(
XList[0],
YList[0],
XList[XList.length - 1],
YList[YList.length - 1]
),
});
});
},
或者
DrawGaspAnimatGroundPolylinePrimitiveFun2() {
import("./data/基础管线.json").then((res) => {
console.log("res", res);
let InitXList = [];
let InitYList = [];
this.primitiveCollection = new Cesium.PrimitiveCollection();
let instanceList = [];
res.Response.Pipe.map((ele, index) => {
let PipeLists = [];
ele.map((el) => {
PipeLists.push(+el.X, +el.Y);
InitXList.push(+el.X);
InitYList.push(+el.Y);
});
//console.log("PipeLists", PipeLists);
let instance = new Cesium.GeometryInstance({
geometry: new Cesium.GroundPolylineGeometry({
positions: Cesium.Cartesian3.fromDegreesArray(PipeLists),
loop: true,
width: 4.0,
height: 300000,
extrudedHeight: 400000,
}),
attributes: {
// color: index % 2 ? Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString('blue').withAlpha(0.9)) : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString('red').withAlpha(0.9)),
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
Cesium.Color.fromCssColorString("#318ee4")
),
distanceDisplayCondition:
new Cesium.DistanceDisplayConditionGeometryInstanceAttribute(
1000,
30000
),
},
id: `Polyline${index}`,
});
instanceList.push(instance);
});
/* ********************** */
/* material */
let img = require("./data/Water_1_M_Flow3.jpg");
let material = new Cesium.Material({
fabric: {
uniforms: {
uTime: 0,
uImg: img,
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
// 生成默认的基础材质
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
// 定义动画持续时间,从0到1
float durationTime = 1.0;
// 获取当前帧数,fract(x) 返回x的小数部分
float time = fract(czm_frameNumber / (60.0 * durationTime));
// 根据uv采样颜色
vec4 color = texture(uImg,vec2(fract(st.s - time),st.t));
material.alpha = color.a;
material.diffuse = color.rgb;
return material;
}
`,
},
});
/*********************** */
//使用gasp实现补间动画,完成动画效果
gsap.to(material.uniforms, {
uTime: 1,
duration: 0.1,
repeat: -1,
ease: "linear",
yoyo: false,
});
/* ********************** */
let appearance = new Cesium.PolylineMaterialAppearance({
material: material,
aboveGround: false,
translucent: true,
});
this.groundPolylinePrimitive = new Cesium.GroundPolylinePrimitive({
geometryInstances: instanceList,
appearance: appearance,
});
this.primitiveCollection.add(this.groundPolylinePrimitive);
this.Tileset = viewer.scene.groundPrimitives.add(
this.primitiveCollection
);
let XList = InitXList.sort((a, b) => a - b);
let YList = InitYList.sort((a, b) => a - b);
viewer.camera.setView({
destination: Cesium.Rectangle.fromDegrees(
XList[0],
YList[0],
XList[XList.length - 1],
YList[YList.length - 1]
),
});
});
},
参考链接:https://blog.csdn.net/qq_37435704/article/details/130928690