File
Constructor
constructor(babylonIntegration: BabylonIntegration, amountParticles: number, animationDuration: number, animationName: ParticleAnimName, startPosition: Vector3)
|
Parameters :
-
babylonIntegration
-
startPosition
Vectors of starting position
-
amountParticles
amount of particles into the scene
-
animationDuration
|
Methods
|
Private init
|
init()
|
|
Returns: void
|
|
Public runParticles
|
runParticles()
|
|
Returns: void
|
|
Private recycleParticle
|
recycleParticle(particle: SolidParticle)
|
Particles during the animation
Returns: void
|
|
explosionAnim
|
explosionAnim(particle: SolidParticle)
|
|
Returns: void
|
|
amountParticles
|
amountParticles: number
|
|
animationDuration
|
animationDuration: number
|
|
animationName
|
animationName: ParticleAnimName
|
|
currentSPS
|
currentSPS: SolidParticleSystem
|
|
observer
|
observer: Observer<any>
|
|
position
|
position: Vector3
|
import { Mesh, Vector3, SolidParticleSystem,
SolidParticle, Observer,MeshBuilder, CubicEase,
Animation, EasingFunction, Scalar,Color4 } from "@babylonjs/core";
import { AppUtils } from "../app-utils";
import { BabylonIntegration } from "./babylon-integration";
export enum ParticleAnimName {
explosion,
basket
}
export class BabylonJs5Confetti {
babylonIntegration: BabylonIntegration;
mesh: Mesh;
position: Vector3;
amountParticles: number;
currentSPS: SolidParticleSystem;
observer: Observer<any>;
animationDuration: number;
animationName: ParticleAnimName;
/**
* https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_intro
*
* @param babylonIntegration BabylonIntegration
* @param startPosition Vectors of starting position
* @param amountParticles amount of particles into the scene
* @param animationDuration duration in miliseconds
*/
constructor(
babylonIntegration: BabylonIntegration,
amountParticles: number,
animationDuration: number,
animationName: ParticleAnimName,
startPosition?: Vector3
) {
this.babylonIntegration = babylonIntegration;
if (startPosition) {
this.position = startPosition;
} else {
this.position = new Vector3(0, 0, 0);
}
this.animationName = animationName;
this.animationDuration = animationDuration;
this.amountParticles = amountParticles;
this.currentSPS = this.init();
this.currentSPS.setParticles();
}
private init() {
const SPS = new SolidParticleSystem("SPS", this.babylonIntegration.scene) as SolidParticleSystem;
const tetra = MeshBuilder.CreatePlane("tetra", { size: 0.18 });
SPS.addShape(tetra, this.amountParticles);
tetra.dispose();
this.mesh = SPS.buildMesh();
this.mesh.layerMask = this.babylonIntegration.camera.layerMask;
SPS.initParticles = () => {
for (let p = 0; p < SPS.nbParticles; p++) {
this.recycleParticle(SPS.particles[p]);
}
};
SPS.initParticles();
return SPS;
}
/**
* Start animation
*/
public async runParticles() {
let gravity: number;
this.currentSPS.updateParticle = particle => {
gravity = this.animationName === ParticleAnimName.basket ? -0.005 : -0.0003;
particle.velocity.y += gravity;
particle.position.addInPlace(particle.velocity); // update particle new position
particle.rotation.addInPlace(particle.velocity);
return particle;
};
this.observer = this.babylonIntegration.scene.onAfterRenderObservable.add(async () => {
this.currentSPS.setParticles();
});
await AppUtils.timeOut(this.animationDuration);
const ease = new CubicEase();
ease.setEasingMode(EasingFunction.EASINGMODE_EASEINOUT);
const fade = Animation.CreateAndStartAnimation("fm1", this.mesh, "visibility", 60, 60, this.mesh.visibility, 0, 0, ease);
fade.onAnimationEnd = () => {
if (this.babylonIntegration.scene) {
// verify if scene existe maybe we already leave the page at the end of the activity
this.babylonIntegration.scene.onAfterRenderObservable.remove(this.observer);
}
this.currentSPS.dispose();
};
fade.disposeOnEnd = true;
}
/**
* Particles during the animation
*/
private recycleParticle(particle: SolidParticle) {
if (this.animationName === ParticleAnimName.explosion) {
this.explosionAnim(particle);
}
}
/**
* Confetti explosion anim
*
* @param particle SolidParticle
*/
explosionAnim(particle: SolidParticle) {
const speed = 0.3;
particle.position.x = this.position.x;
particle.position.y = this.position.y;
particle.position.z = this.position.z;
particle.rotation.x = Scalar.RandomRange(-Math.PI, Math.PI);
particle.rotation.y = Scalar.RandomRange(-Math.PI, Math.PI);
particle.rotation.z = Scalar.RandomRange(-Math.PI, Math.PI);
const hexColorsAccepted = ["#a864fd", "#29cdff", "#78ff44", "#ff718d", "#fdff6a", "#02FEFF", "#6D2EF1"];
particle.color = Color4.FromHexString(hexColorsAccepted[Math.floor(Math.random() * hexColorsAccepted.length)]);
particle.velocity.x = Scalar.RandomRange(-0.2 * speed, 0.2 * speed);
particle.velocity.z = Scalar.RandomRange(-0.2 * speed, 0.2 * speed);
particle.velocity.y = Scalar.RandomRange(0.01, 0.12);
}
}