需求:要做个喷水的效果,于是看了网上的粒子系统发现基本都是管网demo的,于是自己写一个。
效果一:
代码:
const viewer = new Cesium.Viewer("cesiumContainer", {
shouldAnimate: true,
});
function computeModelMatrix(position) {
let center = Cesium.Cartesian3.fromDegrees(120.40100613624982, 36.09030781, -5)
let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);
return modelMatrix;
}
// 计算粒子发射器的位置姿态
function computeEmitterodelMatrix() {
let hpr = Cesium.HeadingPitchRoll.fromDegrees(0, 0, 0);//!!!发射粒子的方向
let trs = new Cesium.TranslationRotationScale();
trs.translation = Cesium.Cartesian3.fromElements(0, 0, 0);
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);
let Matrix4 = Cesium.Matrix4.fromTranslationRotationScale(trs);
return Matrix4
}
let particle = new Cesium.ParticleSystem({
image: "../SampleData/smoke.png",
// 从绿色到白色淡出
startColor: Cesium.Color.LIGHTSEAGREEN.withAlpha(0.8),
endColor: Cesium.Color.WHITE.withAlpha(0.0),
// 粒子的大小是由imageSize决定可通过下面参数改变
// imageSize: new Cesium.Cartesian2(5, 5), //慎用容易造成卡顿
// 随机化粒子大小
// minimumImageSize : new Cesium.Cartesian2(5, 5),
// maximumImageSize : new Cesium.Cartesian2(10,10),
// 通过startScale和endScale使粒子随着时间的推移而增大或缩小。
startscale: 1,// 初始缩放比例
endScale: 50,// 最终缩放比例
// speed: 200,
minimumSpeed: 180,
maximumSpeed: 200,
sizelnMeters: false, //使用米为单位,位false时以像素位单位
emissionRate: 1000,// 发射速率
// bursts : [// 每秒发射多少粒子,可以改变粒子的浓度
// new Cesium.ParticleBurst({time : 5.0, minimum : 300, maximum : 500}),
// new Cesium.ParticleBurst({time : 10.0, minimum : 50, maximum : 100}),
// new Cesium.ParticleBurst({time : 15.0, minimum : 200, maximum : 300})
// ],
lifetime: 0.2, // 粒子寿命 秒
// 也可以用下面位每个粒子随机寿命
// minimumParticlelife: 1.5,
// maximumParticleLife: 2,
// loop: false,// 是否一直循环
// 4种发射器类型
// emitter: new Cesium.BoxEmitter(new Cesium.Cartesian3(5.0, 5.0, 5.0)),// 盒子发射器
// emitter: new Cesium.CircleEmitter(5.0),// 圆形发射器
// emitter: new Cesium.SphereEmitter(5.0),// 球形发射器
emitter: new Cesium.ConeEmitter(Cesium.Math.toRadians(30.0)),// 锥形发射器
modelMatrix: computeModelMatrix({ lon: 120.3918010, lat: 36.0733867, alt: 41 }),// 粒子系统位置矩阵
emitterwodellatrix: computeEmitterodelMatrix(),// 发射器转换为世界坐标
// 增加重力场影像,
updateCallback: applyGravity,
});
var gravityVector = new Cesium.Cartesian3();
var gravity = -70;// !!!重力方向向上向下 -(9.8*9.8)
function applyGravity(p, dt) {
var position = p.position;
Cesium.Cartesian3.normalize(position, gravityVector);
Cesium.Cartesian3.multiplyByScalar(gravityVector, gravity * dt, gravityVector);
p.velocity = Cesium.Cartesian3.add(p.velocity, gravityVector, p.velocity);
}
viewer.scene.primitives.add(particle)
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(120.3927743, 36.0841218, 160),
orientation: {
heading: Cesium.Math.toRadians(45),
pitch: Cesium.Math.toRadians(-2),
roll: Cesium.Math.toRadians(0),
},
});
可以修改参数得到自己喜欢的效果。
效果二:不带重力场的:
效果三:
//水蔓延
_viewer.scene.primitives.add(new Cesium.ParticleSystem({
image: require('@/assets/smoke.png'),
startColor: Cesium.Color.CADETBLUE,
endColor: Cesium.Color.WHITE.withAlpha(0.0),
startscale: 10,// 初始缩放比例
endScale: 30,// 最终缩放比例
minimumSpeed: 20,
maximumSpeed: 50,
sizelnMeters: false, //使用米为单位,位false时以像素位单位
emissionRate: 1000,
lifetime: 0.2,
emitter: new Cesium.ConeEmitter(Cesium.Math.toRadians(90.0)),// 锥形发射器
modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(_postion),// 粒子系统位置矩阵
emitterwodellatrix: ()=>{
let hpr = Cesium.HeadingPitchRoll.fromDegrees(0, 0, 0);//!!!发射粒子的方向
let trs = new Cesium.TranslationRotationScale();
trs.translation = Cesium.Cartesian3.fromElements(0, 0, 0);
trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);
let Matrix4 = Cesium.Matrix4.fromTranslationRotationScale(trs);
return Matrix4
},
// 增加重力场
updateCallback: (p, dt) =>{
let gravityVector = new Cesium.Cartesian3();
let position = p.position;
Cesium.Cartesian3.normalize(position, gravityVector);
Cesium.Cartesian3.multiplyByScalar(gravityVector, -1 * dt, gravityVector);
p.velocity = Cesium.Cartesian3.add(p.velocity, gravityVector, p.velocity);
},
}))
效果四:
let _postion = Cesium.Cartesian3.fromDegrees(...overflowPointData.postion)
let _color = overflowPointData.type ==0? Cesium.Color.fromCssColorString('#00FFFF').withAlpha(0.9):Cesium.Color.fromCssColorString('#1E90FF').withAlpha(0.9);
// 视频播放
let videoElement = document.getElementById("waterVideo")
videoElement.play();
_viewer.entities.add({
position: _postion,
name: 'entityOverflowPoint',
point: {
pixelSize: 10,
color: _color,
scaleByDistance: new Cesium.NearFarScalar(3000, 1, 10000, 0.3),
},
ellipse: {
semiMinorAxis: new Cesium.CallbackProperty(() => {
return _this.currentProgress<40?40:_this.currentProgress;
}, false),
semiMajorAxis: new Cesium.CallbackProperty(() => {
return _this.currentProgress<40?40:_this.currentProgress;
}, false),
height: -20,
material: videoElement,
// semiMinorAxis: 100,
// semiMajorAxis: 100,
},
})
圆柱改变大小:
// // 圆柱大小改变
// let s1 = 0
// let s2 = 0
// _viewer.entities.add({
// position: _postion,
// name: 'entityOverflowPoint',
// point: {
// pixelSize: 10,
// color: _color,
// scaleByDistance: new Cesium.NearFarScalar(3000, 1, 10000, 0.3),
// },
// ellipse: {
// semiMinorAxis: new Cesium.CallbackProperty(() => {
// s1 = s1++ < 100 ? s1 : 10
// return s1
// }, false),
// semiMajorAxis: new Cesium.CallbackProperty(() => {
// s2 = s2++ < 100 ? s2 : 10
// return s2
// }, false),
// height: -20,
// extrudedHeight: 20,
// material:_color,
// // material: videoElement,
// // semiMinorAxis: 100,
// // semiMajorAxis: 100,
// // stRotation: new Cesium.CallbackProperty(() =>{
// // s1 += 0.01;
// // return rotation;
// // }, false),
// },
// })