@tsparticles/plugin-emitters
Advanced tools
Comparing version 3.0.0-beta.3 to 3.0.0-beta.4
import { Vector, calcPositionOrRandomFromSizeRanged, deepExtend, getRangeValue, getSize, isPointInside, itemFromSingleOrMultiple, randomInRange, rangeColorToHsl, } from "@tsparticles/engine"; | ||
import { Emitter } from "./Options/Classes/Emitter.js"; | ||
import { EmitterSize } from "./Options/Classes/EmitterSize.js"; | ||
function setParticlesOptionsColor(particlesOptions, color) { | ||
if (particlesOptions.color) { | ||
particlesOptions.color.value = color; | ||
} | ||
else { | ||
particlesOptions.color = { | ||
value: color, | ||
}; | ||
} | ||
} | ||
export class EmitterInstance { | ||
@@ -8,9 +18,7 @@ constructor(engine, emitters, container, options, position) { | ||
this.container = container; | ||
this._calcPosition = () => { | ||
return calcPositionOrRandomFromSizeRanged({ | ||
size: this.container.canvas.size, | ||
position: this.options.position, | ||
}); | ||
}; | ||
this._destroy = () => { | ||
this._mutationObserver?.disconnect(); | ||
this._mutationObserver = undefined; | ||
this._resizeObserver?.disconnect(); | ||
this._resizeObserver = undefined; | ||
this.emitters.removeEmitter(this); | ||
@@ -24,36 +32,2 @@ this._engine.dispatchEvent("emitterDestroyed", { | ||
}; | ||
this._emit = () => { | ||
if (this._paused) { | ||
return; | ||
} | ||
const quantity = getRangeValue(this.options.rate.quantity); | ||
this._emitParticles(quantity); | ||
}; | ||
this._emitParticles = (quantity) => { | ||
const position = this.getPosition(), size = this.getSize(), singleParticlesOptions = itemFromSingleOrMultiple(this._particlesOptions); | ||
for (let i = 0; i < quantity; i++) { | ||
const particlesOptions = deepExtend({}, singleParticlesOptions); | ||
if (this.spawnColor) { | ||
const hslAnimation = this.options.spawnColor?.animation; | ||
if (hslAnimation) { | ||
this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360); | ||
this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100); | ||
this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100); | ||
} | ||
if (!particlesOptions.color) { | ||
particlesOptions.color = { | ||
value: this.spawnColor, | ||
}; | ||
} | ||
else { | ||
particlesOptions.color.value = this.spawnColor; | ||
} | ||
} | ||
if (!position) { | ||
return; | ||
} | ||
const pPosition = this._shape?.randomPosition(position, size, this.fill) ?? position; | ||
this.container.particles.addParticle(pPosition, particlesOptions); | ||
} | ||
}; | ||
this._prepareToDie = () => { | ||
@@ -94,3 +68,2 @@ if (this._paused) { | ||
this.name = this.options.name; | ||
this._shape = this._engine.emitterShapeManager?.getShape(this.options.shape); | ||
this.fill = this.options.fill; | ||
@@ -108,15 +81,26 @@ this._firstSpawn = !this.options.life.wait; | ||
this._particlesOptions = particlesOptions; | ||
this.size = | ||
this.options.size ?? | ||
(() => { | ||
const size = new EmitterSize(); | ||
size.load({ | ||
height: 0, | ||
mode: "percent", | ||
width: 0, | ||
}); | ||
return size; | ||
})(); | ||
this._size = this._calcSize(); | ||
this.size = getSize(this._size, this.container.canvas.size); | ||
this._lifeCount = this.options.life.count ?? -1; | ||
this._immortal = this._lifeCount <= 0; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
this._mutationObserver = new MutationObserver(() => { | ||
this.resize(); | ||
}); | ||
this._resizeObserver = new ResizeObserver(() => { | ||
this.resize(); | ||
}); | ||
this._mutationObserver.observe(element, { | ||
attributes: true, | ||
attributeFilter: ["style", "width", "height"], | ||
}); | ||
this._resizeObserver.observe(element); | ||
} | ||
} | ||
const shapeOptions = this.options.shape, shapeGenerator = this._engine.emitterShapeManager?.getShapeGenerator(shapeOptions.type); | ||
if (shapeGenerator) { | ||
this._shape = shapeGenerator.generate(this.position, this.size, this.fill, shapeOptions.options); | ||
} | ||
this._engine.dispatchEvent("emitterCreated", { | ||
@@ -138,29 +122,5 @@ container, | ||
} | ||
getPosition() { | ||
if (this.options.domId) { | ||
const container = this.container, element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio, | ||
y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return this.position; | ||
async init() { | ||
await this._shape?.init(); | ||
} | ||
getSize() { | ||
const container = this.container; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
width: elRect.width * container.retina.pixelRatio, | ||
height: elRect.height * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return getSize(this.size, container.canvas.size); | ||
} | ||
pause() { | ||
@@ -195,4 +155,7 @@ if (this._paused) { | ||
: this._calcPosition(); | ||
this._size = this._calcSize(); | ||
this.size = getSize(this._size, this.container.canvas.size); | ||
this._shape?.resize(this.position, this.size); | ||
} | ||
update(delta) { | ||
async update(delta) { | ||
if (this._paused) { | ||
@@ -208,3 +171,3 @@ return; | ||
this._startParticlesAdded = true; | ||
this._emitParticles(this.options.startCount); | ||
await this._emitParticles(this.options.startCount); | ||
} | ||
@@ -252,2 +215,92 @@ if (this._duration !== undefined) { | ||
} | ||
_calcPosition() { | ||
if (this.options.domId) { | ||
const container = this.container, element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio, | ||
y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return calcPositionOrRandomFromSizeRanged({ | ||
size: this.container.canvas.size, | ||
position: this.options.position, | ||
}); | ||
} | ||
_calcSize() { | ||
const container = this.container; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
width: elRect.width * container.retina.pixelRatio, | ||
height: elRect.height * container.retina.pixelRatio, | ||
mode: "precise", | ||
}; | ||
} | ||
} | ||
return (this.options.size ?? | ||
(() => { | ||
const size = new EmitterSize(); | ||
size.load({ | ||
height: 0, | ||
mode: "percent", | ||
width: 0, | ||
}); | ||
return size; | ||
})()); | ||
} | ||
async _emit() { | ||
if (this._paused) { | ||
return; | ||
} | ||
const quantity = getRangeValue(this.options.rate.quantity); | ||
await this._emitParticles(quantity); | ||
} | ||
async _emitParticles(quantity) { | ||
const singleParticlesOptions = itemFromSingleOrMultiple(this._particlesOptions); | ||
for (let i = 0; i < quantity; i++) { | ||
const particlesOptions = deepExtend({}, singleParticlesOptions); | ||
if (this.spawnColor) { | ||
const hslAnimation = this.options.spawnColor?.animation; | ||
if (hslAnimation) { | ||
this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360); | ||
this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100); | ||
this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100); | ||
} | ||
setParticlesOptionsColor(particlesOptions, this.spawnColor); | ||
} | ||
const shapeOptions = this.options.shape; | ||
let position = this.position; | ||
if (this._shape) { | ||
const shapePosData = await this._shape.randomPosition(); | ||
if (shapePosData) { | ||
position = shapePosData.position; | ||
const replaceData = shapeOptions.replace; | ||
if (replaceData.color && shapePosData.color) { | ||
setParticlesOptionsColor(particlesOptions, shapePosData.color); | ||
} | ||
if (replaceData.opacity) { | ||
if (particlesOptions.opacity) { | ||
particlesOptions.opacity.value = shapePosData.opacity; | ||
} | ||
else { | ||
particlesOptions.opacity = { | ||
value: shapePosData.opacity, | ||
}; | ||
} | ||
} | ||
} | ||
else { | ||
position = null; | ||
} | ||
} | ||
if (position) { | ||
this.container.particles.addParticle(position, particlesOptions); | ||
} | ||
} | ||
} | ||
} |
@@ -20,3 +20,3 @@ import { arrayRandomIndex, executeOnSingleOrMultiple, isArray, isNumber, itemFromArray, } from "@tsparticles/engine"; | ||
: this.array.find((t) => t.name === idxOrName); | ||
container.addEmitter = (options, position) => this.addEmitter(options, position); | ||
container.addEmitter = async (options, position) => this.addEmitter(options, position); | ||
container.removeEmitter = (idxOrName) => { | ||
@@ -41,6 +41,7 @@ const emitter = container.getEmitter(idxOrName); | ||
} | ||
addEmitter(options, position) { | ||
async addEmitter(options, position) { | ||
const emitterOptions = new Emitter(); | ||
emitterOptions.load(options); | ||
const emitter = new EmitterInstance(this._engine, this, this.container, emitterOptions, position); | ||
await emitter.init(); | ||
this.array.push(emitter); | ||
@@ -89,7 +90,7 @@ return emitter; | ||
for (const emitterOptions of this.emitters) { | ||
this.addEmitter(emitterOptions); | ||
await this.addEmitter(emitterOptions); | ||
} | ||
} | ||
else { | ||
this.addEmitter(this.emitters); | ||
await this.addEmitter(this.emitters); | ||
} | ||
@@ -121,7 +122,7 @@ } | ||
} | ||
update(delta) { | ||
async update(delta) { | ||
for (const emitter of this.array) { | ||
emitter.update(delta); | ||
await emitter.update(delta); | ||
} | ||
} | ||
} |
import { executeOnSingleOrMultiple, isArray, isInArray, } from "@tsparticles/engine"; | ||
import { CircleShape } from "./Shapes/Circle/CircleShape.js"; | ||
import { Emitter } from "./Options/Classes/Emitter.js"; | ||
import { Emitters } from "./Emitters.js"; | ||
import { ShapeManager } from "./ShapeManager.js"; | ||
import { SquareShape } from "./Shapes/Square/SquareShape.js"; | ||
class EmittersPlugin { | ||
@@ -97,5 +95,5 @@ constructor(engine) { | ||
} | ||
if (!engine.addEmitterShape) { | ||
engine.addEmitterShape = (name, shape) => { | ||
engine.emitterShapeManager?.addShape(name, shape); | ||
if (!engine.addEmitterShapeGenerator) { | ||
engine.addEmitterShapeGenerator = (name, generator) => { | ||
engine.emitterShapeManager?.addShapeGenerator(name, generator); | ||
}; | ||
@@ -105,8 +103,9 @@ } | ||
await engine.addPlugin(plugin, refresh); | ||
engine.addEmitterShape("circle", new CircleShape()); | ||
engine.addEmitterShape("square", new SquareShape()); | ||
} | ||
export * from "./EmitterContainer.js"; | ||
export * from "./EmitterShapeBase.js"; | ||
export * from "./EmittersEngine.js"; | ||
export * from "./IEmitterShape.js"; | ||
export * from "./IEmitterShapeGenerator.js"; | ||
export * from "./Enums/EmitterClickMode.js"; | ||
export * from "./Enums/EmitterShapeType.js"; | ||
export * from "./IRandomPositionData.js"; |
import { AnimatableColor, deepExtend, executeOnSingleOrMultiple, setRangeValue, } from "@tsparticles/engine"; | ||
import { EmitterLife } from "./EmitterLife.js"; | ||
import { EmitterRate } from "./EmitterRate.js"; | ||
import { EmitterShape } from "./EmitterShape.js"; | ||
import { EmitterSize } from "./EmitterSize.js"; | ||
@@ -11,3 +12,3 @@ export class Emitter { | ||
this.rate = new EmitterRate(); | ||
this.shape = "square"; | ||
this.shape = new EmitterShape(); | ||
this.startCount = 0; | ||
@@ -41,5 +42,3 @@ } | ||
this.rate.load(data.rate); | ||
if (data.shape !== undefined) { | ||
this.shape = data.shape; | ||
} | ||
this.shape.load(data.shape); | ||
if (data.position !== undefined) { | ||
@@ -46,0 +45,0 @@ this.position = {}; |
@@ -1,2 +0,2 @@ | ||
const shapes = new Map(); | ||
const shapeGeneratorss = new Map(); | ||
export class ShapeManager { | ||
@@ -6,13 +6,13 @@ constructor(engine) { | ||
} | ||
addShape(name, drawer) { | ||
if (!this.getShape(name)) { | ||
shapes.set(name, drawer); | ||
addShapeGenerator(name, generator) { | ||
if (!this.getShapeGenerator(name)) { | ||
shapeGeneratorss.set(name, generator); | ||
} | ||
} | ||
getShape(name) { | ||
return shapes.get(name); | ||
getShapeGenerator(name) { | ||
return shapeGeneratorss.get(name); | ||
} | ||
getSupportedShapes() { | ||
return shapes.keys(); | ||
getSupportedShapeGenerators() { | ||
return shapeGeneratorss.keys(); | ||
} | ||
} |
@@ -7,2 +7,12 @@ "use strict"; | ||
const EmitterSize_js_1 = require("./Options/Classes/EmitterSize.js"); | ||
function setParticlesOptionsColor(particlesOptions, color) { | ||
if (particlesOptions.color) { | ||
particlesOptions.color.value = color; | ||
} | ||
else { | ||
particlesOptions.color = { | ||
value: color, | ||
}; | ||
} | ||
} | ||
class EmitterInstance { | ||
@@ -12,9 +22,7 @@ constructor(engine, emitters, container, options, position) { | ||
this.container = container; | ||
this._calcPosition = () => { | ||
return (0, engine_1.calcPositionOrRandomFromSizeRanged)({ | ||
size: this.container.canvas.size, | ||
position: this.options.position, | ||
}); | ||
}; | ||
this._destroy = () => { | ||
this._mutationObserver?.disconnect(); | ||
this._mutationObserver = undefined; | ||
this._resizeObserver?.disconnect(); | ||
this._resizeObserver = undefined; | ||
this.emitters.removeEmitter(this); | ||
@@ -28,36 +36,2 @@ this._engine.dispatchEvent("emitterDestroyed", { | ||
}; | ||
this._emit = () => { | ||
if (this._paused) { | ||
return; | ||
} | ||
const quantity = (0, engine_1.getRangeValue)(this.options.rate.quantity); | ||
this._emitParticles(quantity); | ||
}; | ||
this._emitParticles = (quantity) => { | ||
const position = this.getPosition(), size = this.getSize(), singleParticlesOptions = (0, engine_1.itemFromSingleOrMultiple)(this._particlesOptions); | ||
for (let i = 0; i < quantity; i++) { | ||
const particlesOptions = (0, engine_1.deepExtend)({}, singleParticlesOptions); | ||
if (this.spawnColor) { | ||
const hslAnimation = this.options.spawnColor?.animation; | ||
if (hslAnimation) { | ||
this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360); | ||
this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100); | ||
this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100); | ||
} | ||
if (!particlesOptions.color) { | ||
particlesOptions.color = { | ||
value: this.spawnColor, | ||
}; | ||
} | ||
else { | ||
particlesOptions.color.value = this.spawnColor; | ||
} | ||
} | ||
if (!position) { | ||
return; | ||
} | ||
const pPosition = this._shape?.randomPosition(position, size, this.fill) ?? position; | ||
this.container.particles.addParticle(pPosition, particlesOptions); | ||
} | ||
}; | ||
this._prepareToDie = () => { | ||
@@ -98,3 +72,2 @@ if (this._paused) { | ||
this.name = this.options.name; | ||
this._shape = this._engine.emitterShapeManager?.getShape(this.options.shape); | ||
this.fill = this.options.fill; | ||
@@ -112,15 +85,26 @@ this._firstSpawn = !this.options.life.wait; | ||
this._particlesOptions = particlesOptions; | ||
this.size = | ||
this.options.size ?? | ||
(() => { | ||
const size = new EmitterSize_js_1.EmitterSize(); | ||
size.load({ | ||
height: 0, | ||
mode: "percent", | ||
width: 0, | ||
}); | ||
return size; | ||
})(); | ||
this._size = this._calcSize(); | ||
this.size = (0, engine_1.getSize)(this._size, this.container.canvas.size); | ||
this._lifeCount = this.options.life.count ?? -1; | ||
this._immortal = this._lifeCount <= 0; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
this._mutationObserver = new MutationObserver(() => { | ||
this.resize(); | ||
}); | ||
this._resizeObserver = new ResizeObserver(() => { | ||
this.resize(); | ||
}); | ||
this._mutationObserver.observe(element, { | ||
attributes: true, | ||
attributeFilter: ["style", "width", "height"], | ||
}); | ||
this._resizeObserver.observe(element); | ||
} | ||
} | ||
const shapeOptions = this.options.shape, shapeGenerator = this._engine.emitterShapeManager?.getShapeGenerator(shapeOptions.type); | ||
if (shapeGenerator) { | ||
this._shape = shapeGenerator.generate(this.position, this.size, this.fill, shapeOptions.options); | ||
} | ||
this._engine.dispatchEvent("emitterCreated", { | ||
@@ -142,29 +126,5 @@ container, | ||
} | ||
getPosition() { | ||
if (this.options.domId) { | ||
const container = this.container, element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio, | ||
y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return this.position; | ||
async init() { | ||
await this._shape?.init(); | ||
} | ||
getSize() { | ||
const container = this.container; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
width: elRect.width * container.retina.pixelRatio, | ||
height: elRect.height * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return (0, engine_1.getSize)(this.size, container.canvas.size); | ||
} | ||
pause() { | ||
@@ -199,4 +159,7 @@ if (this._paused) { | ||
: this._calcPosition(); | ||
this._size = this._calcSize(); | ||
this.size = (0, engine_1.getSize)(this._size, this.container.canvas.size); | ||
this._shape?.resize(this.position, this.size); | ||
} | ||
update(delta) { | ||
async update(delta) { | ||
if (this._paused) { | ||
@@ -212,3 +175,3 @@ return; | ||
this._startParticlesAdded = true; | ||
this._emitParticles(this.options.startCount); | ||
await this._emitParticles(this.options.startCount); | ||
} | ||
@@ -256,3 +219,93 @@ if (this._duration !== undefined) { | ||
} | ||
_calcPosition() { | ||
if (this.options.domId) { | ||
const container = this.container, element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio, | ||
y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return (0, engine_1.calcPositionOrRandomFromSizeRanged)({ | ||
size: this.container.canvas.size, | ||
position: this.options.position, | ||
}); | ||
} | ||
_calcSize() { | ||
const container = this.container; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
width: elRect.width * container.retina.pixelRatio, | ||
height: elRect.height * container.retina.pixelRatio, | ||
mode: "precise", | ||
}; | ||
} | ||
} | ||
return (this.options.size ?? | ||
(() => { | ||
const size = new EmitterSize_js_1.EmitterSize(); | ||
size.load({ | ||
height: 0, | ||
mode: "percent", | ||
width: 0, | ||
}); | ||
return size; | ||
})()); | ||
} | ||
async _emit() { | ||
if (this._paused) { | ||
return; | ||
} | ||
const quantity = (0, engine_1.getRangeValue)(this.options.rate.quantity); | ||
await this._emitParticles(quantity); | ||
} | ||
async _emitParticles(quantity) { | ||
const singleParticlesOptions = (0, engine_1.itemFromSingleOrMultiple)(this._particlesOptions); | ||
for (let i = 0; i < quantity; i++) { | ||
const particlesOptions = (0, engine_1.deepExtend)({}, singleParticlesOptions); | ||
if (this.spawnColor) { | ||
const hslAnimation = this.options.spawnColor?.animation; | ||
if (hslAnimation) { | ||
this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360); | ||
this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100); | ||
this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100); | ||
} | ||
setParticlesOptionsColor(particlesOptions, this.spawnColor); | ||
} | ||
const shapeOptions = this.options.shape; | ||
let position = this.position; | ||
if (this._shape) { | ||
const shapePosData = await this._shape.randomPosition(); | ||
if (shapePosData) { | ||
position = shapePosData.position; | ||
const replaceData = shapeOptions.replace; | ||
if (replaceData.color && shapePosData.color) { | ||
setParticlesOptionsColor(particlesOptions, shapePosData.color); | ||
} | ||
if (replaceData.opacity) { | ||
if (particlesOptions.opacity) { | ||
particlesOptions.opacity.value = shapePosData.opacity; | ||
} | ||
else { | ||
particlesOptions.opacity = { | ||
value: shapePosData.opacity, | ||
}; | ||
} | ||
} | ||
} | ||
else { | ||
position = null; | ||
} | ||
} | ||
if (position) { | ||
this.container.particles.addParticle(position, particlesOptions); | ||
} | ||
} | ||
} | ||
} | ||
exports.EmitterInstance = EmitterInstance; |
@@ -23,3 +23,3 @@ "use strict"; | ||
: this.array.find((t) => t.name === idxOrName); | ||
container.addEmitter = (options, position) => this.addEmitter(options, position); | ||
container.addEmitter = async (options, position) => this.addEmitter(options, position); | ||
container.removeEmitter = (idxOrName) => { | ||
@@ -44,6 +44,7 @@ const emitter = container.getEmitter(idxOrName); | ||
} | ||
addEmitter(options, position) { | ||
async addEmitter(options, position) { | ||
const emitterOptions = new Emitter_js_1.Emitter(); | ||
emitterOptions.load(options); | ||
const emitter = new EmitterInstance_js_1.EmitterInstance(this._engine, this, this.container, emitterOptions, position); | ||
await emitter.init(); | ||
this.array.push(emitter); | ||
@@ -92,7 +93,7 @@ return emitter; | ||
for (const emitterOptions of this.emitters) { | ||
this.addEmitter(emitterOptions); | ||
await this.addEmitter(emitterOptions); | ||
} | ||
} | ||
else { | ||
this.addEmitter(this.emitters); | ||
await this.addEmitter(this.emitters); | ||
} | ||
@@ -124,5 +125,5 @@ } | ||
} | ||
update(delta) { | ||
async update(delta) { | ||
for (const emitter of this.array) { | ||
emitter.update(delta); | ||
await emitter.update(delta); | ||
} | ||
@@ -129,0 +130,0 @@ } |
@@ -19,7 +19,5 @@ "use strict"; | ||
const engine_1 = require("@tsparticles/engine"); | ||
const CircleShape_js_1 = require("./Shapes/Circle/CircleShape.js"); | ||
const Emitter_js_1 = require("./Options/Classes/Emitter.js"); | ||
const Emitters_js_1 = require("./Emitters.js"); | ||
const ShapeManager_js_1 = require("./ShapeManager.js"); | ||
const SquareShape_js_1 = require("./Shapes/Square/SquareShape.js"); | ||
class EmittersPlugin { | ||
@@ -115,5 +113,5 @@ constructor(engine) { | ||
} | ||
if (!engine.addEmitterShape) { | ||
engine.addEmitterShape = (name, shape) => { | ||
engine.emitterShapeManager?.addShape(name, shape); | ||
if (!engine.addEmitterShapeGenerator) { | ||
engine.addEmitterShapeGenerator = (name, generator) => { | ||
engine.emitterShapeManager?.addShapeGenerator(name, generator); | ||
}; | ||
@@ -123,9 +121,10 @@ } | ||
await engine.addPlugin(plugin, refresh); | ||
engine.addEmitterShape("circle", new CircleShape_js_1.CircleShape()); | ||
engine.addEmitterShape("square", new SquareShape_js_1.SquareShape()); | ||
} | ||
exports.loadEmittersPlugin = loadEmittersPlugin; | ||
__exportStar(require("./EmitterContainer.js"), exports); | ||
__exportStar(require("./EmitterShapeBase.js"), exports); | ||
__exportStar(require("./EmittersEngine.js"), exports); | ||
__exportStar(require("./IEmitterShape.js"), exports); | ||
__exportStar(require("./IEmitterShapeGenerator.js"), exports); | ||
__exportStar(require("./Enums/EmitterClickMode.js"), exports); | ||
__exportStar(require("./Enums/EmitterShapeType.js"), exports); | ||
__exportStar(require("./IRandomPositionData.js"), exports); |
@@ -7,2 +7,3 @@ "use strict"; | ||
const EmitterRate_js_1 = require("./EmitterRate.js"); | ||
const EmitterShape_js_1 = require("./EmitterShape.js"); | ||
const EmitterSize_js_1 = require("./EmitterSize.js"); | ||
@@ -15,3 +16,3 @@ class Emitter { | ||
this.rate = new EmitterRate_js_1.EmitterRate(); | ||
this.shape = "square"; | ||
this.shape = new EmitterShape_js_1.EmitterShape(); | ||
this.startCount = 0; | ||
@@ -45,5 +46,3 @@ } | ||
this.rate.load(data.rate); | ||
if (data.shape !== undefined) { | ||
this.shape = data.shape; | ||
} | ||
this.shape.load(data.shape); | ||
if (data.position !== undefined) { | ||
@@ -50,0 +49,0 @@ this.position = {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ShapeManager = void 0; | ||
const shapes = new Map(); | ||
const shapeGeneratorss = new Map(); | ||
class ShapeManager { | ||
@@ -9,14 +9,14 @@ constructor(engine) { | ||
} | ||
addShape(name, drawer) { | ||
if (!this.getShape(name)) { | ||
shapes.set(name, drawer); | ||
addShapeGenerator(name, generator) { | ||
if (!this.getShapeGenerator(name)) { | ||
shapeGeneratorss.set(name, generator); | ||
} | ||
} | ||
getShape(name) { | ||
return shapes.get(name); | ||
getShapeGenerator(name) { | ||
return shapeGeneratorss.get(name); | ||
} | ||
getSupportedShapes() { | ||
return shapes.keys(); | ||
getSupportedShapeGenerators() { | ||
return shapeGeneratorss.keys(); | ||
} | ||
} | ||
exports.ShapeManager = ShapeManager; |
import { Vector, calcPositionOrRandomFromSizeRanged, deepExtend, getRangeValue, getSize, isPointInside, itemFromSingleOrMultiple, randomInRange, rangeColorToHsl, } from "@tsparticles/engine"; | ||
import { Emitter } from "./Options/Classes/Emitter.js"; | ||
import { EmitterSize } from "./Options/Classes/EmitterSize.js"; | ||
function setParticlesOptionsColor(particlesOptions, color) { | ||
if (particlesOptions.color) { | ||
particlesOptions.color.value = color; | ||
} | ||
else { | ||
particlesOptions.color = { | ||
value: color, | ||
}; | ||
} | ||
} | ||
export class EmitterInstance { | ||
@@ -8,9 +18,7 @@ constructor(engine, emitters, container, options, position) { | ||
this.container = container; | ||
this._calcPosition = () => { | ||
return calcPositionOrRandomFromSizeRanged({ | ||
size: this.container.canvas.size, | ||
position: this.options.position, | ||
}); | ||
}; | ||
this._destroy = () => { | ||
this._mutationObserver?.disconnect(); | ||
this._mutationObserver = undefined; | ||
this._resizeObserver?.disconnect(); | ||
this._resizeObserver = undefined; | ||
this.emitters.removeEmitter(this); | ||
@@ -24,36 +32,2 @@ this._engine.dispatchEvent("emitterDestroyed", { | ||
}; | ||
this._emit = () => { | ||
if (this._paused) { | ||
return; | ||
} | ||
const quantity = getRangeValue(this.options.rate.quantity); | ||
this._emitParticles(quantity); | ||
}; | ||
this._emitParticles = (quantity) => { | ||
const position = this.getPosition(), size = this.getSize(), singleParticlesOptions = itemFromSingleOrMultiple(this._particlesOptions); | ||
for (let i = 0; i < quantity; i++) { | ||
const particlesOptions = deepExtend({}, singleParticlesOptions); | ||
if (this.spawnColor) { | ||
const hslAnimation = this.options.spawnColor?.animation; | ||
if (hslAnimation) { | ||
this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360); | ||
this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100); | ||
this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100); | ||
} | ||
if (!particlesOptions.color) { | ||
particlesOptions.color = { | ||
value: this.spawnColor, | ||
}; | ||
} | ||
else { | ||
particlesOptions.color.value = this.spawnColor; | ||
} | ||
} | ||
if (!position) { | ||
return; | ||
} | ||
const pPosition = this._shape?.randomPosition(position, size, this.fill) ?? position; | ||
this.container.particles.addParticle(pPosition, particlesOptions); | ||
} | ||
}; | ||
this._prepareToDie = () => { | ||
@@ -94,3 +68,2 @@ if (this._paused) { | ||
this.name = this.options.name; | ||
this._shape = this._engine.emitterShapeManager?.getShape(this.options.shape); | ||
this.fill = this.options.fill; | ||
@@ -108,15 +81,26 @@ this._firstSpawn = !this.options.life.wait; | ||
this._particlesOptions = particlesOptions; | ||
this.size = | ||
this.options.size ?? | ||
(() => { | ||
const size = new EmitterSize(); | ||
size.load({ | ||
height: 0, | ||
mode: "percent", | ||
width: 0, | ||
}); | ||
return size; | ||
})(); | ||
this._size = this._calcSize(); | ||
this.size = getSize(this._size, this.container.canvas.size); | ||
this._lifeCount = this.options.life.count ?? -1; | ||
this._immortal = this._lifeCount <= 0; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
this._mutationObserver = new MutationObserver(() => { | ||
this.resize(); | ||
}); | ||
this._resizeObserver = new ResizeObserver(() => { | ||
this.resize(); | ||
}); | ||
this._mutationObserver.observe(element, { | ||
attributes: true, | ||
attributeFilter: ["style", "width", "height"], | ||
}); | ||
this._resizeObserver.observe(element); | ||
} | ||
} | ||
const shapeOptions = this.options.shape, shapeGenerator = this._engine.emitterShapeManager?.getShapeGenerator(shapeOptions.type); | ||
if (shapeGenerator) { | ||
this._shape = shapeGenerator.generate(this.position, this.size, this.fill, shapeOptions.options); | ||
} | ||
this._engine.dispatchEvent("emitterCreated", { | ||
@@ -138,29 +122,5 @@ container, | ||
} | ||
getPosition() { | ||
if (this.options.domId) { | ||
const container = this.container, element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio, | ||
y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return this.position; | ||
async init() { | ||
await this._shape?.init(); | ||
} | ||
getSize() { | ||
const container = this.container; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
width: elRect.width * container.retina.pixelRatio, | ||
height: elRect.height * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return getSize(this.size, container.canvas.size); | ||
} | ||
pause() { | ||
@@ -195,4 +155,7 @@ if (this._paused) { | ||
: this._calcPosition(); | ||
this._size = this._calcSize(); | ||
this.size = getSize(this._size, this.container.canvas.size); | ||
this._shape?.resize(this.position, this.size); | ||
} | ||
update(delta) { | ||
async update(delta) { | ||
if (this._paused) { | ||
@@ -208,3 +171,3 @@ return; | ||
this._startParticlesAdded = true; | ||
this._emitParticles(this.options.startCount); | ||
await this._emitParticles(this.options.startCount); | ||
} | ||
@@ -252,2 +215,92 @@ if (this._duration !== undefined) { | ||
} | ||
_calcPosition() { | ||
if (this.options.domId) { | ||
const container = this.container, element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio, | ||
y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return calcPositionOrRandomFromSizeRanged({ | ||
size: this.container.canvas.size, | ||
position: this.options.position, | ||
}); | ||
} | ||
_calcSize() { | ||
const container = this.container; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
width: elRect.width * container.retina.pixelRatio, | ||
height: elRect.height * container.retina.pixelRatio, | ||
mode: "precise", | ||
}; | ||
} | ||
} | ||
return (this.options.size ?? | ||
(() => { | ||
const size = new EmitterSize(); | ||
size.load({ | ||
height: 0, | ||
mode: "percent", | ||
width: 0, | ||
}); | ||
return size; | ||
})()); | ||
} | ||
async _emit() { | ||
if (this._paused) { | ||
return; | ||
} | ||
const quantity = getRangeValue(this.options.rate.quantity); | ||
await this._emitParticles(quantity); | ||
} | ||
async _emitParticles(quantity) { | ||
const singleParticlesOptions = itemFromSingleOrMultiple(this._particlesOptions); | ||
for (let i = 0; i < quantity; i++) { | ||
const particlesOptions = deepExtend({}, singleParticlesOptions); | ||
if (this.spawnColor) { | ||
const hslAnimation = this.options.spawnColor?.animation; | ||
if (hslAnimation) { | ||
this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360); | ||
this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100); | ||
this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100); | ||
} | ||
setParticlesOptionsColor(particlesOptions, this.spawnColor); | ||
} | ||
const shapeOptions = this.options.shape; | ||
let position = this.position; | ||
if (this._shape) { | ||
const shapePosData = await this._shape.randomPosition(); | ||
if (shapePosData) { | ||
position = shapePosData.position; | ||
const replaceData = shapeOptions.replace; | ||
if (replaceData.color && shapePosData.color) { | ||
setParticlesOptionsColor(particlesOptions, shapePosData.color); | ||
} | ||
if (replaceData.opacity) { | ||
if (particlesOptions.opacity) { | ||
particlesOptions.opacity.value = shapePosData.opacity; | ||
} | ||
else { | ||
particlesOptions.opacity = { | ||
value: shapePosData.opacity, | ||
}; | ||
} | ||
} | ||
} | ||
else { | ||
position = null; | ||
} | ||
} | ||
if (position) { | ||
this.container.particles.addParticle(position, particlesOptions); | ||
} | ||
} | ||
} | ||
} |
@@ -20,3 +20,3 @@ import { arrayRandomIndex, executeOnSingleOrMultiple, isArray, isNumber, itemFromArray, } from "@tsparticles/engine"; | ||
: this.array.find((t) => t.name === idxOrName); | ||
container.addEmitter = (options, position) => this.addEmitter(options, position); | ||
container.addEmitter = async (options, position) => this.addEmitter(options, position); | ||
container.removeEmitter = (idxOrName) => { | ||
@@ -41,6 +41,7 @@ const emitter = container.getEmitter(idxOrName); | ||
} | ||
addEmitter(options, position) { | ||
async addEmitter(options, position) { | ||
const emitterOptions = new Emitter(); | ||
emitterOptions.load(options); | ||
const emitter = new EmitterInstance(this._engine, this, this.container, emitterOptions, position); | ||
await emitter.init(); | ||
this.array.push(emitter); | ||
@@ -89,7 +90,7 @@ return emitter; | ||
for (const emitterOptions of this.emitters) { | ||
this.addEmitter(emitterOptions); | ||
await this.addEmitter(emitterOptions); | ||
} | ||
} | ||
else { | ||
this.addEmitter(this.emitters); | ||
await this.addEmitter(this.emitters); | ||
} | ||
@@ -121,7 +122,7 @@ } | ||
} | ||
update(delta) { | ||
async update(delta) { | ||
for (const emitter of this.array) { | ||
emitter.update(delta); | ||
await emitter.update(delta); | ||
} | ||
} | ||
} |
import { executeOnSingleOrMultiple, isArray, isInArray, } from "@tsparticles/engine"; | ||
import { CircleShape } from "./Shapes/Circle/CircleShape.js"; | ||
import { Emitter } from "./Options/Classes/Emitter.js"; | ||
import { Emitters } from "./Emitters.js"; | ||
import { ShapeManager } from "./ShapeManager.js"; | ||
import { SquareShape } from "./Shapes/Square/SquareShape.js"; | ||
class EmittersPlugin { | ||
@@ -97,5 +95,5 @@ constructor(engine) { | ||
} | ||
if (!engine.addEmitterShape) { | ||
engine.addEmitterShape = (name, shape) => { | ||
engine.emitterShapeManager?.addShape(name, shape); | ||
if (!engine.addEmitterShapeGenerator) { | ||
engine.addEmitterShapeGenerator = (name, generator) => { | ||
engine.emitterShapeManager?.addShapeGenerator(name, generator); | ||
}; | ||
@@ -105,8 +103,9 @@ } | ||
await engine.addPlugin(plugin, refresh); | ||
engine.addEmitterShape("circle", new CircleShape()); | ||
engine.addEmitterShape("square", new SquareShape()); | ||
} | ||
export * from "./EmitterContainer.js"; | ||
export * from "./EmitterShapeBase.js"; | ||
export * from "./EmittersEngine.js"; | ||
export * from "./IEmitterShape.js"; | ||
export * from "./IEmitterShapeGenerator.js"; | ||
export * from "./Enums/EmitterClickMode.js"; | ||
export * from "./Enums/EmitterShapeType.js"; | ||
export * from "./IRandomPositionData.js"; |
import { AnimatableColor, deepExtend, executeOnSingleOrMultiple, setRangeValue, } from "@tsparticles/engine"; | ||
import { EmitterLife } from "./EmitterLife.js"; | ||
import { EmitterRate } from "./EmitterRate.js"; | ||
import { EmitterShape } from "./EmitterShape.js"; | ||
import { EmitterSize } from "./EmitterSize.js"; | ||
@@ -11,3 +12,3 @@ export class Emitter { | ||
this.rate = new EmitterRate(); | ||
this.shape = "square"; | ||
this.shape = new EmitterShape(); | ||
this.startCount = 0; | ||
@@ -41,5 +42,3 @@ } | ||
this.rate.load(data.rate); | ||
if (data.shape !== undefined) { | ||
this.shape = data.shape; | ||
} | ||
this.shape.load(data.shape); | ||
if (data.position !== undefined) { | ||
@@ -46,0 +45,0 @@ this.position = {}; |
@@ -1,2 +0,2 @@ | ||
const shapes = new Map(); | ||
const shapeGeneratorss = new Map(); | ||
export class ShapeManager { | ||
@@ -6,13 +6,13 @@ constructor(engine) { | ||
} | ||
addShape(name, drawer) { | ||
if (!this.getShape(name)) { | ||
shapes.set(name, drawer); | ||
addShapeGenerator(name, generator) { | ||
if (!this.getShapeGenerator(name)) { | ||
shapeGeneratorss.set(name, generator); | ||
} | ||
} | ||
getShape(name) { | ||
return shapes.get(name); | ||
getShapeGenerator(name) { | ||
return shapeGeneratorss.get(name); | ||
} | ||
getSupportedShapes() { | ||
return shapes.keys(); | ||
getSupportedShapeGenerators() { | ||
return shapeGeneratorss.keys(); | ||
} | ||
} |
{ | ||
"name": "@tsparticles/plugin-emitters", | ||
"version": "3.0.0-beta.3", | ||
"version": "3.0.0-beta.4", | ||
"description": "tsParticles emitters plugin", | ||
@@ -63,3 +63,3 @@ "homepage": "https://particles.js.org", | ||
"canvas-confetti", | ||
"@tsparticles/plugin" | ||
"tsparticles-plugin" | ||
], | ||
@@ -90,3 +90,3 @@ "author": "Matteo Bruni <matteo.bruni@me.com>", | ||
"dependencies": { | ||
"@tsparticles/engine": "^3.0.0-beta.3" | ||
"@tsparticles/engine": "^3.0.0-beta.4" | ||
}, | ||
@@ -93,0 +93,0 @@ "publishConfig": { |
@@ -7,3 +7,3 @@ /*! | ||
* How to use? : Check the GitHub README | ||
* v3.0.0-beta.3 | ||
* v3.0.0-beta.4 | ||
*/ | ||
@@ -95,2 +95,3 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
__webpack_require__.d(__webpack_exports__, { | ||
EmitterShapeBase: () => (/* reexport */ EmitterShapeBase), | ||
loadEmittersPlugin: () => (/* binding */ loadEmittersPlugin) | ||
@@ -101,31 +102,2 @@ }); | ||
var engine_root_window_ = __webpack_require__(533); | ||
;// CONCATENATED MODULE: ./dist/browser/Shapes/Circle/CircleShape.js | ||
class CircleShape { | ||
randomPosition(position, size, fill) { | ||
const generateTheta = (x, y) => { | ||
const u = (0,engine_root_window_.getRandom)() / 4.0, | ||
theta = Math.atan(y / x * Math.tan(2 * Math.PI * u)), | ||
v = (0,engine_root_window_.getRandom)(); | ||
if (v < 0.25) { | ||
return theta; | ||
} else if (v < 0.5) { | ||
return Math.PI - theta; | ||
} else if (v < 0.75) { | ||
return Math.PI + theta; | ||
} else { | ||
return -theta; | ||
} | ||
}, | ||
radius = (x, y, theta) => x * y / Math.sqrt((y * Math.cos(theta)) ** 2 + (x * Math.sin(theta)) ** 2), | ||
[a, b] = [size.width / 2, size.height / 2], | ||
randomTheta = generateTheta(a, b), | ||
maxRadius = radius(a, b, randomTheta), | ||
randomRadius = fill ? maxRadius * Math.sqrt((0,engine_root_window_.getRandom)()) : maxRadius; | ||
return { | ||
x: position.x + randomRadius * Math.cos(randomTheta), | ||
y: position.y + randomRadius * Math.sin(randomTheta) | ||
}; | ||
} | ||
} | ||
;// CONCATENATED MODULE: ./dist/browser/Options/Classes/EmitterLife.js | ||
@@ -174,2 +146,42 @@ | ||
} | ||
;// CONCATENATED MODULE: ./dist/browser/Options/Classes/EmitterShapeReplace.js | ||
class EmitterShapeReplace { | ||
constructor() { | ||
this.color = false; | ||
this.opacity = false; | ||
} | ||
load(data) { | ||
if (!data) { | ||
return; | ||
} | ||
if (data.color !== undefined) { | ||
this.color = data.color; | ||
} | ||
if (data.opacity !== undefined) { | ||
this.opacity = data.opacity; | ||
} | ||
} | ||
} | ||
;// CONCATENATED MODULE: ./dist/browser/Options/Classes/EmitterShape.js | ||
class EmitterShape { | ||
constructor() { | ||
this.options = {}; | ||
this.replace = new EmitterShapeReplace(); | ||
this.type = "square"; | ||
} | ||
load(data) { | ||
if (!data) { | ||
return; | ||
} | ||
if (data.options !== undefined) { | ||
this.options = (0,engine_root_window_.deepExtend)({}, data.options ?? {}); | ||
} | ||
this.replace.load(data.replace); | ||
if (data.type !== undefined) { | ||
this.type = data.type; | ||
} | ||
} | ||
} | ||
;// CONCATENATED MODULE: ./dist/browser/Options/Classes/EmitterSize.js | ||
@@ -202,2 +214,3 @@ class EmitterSize { | ||
class Emitter { | ||
@@ -209,3 +222,3 @@ constructor() { | ||
this.rate = new EmitterRate(); | ||
this.shape = "square"; | ||
this.shape = new EmitterShape(); | ||
this.startCount = 0; | ||
@@ -239,5 +252,3 @@ } | ||
this.rate.load(data.rate); | ||
if (data.shape !== undefined) { | ||
this.shape = data.shape; | ||
} | ||
this.shape.load(data.shape); | ||
if (data.position !== undefined) { | ||
@@ -267,2 +278,11 @@ this.position = {}; | ||
function setParticlesOptionsColor(particlesOptions, color) { | ||
if (particlesOptions.color) { | ||
particlesOptions.color.value = color; | ||
} else { | ||
particlesOptions.color = { | ||
value: color | ||
}; | ||
} | ||
} | ||
class EmitterInstance { | ||
@@ -272,9 +292,7 @@ constructor(engine, emitters, container, options, position) { | ||
this.container = container; | ||
this._calcPosition = () => { | ||
return (0,engine_root_window_.calcPositionOrRandomFromSizeRanged)({ | ||
size: this.container.canvas.size, | ||
position: this.options.position | ||
}); | ||
}; | ||
this._destroy = () => { | ||
this._mutationObserver?.disconnect(); | ||
this._mutationObserver = undefined; | ||
this._resizeObserver?.disconnect(); | ||
this._resizeObserver = undefined; | ||
this.emitters.removeEmitter(this); | ||
@@ -288,37 +306,2 @@ this._engine.dispatchEvent("emitterDestroyed", { | ||
}; | ||
this._emit = () => { | ||
if (this._paused) { | ||
return; | ||
} | ||
const quantity = (0,engine_root_window_.getRangeValue)(this.options.rate.quantity); | ||
this._emitParticles(quantity); | ||
}; | ||
this._emitParticles = quantity => { | ||
const position = this.getPosition(), | ||
size = this.getSize(), | ||
singleParticlesOptions = (0,engine_root_window_.itemFromSingleOrMultiple)(this._particlesOptions); | ||
for (let i = 0; i < quantity; i++) { | ||
const particlesOptions = (0,engine_root_window_.deepExtend)({}, singleParticlesOptions); | ||
if (this.spawnColor) { | ||
const hslAnimation = this.options.spawnColor?.animation; | ||
if (hslAnimation) { | ||
this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360); | ||
this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100); | ||
this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100); | ||
} | ||
if (!particlesOptions.color) { | ||
particlesOptions.color = { | ||
value: this.spawnColor | ||
}; | ||
} else { | ||
particlesOptions.color.value = this.spawnColor; | ||
} | ||
} | ||
if (!position) { | ||
return; | ||
} | ||
const pPosition = this._shape?.randomPosition(position, size, this.fill) ?? position; | ||
this.container.particles.addParticle(pPosition, particlesOptions); | ||
} | ||
}; | ||
this._prepareToDie = () => { | ||
@@ -358,3 +341,2 @@ if (this._paused) { | ||
this.name = this.options.name; | ||
this._shape = this._engine.emitterShapeManager?.getShape(this.options.shape); | ||
this.fill = this.options.fill; | ||
@@ -372,13 +354,27 @@ this._firstSpawn = !this.options.life.wait; | ||
this._particlesOptions = particlesOptions; | ||
this.size = this.options.size ?? (() => { | ||
const size = new EmitterSize(); | ||
size.load({ | ||
height: 0, | ||
mode: "percent", | ||
width: 0 | ||
}); | ||
return size; | ||
})(); | ||
this._size = this._calcSize(); | ||
this.size = (0,engine_root_window_.getSize)(this._size, this.container.canvas.size); | ||
this._lifeCount = this.options.life.count ?? -1; | ||
this._immortal = this._lifeCount <= 0; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
this._mutationObserver = new MutationObserver(() => { | ||
this.resize(); | ||
}); | ||
this._resizeObserver = new ResizeObserver(() => { | ||
this.resize(); | ||
}); | ||
this._mutationObserver.observe(element, { | ||
attributes: true, | ||
attributeFilter: ["style", "width", "height"] | ||
}); | ||
this._resizeObserver.observe(element); | ||
} | ||
} | ||
const shapeOptions = this.options.shape, | ||
shapeGenerator = this._engine.emitterShapeManager?.getShapeGenerator(shapeOptions.type); | ||
if (shapeGenerator) { | ||
this._shape = shapeGenerator.generate(this.position, this.size, this.fill, shapeOptions.options); | ||
} | ||
this._engine.dispatchEvent("emitterCreated", { | ||
@@ -400,30 +396,5 @@ container, | ||
} | ||
getPosition() { | ||
if (this.options.domId) { | ||
const container = this.container, | ||
element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio, | ||
y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio | ||
}; | ||
} | ||
} | ||
return this.position; | ||
async init() { | ||
await this._shape?.init(); | ||
} | ||
getSize() { | ||
const container = this.container; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
width: elRect.width * container.retina.pixelRatio, | ||
height: elRect.height * container.retina.pixelRatio | ||
}; | ||
} | ||
} | ||
return (0,engine_root_window_.getSize)(this.size, container.canvas.size); | ||
} | ||
pause() { | ||
@@ -453,4 +424,7 @@ if (this._paused) { | ||
this.position = initialPosition && (0,engine_root_window_.isPointInside)(initialPosition, this.container.canvas.size, engine_root_window_.Vector.origin) ? initialPosition : this._calcPosition(); | ||
this._size = this._calcSize(); | ||
this.size = (0,engine_root_window_.getSize)(this._size, this.container.canvas.size); | ||
this._shape?.resize(this.position, this.size); | ||
} | ||
update(delta) { | ||
async update(delta) { | ||
if (this._paused) { | ||
@@ -466,3 +440,3 @@ return; | ||
this._startParticlesAdded = true; | ||
this._emitParticles(this.options.startCount); | ||
await this._emitParticles(this.options.startCount); | ||
} | ||
@@ -508,2 +482,90 @@ if (this._duration !== undefined) { | ||
} | ||
_calcPosition() { | ||
if (this.options.domId) { | ||
const container = this.container, | ||
element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio, | ||
y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio | ||
}; | ||
} | ||
} | ||
return (0,engine_root_window_.calcPositionOrRandomFromSizeRanged)({ | ||
size: this.container.canvas.size, | ||
position: this.options.position | ||
}); | ||
} | ||
_calcSize() { | ||
const container = this.container; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
width: elRect.width * container.retina.pixelRatio, | ||
height: elRect.height * container.retina.pixelRatio, | ||
mode: "precise" | ||
}; | ||
} | ||
} | ||
return this.options.size ?? (() => { | ||
const size = new EmitterSize(); | ||
size.load({ | ||
height: 0, | ||
mode: "percent", | ||
width: 0 | ||
}); | ||
return size; | ||
})(); | ||
} | ||
async _emit() { | ||
if (this._paused) { | ||
return; | ||
} | ||
const quantity = (0,engine_root_window_.getRangeValue)(this.options.rate.quantity); | ||
await this._emitParticles(quantity); | ||
} | ||
async _emitParticles(quantity) { | ||
const singleParticlesOptions = (0,engine_root_window_.itemFromSingleOrMultiple)(this._particlesOptions); | ||
for (let i = 0; i < quantity; i++) { | ||
const particlesOptions = (0,engine_root_window_.deepExtend)({}, singleParticlesOptions); | ||
if (this.spawnColor) { | ||
const hslAnimation = this.options.spawnColor?.animation; | ||
if (hslAnimation) { | ||
this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360); | ||
this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100); | ||
this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100); | ||
} | ||
setParticlesOptionsColor(particlesOptions, this.spawnColor); | ||
} | ||
const shapeOptions = this.options.shape; | ||
let position = this.position; | ||
if (this._shape) { | ||
const shapePosData = await this._shape.randomPosition(); | ||
if (shapePosData) { | ||
position = shapePosData.position; | ||
const replaceData = shapeOptions.replace; | ||
if (replaceData.color && shapePosData.color) { | ||
setParticlesOptionsColor(particlesOptions, shapePosData.color); | ||
} | ||
if (replaceData.opacity) { | ||
if (particlesOptions.opacity) { | ||
particlesOptions.opacity.value = shapePosData.opacity; | ||
} else { | ||
particlesOptions.opacity = { | ||
value: shapePosData.opacity | ||
}; | ||
} | ||
} | ||
} else { | ||
position = null; | ||
} | ||
} | ||
if (position) { | ||
this.container.particles.addParticle(position, particlesOptions); | ||
} | ||
} | ||
} | ||
} | ||
@@ -528,3 +590,3 @@ ;// CONCATENATED MODULE: ./dist/browser/Emitters.js | ||
container.getEmitter = idxOrName => idxOrName === undefined || (0,engine_root_window_.isNumber)(idxOrName) ? this.array[idxOrName || 0] : this.array.find(t => t.name === idxOrName); | ||
container.addEmitter = (options, position) => this.addEmitter(options, position); | ||
container.addEmitter = async (options, position) => this.addEmitter(options, position); | ||
container.removeEmitter = idxOrName => { | ||
@@ -549,6 +611,7 @@ const emitter = container.getEmitter(idxOrName); | ||
} | ||
addEmitter(options, position) { | ||
async addEmitter(options, position) { | ||
const emitterOptions = new Emitter(); | ||
emitterOptions.load(options); | ||
const emitter = new EmitterInstance(this._engine, this, this.container, emitterOptions, position); | ||
await emitter.init(); | ||
this.array.push(emitter); | ||
@@ -597,6 +660,6 @@ return emitter; | ||
for (const emitterOptions of this.emitters) { | ||
this.addEmitter(emitterOptions); | ||
await this.addEmitter(emitterOptions); | ||
} | ||
} else { | ||
this.addEmitter(this.emitters); | ||
await this.addEmitter(this.emitters); | ||
} | ||
@@ -628,5 +691,5 @@ } | ||
} | ||
update(delta) { | ||
async update(delta) { | ||
for (const emitter of this.array) { | ||
emitter.update(delta); | ||
await emitter.update(delta); | ||
} | ||
@@ -636,3 +699,3 @@ } | ||
;// CONCATENATED MODULE: ./dist/browser/ShapeManager.js | ||
const shapes = new Map(); | ||
const shapeGeneratorss = new Map(); | ||
class ShapeManager { | ||
@@ -642,56 +705,26 @@ constructor(engine) { | ||
} | ||
addShape(name, drawer) { | ||
if (!this.getShape(name)) { | ||
shapes.set(name, drawer); | ||
addShapeGenerator(name, generator) { | ||
if (!this.getShapeGenerator(name)) { | ||
shapeGeneratorss.set(name, generator); | ||
} | ||
} | ||
getShape(name) { | ||
return shapes.get(name); | ||
getShapeGenerator(name) { | ||
return shapeGeneratorss.get(name); | ||
} | ||
getSupportedShapes() { | ||
return shapes.keys(); | ||
getSupportedShapeGenerators() { | ||
return shapeGeneratorss.keys(); | ||
} | ||
} | ||
;// CONCATENATED MODULE: ./dist/browser/Shapes/Square/SquareShape.js | ||
function randomSquareCoordinate(position, offset) { | ||
return position + offset * ((0,engine_root_window_.getRandom)() - 0.5); | ||
} | ||
class SquareShape { | ||
randomPosition(position, size, fill) { | ||
if (fill) { | ||
return { | ||
x: randomSquareCoordinate(position.x, size.width), | ||
y: randomSquareCoordinate(position.y, size.height) | ||
}; | ||
} else { | ||
const halfW = size.width / 2, | ||
halfH = size.height / 2, | ||
side = Math.floor((0,engine_root_window_.getRandom)() * 4), | ||
v = ((0,engine_root_window_.getRandom)() - 0.5) * 2; | ||
switch (side) { | ||
case 0: | ||
return { | ||
x: position.x + v * halfW, | ||
y: position.y - halfH | ||
}; | ||
case 1: | ||
return { | ||
x: position.x - halfW, | ||
y: position.y + v * halfH | ||
}; | ||
case 2: | ||
return { | ||
x: position.x + v * halfW, | ||
y: position.y + halfH | ||
}; | ||
case 3: | ||
default: | ||
return { | ||
x: position.x + halfW, | ||
y: position.y + v * halfH | ||
}; | ||
} | ||
} | ||
;// CONCATENATED MODULE: ./dist/browser/EmitterShapeBase.js | ||
class EmitterShapeBase { | ||
constructor(position, size, fill, options) { | ||
this.position = position; | ||
this.size = size; | ||
this.fill = fill; | ||
this.options = options; | ||
} | ||
resize(position, size) { | ||
this.position = position; | ||
this.size = size; | ||
} | ||
} | ||
@@ -703,4 +736,2 @@ ;// CONCATENATED MODULE: ./dist/browser/index.js | ||
class EmittersPlugin { | ||
@@ -790,5 +821,5 @@ constructor(engine) { | ||
} | ||
if (!engine.addEmitterShape) { | ||
engine.addEmitterShape = (name, shape) => { | ||
engine.emitterShapeManager?.addShape(name, shape); | ||
if (!engine.addEmitterShapeGenerator) { | ||
engine.addEmitterShapeGenerator = (name, generator) => { | ||
engine.emitterShapeManager?.addShapeGenerator(name, generator); | ||
}; | ||
@@ -798,4 +829,2 @@ } | ||
await engine.addPlugin(plugin, refresh); | ||
engine.addEmitterShape("circle", new CircleShape()); | ||
engine.addEmitterShape("square", new SquareShape()); | ||
} | ||
@@ -806,2 +835,5 @@ | ||
})(); | ||
@@ -808,0 +840,0 @@ |
/*! For license information please see tsparticles.plugin.emitters.min.js.LICENSE.txt */ | ||
!function(t,i){if("object"==typeof exports&&"object"==typeof module)module.exports=i(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],i);else{var e="object"==typeof exports?i(require("@tsparticles/engine")):i(t.window);for(var s in e)("object"==typeof exports?exports:t)[s]=e[s]}}(this,(t=>(()=>{"use strict";var i={533:i=>{i.exports=t}},e={};function s(t){var n=e[t];if(void 0!==n)return n.exports;var o=e[t]={exports:{}};return i[t](o,o.exports,s),o.exports}s.d=(t,i)=>{for(var e in i)s.o(i,e)&&!s.o(t,e)&&Object.defineProperty(t,e,{enumerable:!0,get:i[e]})},s.o=(t,i)=>Object.prototype.hasOwnProperty.call(t,i),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var n={};return(()=>{s.r(n),s.d(n,{loadEmittersPlugin:()=>y});var t=s(533);class i{randomPosition(i,e,s){const[n,o]=[e.width/2,e.height/2],a=((i,e)=>{const s=(0,t.getRandom)()/4,n=Math.atan(e/i*Math.tan(2*Math.PI*s)),o=(0,t.getRandom)();return o<.25?n:o<.5?Math.PI-n:o<.75?Math.PI+n:-n})(n,o),r=(c=a,(l=n)*(d=o)/Math.sqrt((d*Math.cos(c))**2+(l*Math.sin(c))**2)),h=s?r*Math.sqrt((0,t.getRandom)()):r;var l,d,c;return{x:i.x+h*Math.cos(a),y:i.y+h*Math.sin(a)}}}class e{constructor(){this.wait=!1}load(i){i&&(void 0!==i.count&&(this.count=i.count),void 0!==i.delay&&(this.delay=(0,t.setRangeValue)(i.delay)),void 0!==i.duration&&(this.duration=(0,t.setRangeValue)(i.duration)),void 0!==i.wait&&(this.wait=i.wait))}}class o{constructor(){this.quantity=1,this.delay=.1}load(i){void 0!==i&&(void 0!==i.quantity&&(this.quantity=(0,t.setRangeValue)(i.quantity)),void 0!==i.delay&&(this.delay=(0,t.setRangeValue)(i.delay)))}}class a{constructor(){this.mode="percent",this.height=0,this.width=0}load(t){void 0!==t&&(void 0!==t.mode&&(this.mode=t.mode),void 0!==t.height&&(this.height=t.height),void 0!==t.width&&(this.width=t.width))}}class r{constructor(){this.autoPlay=!0,this.fill=!0,this.life=new e,this.rate=new o,this.shape="square",this.startCount=0}load(i){i&&(void 0!==i.autoPlay&&(this.autoPlay=i.autoPlay),void 0!==i.size&&(this.size||(this.size=new a),this.size.load(i.size)),void 0!==i.direction&&(this.direction=i.direction),this.domId=i.domId,void 0!==i.fill&&(this.fill=i.fill),this.life.load(i.life),this.name=i.name,this.particles=(0,t.executeOnSingleOrMultiple)(i.particles,(i=>(0,t.deepExtend)({},i))),this.rate.load(i.rate),void 0!==i.shape&&(this.shape=i.shape),void 0!==i.position&&(this.position={},void 0!==i.position.x&&(this.position.x=(0,t.setRangeValue)(i.position.x)),void 0!==i.position.y&&(this.position.y=(0,t.setRangeValue)(i.position.y))),void 0!==i.spawnColor&&(void 0===this.spawnColor&&(this.spawnColor=new t.AnimatableColor),this.spawnColor.load(i.spawnColor)),void 0!==i.startCount&&(this.startCount=i.startCount))}}class h{constructor(i,e,s,n,o){this.emitters=e,this.container=s,this._calcPosition=()=>(0,t.calcPositionOrRandomFromSizeRanged)({size:this.container.canvas.size,position:this.options.position}),this._destroy=()=>{this.emitters.removeEmitter(this),this._engine.dispatchEvent("emitterDestroyed",{container:this.container,data:{emitter:this}})},this._emit=()=>{if(this._paused)return;const i=(0,t.getRangeValue)(this.options.rate.quantity);this._emitParticles(i)},this._emitParticles=i=>{const e=this.getPosition(),s=this.getSize(),n=(0,t.itemFromSingleOrMultiple)(this._particlesOptions);for(let o=0;o<i;o++){const i=(0,t.deepExtend)({},n);if(this.spawnColor){const t=this.options.spawnColor?.animation;t&&(this.spawnColor.h=this._setColorAnimation(t.h,this.spawnColor.h,360),this.spawnColor.s=this._setColorAnimation(t.s,this.spawnColor.s,100),this.spawnColor.l=this._setColorAnimation(t.l,this.spawnColor.l,100)),i.color?i.color.value=this.spawnColor:i.color={value:this.spawnColor}}if(!e)return;const o=this._shape?.randomPosition(e,s,this.fill)??e;this.container.particles.addParticle(o,i)}},this._prepareToDie=()=>{if(this._paused)return;const i=void 0!==this.options.life?.duration?(0,t.getRangeValue)(this.options.life.duration):void 0;this.container.retina.reduceFactor&&(this._lifeCount>0||this._immortal)&&void 0!==i&&i>0&&(this._duration=1e3*i)},this._setColorAnimation=(i,e,s)=>{const n=this.container;if(!i.enable)return e;const o=(0,t.randomInRange)(i.offset),a=1e3*(0,t.getRangeValue)(this.options.rate.delay)/n.retina.reduceFactor;return(e+(0,t.getRangeValue)(i.speed??0)*n.fpsLimit/a+3.6*o)%s},this._engine=i,this._currentDuration=0,this._currentEmitDelay=0,this._currentSpawnDelay=0,this._initialPosition=o,n instanceof r?this.options=n:(this.options=new r,this.options.load(n)),this._spawnDelay=1e3*(0,t.getRangeValue)(this.options.life.delay??0)/this.container.retina.reduceFactor,this.position=this._initialPosition??this._calcPosition(),this.name=this.options.name,this._shape=this._engine.emitterShapeManager?.getShape(this.options.shape),this.fill=this.options.fill,this._firstSpawn=!this.options.life.wait,this._startParticlesAdded=!1;let h=(0,t.deepExtend)({},this.options.particles);h??={},h.move??={},h.move.direction??=this.options.direction,this.options.spawnColor&&(this.spawnColor=(0,t.rangeColorToHsl)(this.options.spawnColor)),this._paused=!this.options.autoPlay,this._particlesOptions=h,this.size=this.options.size??(()=>{const t=new a;return t.load({height:0,mode:"percent",width:0}),t})(),this._lifeCount=this.options.life.count??-1,this._immortal=this._lifeCount<=0,this._engine.dispatchEvent("emitterCreated",{container:s,data:{emitter:this}}),this.play()}externalPause(){this._paused=!0,this.pause()}externalPlay(){this._paused=!1,this.play()}getPosition(){if(this.options.domId){const t=this.container,i=document.getElementById(this.options.domId);if(i){const e=i.getBoundingClientRect();return{x:(e.x+e.width/2)*t.retina.pixelRatio,y:(e.y+e.height/2)*t.retina.pixelRatio}}}return this.position}getSize(){const i=this.container;if(this.options.domId){const t=document.getElementById(this.options.domId);if(t){const e=t.getBoundingClientRect();return{width:e.width*i.retina.pixelRatio,height:e.height*i.retina.pixelRatio}}}return(0,t.getSize)(this.size,i.canvas.size)}pause(){this._paused||delete this._emitDelay}play(){if(!this._paused&&this.container.retina.reduceFactor&&(this._lifeCount>0||this._immortal||!this.options.life.count)&&(this._firstSpawn||this._currentSpawnDelay>=(this._spawnDelay??0))){if(void 0===this._emitDelay){const i=(0,t.getRangeValue)(this.options.rate.delay);this._emitDelay=1e3*i/this.container.retina.reduceFactor}(this._lifeCount>0||this._immortal)&&this._prepareToDie()}}resize(){const i=this._initialPosition;this.position=i&&(0,t.isPointInside)(i,this.container.canvas.size,t.Vector.origin)?i:this._calcPosition()}update(i){this._paused||(this._firstSpawn&&(this._firstSpawn=!1,this._currentSpawnDelay=this._spawnDelay??0,this._currentEmitDelay=this._emitDelay??0),this._startParticlesAdded||(this._startParticlesAdded=!0,this._emitParticles(this.options.startCount)),void 0!==this._duration&&(this._currentDuration+=i.value,this._currentDuration>=this._duration&&(this.pause(),void 0!==this._spawnDelay&&delete this._spawnDelay,this._immortal||this._lifeCount--,this._lifeCount>0||this._immortal?(this.position=this._calcPosition(),this._spawnDelay=1e3*(0,t.getRangeValue)(this.options.life.delay??0)/this.container.retina.reduceFactor):this._destroy(),this._currentDuration-=this._duration,delete this._duration)),void 0!==this._spawnDelay&&(this._currentSpawnDelay+=i.value,this._currentSpawnDelay>=this._spawnDelay&&(this._engine.dispatchEvent("emitterPlay",{container:this.container}),this.play(),this._currentSpawnDelay-=this._currentSpawnDelay,delete this._spawnDelay)),void 0!==this._emitDelay&&(this._currentEmitDelay+=i.value,this._currentEmitDelay>=this._emitDelay&&(this._emit(),this._currentEmitDelay-=this._emitDelay)))}}class l{constructor(i,e){this.container=e,this._engine=i,this.array=[],this.emitters=[],this.interactivityEmitters={random:{count:1,enable:!1},value:[]},e.getEmitter=i=>void 0===i||(0,t.isNumber)(i)?this.array[i||0]:this.array.find((t=>t.name===i)),e.addEmitter=(t,i)=>this.addEmitter(t,i),e.removeEmitter=t=>{const i=e.getEmitter(t);i&&this.removeEmitter(i)},e.playEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPlay()},e.pauseEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPause()}}addEmitter(t,i){const e=new r;e.load(t);const s=new h(this._engine,this,this.container,e,i);return this.array.push(s),s}handleClickMode(i){const e=this.emitters,s=this.interactivityEmitters;if("emitter"!==i)return;let n;if(s&&(0,t.isArray)(s.value))if(s.value.length>0&&s.random.enable){n=[];const i=[];for(let e=0;e<s.random.count;e++){const o=(0,t.arrayRandomIndex)(s.value);i.includes(o)&&i.length<s.value.length?e--:(i.push(o),n.push((0,t.itemFromArray)(s.value,o)))}}else n=s.value;else n=s?.value;const o=n??e,a=this.container.interactivity.mouse.clickPosition;(0,t.executeOnSingleOrMultiple)(o,(t=>{this.addEmitter(t,a)}))}async init(){if(this.emitters=this.container.actualOptions.emitters,this.interactivityEmitters=this.container.actualOptions.interactivity.modes.emitters,this.emitters)if((0,t.isArray)(this.emitters))for(const t of this.emitters)this.addEmitter(t);else this.addEmitter(this.emitters)}pause(){for(const t of this.array)t.pause()}play(){for(const t of this.array)t.play()}removeEmitter(t){const i=this.array.indexOf(t);i>=0&&this.array.splice(i,1)}resize(){for(const t of this.array)t.resize()}stop(){this.array=[]}update(t){for(const i of this.array)i.update(t)}}const d=new Map;class c{constructor(t){this._engine=t}addShape(t,i){this.getShape(t)||d.set(t,i)}getShape(t){return d.get(t)}getSupportedShapes(){return d.keys()}}function u(i,e){return i+e*((0,t.getRandom)()-.5)}class p{randomPosition(i,e,s){if(s)return{x:u(i.x,e.width),y:u(i.y,e.height)};{const s=e.width/2,n=e.height/2,o=Math.floor(4*(0,t.getRandom)()),a=2*((0,t.getRandom)()-.5);switch(o){case 0:return{x:i.x+a*s,y:i.y-n};case 1:return{x:i.x-s,y:i.y+a*n};case 2:return{x:i.x+a*s,y:i.y+n};default:return{x:i.x+s,y:i.y+a*n}}}}}class m{constructor(t){this._engine=t,this.id="emitters"}getPlugin(t){return new l(this._engine,t)}loadOptions(i,e){if(!this.needsPlugin(i)&&!this.needsPlugin(e))return;e?.emitters&&(i.emitters=(0,t.executeOnSingleOrMultiple)(e.emitters,(t=>{const i=new r;return i.load(t),i})));const s=e?.interactivity?.modes?.emitters;if(s)if((0,t.isArray)(s))i.interactivity.modes.emitters={random:{count:1,enable:!0},value:s.map((t=>{const i=new r;return i.load(t),i}))};else{const e=s;if(void 0!==e.value)if((0,t.isArray)(e.value))i.interactivity.modes.emitters={random:{count:e.random.count??1,enable:e.random.enable??!1},value:e.value.map((t=>{const i=new r;return i.load(t),i}))};else{const t=new r;t.load(e.value),i.interactivity.modes.emitters={random:{count:e.random.count??1,enable:e.random.enable??!1},value:t}}else{(i.interactivity.modes.emitters={random:{count:1,enable:!1},value:new r}).value.load(s)}}}needsPlugin(i){if(!i)return!1;const e=i.emitters;return(0,t.isArray)(e)&&!!e.length||void 0!==e||!!i.interactivity?.events?.onClick?.mode&&(0,t.isInArray)("emitter",i.interactivity.events.onClick.mode)}}async function y(t,e=!0){t.emitterShapeManager||(t.emitterShapeManager=new c(t)),t.addEmitterShape||(t.addEmitterShape=(i,e)=>{t.emitterShapeManager?.addShape(i,e)});const s=new m(t);await t.addPlugin(s,e),t.addEmitterShape("circle",new i),t.addEmitterShape("square",new p)}})(),n})())); | ||
!function(t,i){if("object"==typeof exports&&"object"==typeof module)module.exports=i(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],i);else{var e="object"==typeof exports?i(require("@tsparticles/engine")):i(t.window);for(var s in e)("object"==typeof exports?exports:t)[s]=e[s]}}(this,(t=>(()=>{"use strict";var i={533:i=>{i.exports=t}},e={};function s(t){var o=e[t];if(void 0!==o)return o.exports;var n=e[t]={exports:{}};return i[t](n,n.exports,s),n.exports}s.d=(t,i)=>{for(var e in i)s.o(i,e)&&!s.o(t,e)&&Object.defineProperty(t,e,{enumerable:!0,get:i[e]})},s.o=(t,i)=>Object.prototype.hasOwnProperty.call(t,i),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var o={};return(()=>{s.r(o),s.d(o,{EmitterShapeBase:()=>m,loadEmittersPlugin:()=>_});var t=s(533);class i{constructor(){this.wait=!1}load(i){i&&(void 0!==i.count&&(this.count=i.count),void 0!==i.delay&&(this.delay=(0,t.setRangeValue)(i.delay)),void 0!==i.duration&&(this.duration=(0,t.setRangeValue)(i.duration)),void 0!==i.wait&&(this.wait=i.wait))}}class e{constructor(){this.quantity=1,this.delay=.1}load(i){void 0!==i&&(void 0!==i.quantity&&(this.quantity=(0,t.setRangeValue)(i.quantity)),void 0!==i.delay&&(this.delay=(0,t.setRangeValue)(i.delay)))}}class n{constructor(){this.color=!1,this.opacity=!1}load(t){t&&(void 0!==t.color&&(this.color=t.color),void 0!==t.opacity&&(this.opacity=t.opacity))}}class a{constructor(){this.options={},this.replace=new n,this.type="square"}load(i){i&&(void 0!==i.options&&(this.options=(0,t.deepExtend)({},i.options??{})),this.replace.load(i.replace),void 0!==i.type&&(this.type=i.type))}}class r{constructor(){this.mode="percent",this.height=0,this.width=0}load(t){void 0!==t&&(void 0!==t.mode&&(this.mode=t.mode),void 0!==t.height&&(this.height=t.height),void 0!==t.width&&(this.width=t.width))}}class h{constructor(){this.autoPlay=!0,this.fill=!0,this.life=new i,this.rate=new e,this.shape=new a,this.startCount=0}load(i){i&&(void 0!==i.autoPlay&&(this.autoPlay=i.autoPlay),void 0!==i.size&&(this.size||(this.size=new r),this.size.load(i.size)),void 0!==i.direction&&(this.direction=i.direction),this.domId=i.domId,void 0!==i.fill&&(this.fill=i.fill),this.life.load(i.life),this.name=i.name,this.particles=(0,t.executeOnSingleOrMultiple)(i.particles,(i=>(0,t.deepExtend)({},i))),this.rate.load(i.rate),this.shape.load(i.shape),void 0!==i.position&&(this.position={},void 0!==i.position.x&&(this.position.x=(0,t.setRangeValue)(i.position.x)),void 0!==i.position.y&&(this.position.y=(0,t.setRangeValue)(i.position.y))),void 0!==i.spawnColor&&(void 0===this.spawnColor&&(this.spawnColor=new t.AnimatableColor),this.spawnColor.load(i.spawnColor)),void 0!==i.startCount&&(this.startCount=i.startCount))}}function l(t,i){t.color?t.color.value=i:t.color={value:i}}class c{constructor(i,e,s,o,n){this.emitters=e,this.container=s,this._destroy=()=>{this._mutationObserver?.disconnect(),this._mutationObserver=void 0,this._resizeObserver?.disconnect(),this._resizeObserver=void 0,this.emitters.removeEmitter(this),this._engine.dispatchEvent("emitterDestroyed",{container:this.container,data:{emitter:this}})},this._prepareToDie=()=>{if(this._paused)return;const i=void 0!==this.options.life?.duration?(0,t.getRangeValue)(this.options.life.duration):void 0;this.container.retina.reduceFactor&&(this._lifeCount>0||this._immortal)&&void 0!==i&&i>0&&(this._duration=1e3*i)},this._setColorAnimation=(i,e,s)=>{const o=this.container;if(!i.enable)return e;const n=(0,t.randomInRange)(i.offset),a=1e3*(0,t.getRangeValue)(this.options.rate.delay)/o.retina.reduceFactor;return(e+(0,t.getRangeValue)(i.speed??0)*o.fpsLimit/a+3.6*n)%s},this._engine=i,this._currentDuration=0,this._currentEmitDelay=0,this._currentSpawnDelay=0,this._initialPosition=n,o instanceof h?this.options=o:(this.options=new h,this.options.load(o)),this._spawnDelay=1e3*(0,t.getRangeValue)(this.options.life.delay??0)/this.container.retina.reduceFactor,this.position=this._initialPosition??this._calcPosition(),this.name=this.options.name,this.fill=this.options.fill,this._firstSpawn=!this.options.life.wait,this._startParticlesAdded=!1;let a=(0,t.deepExtend)({},this.options.particles);if(a??={},a.move??={},a.move.direction??=this.options.direction,this.options.spawnColor&&(this.spawnColor=(0,t.rangeColorToHsl)(this.options.spawnColor)),this._paused=!this.options.autoPlay,this._particlesOptions=a,this._size=this._calcSize(),this.size=(0,t.getSize)(this._size,this.container.canvas.size),this._lifeCount=this.options.life.count??-1,this._immortal=this._lifeCount<=0,this.options.domId){const t=document.getElementById(this.options.domId);t&&(this._mutationObserver=new MutationObserver((()=>{this.resize()})),this._resizeObserver=new ResizeObserver((()=>{this.resize()})),this._mutationObserver.observe(t,{attributes:!0,attributeFilter:["style","width","height"]}),this._resizeObserver.observe(t))}const r=this.options.shape,l=this._engine.emitterShapeManager?.getShapeGenerator(r.type);l&&(this._shape=l.generate(this.position,this.size,this.fill,r.options)),this._engine.dispatchEvent("emitterCreated",{container:s,data:{emitter:this}}),this.play()}externalPause(){this._paused=!0,this.pause()}externalPlay(){this._paused=!1,this.play()}async init(){await(this._shape?.init())}pause(){this._paused||delete this._emitDelay}play(){if(!this._paused&&this.container.retina.reduceFactor&&(this._lifeCount>0||this._immortal||!this.options.life.count)&&(this._firstSpawn||this._currentSpawnDelay>=(this._spawnDelay??0))){if(void 0===this._emitDelay){const i=(0,t.getRangeValue)(this.options.rate.delay);this._emitDelay=1e3*i/this.container.retina.reduceFactor}(this._lifeCount>0||this._immortal)&&this._prepareToDie()}}resize(){const i=this._initialPosition;this.position=i&&(0,t.isPointInside)(i,this.container.canvas.size,t.Vector.origin)?i:this._calcPosition(),this._size=this._calcSize(),this.size=(0,t.getSize)(this._size,this.container.canvas.size),this._shape?.resize(this.position,this.size)}async update(i){this._paused||(this._firstSpawn&&(this._firstSpawn=!1,this._currentSpawnDelay=this._spawnDelay??0,this._currentEmitDelay=this._emitDelay??0),this._startParticlesAdded||(this._startParticlesAdded=!0,await this._emitParticles(this.options.startCount)),void 0!==this._duration&&(this._currentDuration+=i.value,this._currentDuration>=this._duration&&(this.pause(),void 0!==this._spawnDelay&&delete this._spawnDelay,this._immortal||this._lifeCount--,this._lifeCount>0||this._immortal?(this.position=this._calcPosition(),this._spawnDelay=1e3*(0,t.getRangeValue)(this.options.life.delay??0)/this.container.retina.reduceFactor):this._destroy(),this._currentDuration-=this._duration,delete this._duration)),void 0!==this._spawnDelay&&(this._currentSpawnDelay+=i.value,this._currentSpawnDelay>=this._spawnDelay&&(this._engine.dispatchEvent("emitterPlay",{container:this.container}),this.play(),this._currentSpawnDelay-=this._currentSpawnDelay,delete this._spawnDelay)),void 0!==this._emitDelay&&(this._currentEmitDelay+=i.value,this._currentEmitDelay>=this._emitDelay&&(this._emit(),this._currentEmitDelay-=this._emitDelay)))}_calcPosition(){if(this.options.domId){const t=this.container,i=document.getElementById(this.options.domId);if(i){const e=i.getBoundingClientRect();return{x:(e.x+e.width/2)*t.retina.pixelRatio,y:(e.y+e.height/2)*t.retina.pixelRatio}}}return(0,t.calcPositionOrRandomFromSizeRanged)({size:this.container.canvas.size,position:this.options.position})}_calcSize(){const t=this.container;if(this.options.domId){const i=document.getElementById(this.options.domId);if(i){const e=i.getBoundingClientRect();return{width:e.width*t.retina.pixelRatio,height:e.height*t.retina.pixelRatio,mode:"precise"}}}return this.options.size??(()=>{const t=new r;return t.load({height:0,mode:"percent",width:0}),t})()}async _emit(){if(this._paused)return;const i=(0,t.getRangeValue)(this.options.rate.quantity);await this._emitParticles(i)}async _emitParticles(i){const e=(0,t.itemFromSingleOrMultiple)(this._particlesOptions);for(let s=0;s<i;s++){const i=(0,t.deepExtend)({},e);if(this.spawnColor){const t=this.options.spawnColor?.animation;t&&(this.spawnColor.h=this._setColorAnimation(t.h,this.spawnColor.h,360),this.spawnColor.s=this._setColorAnimation(t.s,this.spawnColor.s,100),this.spawnColor.l=this._setColorAnimation(t.l,this.spawnColor.l,100)),l(i,this.spawnColor)}const s=this.options.shape;let o=this.position;if(this._shape){const t=await this._shape.randomPosition();if(t){o=t.position;const e=s.replace;e.color&&t.color&&l(i,t.color),e.opacity&&(i.opacity?i.opacity.value=t.opacity:i.opacity={value:t.opacity})}else o=null}o&&this.container.particles.addParticle(o,i)}}}class d{constructor(i,e){this.container=e,this._engine=i,this.array=[],this.emitters=[],this.interactivityEmitters={random:{count:1,enable:!1},value:[]},e.getEmitter=i=>void 0===i||(0,t.isNumber)(i)?this.array[i||0]:this.array.find((t=>t.name===i)),e.addEmitter=async(t,i)=>this.addEmitter(t,i),e.removeEmitter=t=>{const i=e.getEmitter(t);i&&this.removeEmitter(i)},e.playEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPlay()},e.pauseEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPause()}}async addEmitter(t,i){const e=new h;e.load(t);const s=new c(this._engine,this,this.container,e,i);return await s.init(),this.array.push(s),s}handleClickMode(i){const e=this.emitters,s=this.interactivityEmitters;if("emitter"!==i)return;let o;if(s&&(0,t.isArray)(s.value))if(s.value.length>0&&s.random.enable){o=[];const i=[];for(let e=0;e<s.random.count;e++){const n=(0,t.arrayRandomIndex)(s.value);i.includes(n)&&i.length<s.value.length?e--:(i.push(n),o.push((0,t.itemFromArray)(s.value,n)))}}else o=s.value;else o=s?.value;const n=o??e,a=this.container.interactivity.mouse.clickPosition;(0,t.executeOnSingleOrMultiple)(n,(t=>{this.addEmitter(t,a)}))}async init(){if(this.emitters=this.container.actualOptions.emitters,this.interactivityEmitters=this.container.actualOptions.interactivity.modes.emitters,this.emitters)if((0,t.isArray)(this.emitters))for(const t of this.emitters)await this.addEmitter(t);else await this.addEmitter(this.emitters)}pause(){for(const t of this.array)t.pause()}play(){for(const t of this.array)t.play()}removeEmitter(t){const i=this.array.indexOf(t);i>=0&&this.array.splice(i,1)}resize(){for(const t of this.array)t.resize()}stop(){this.array=[]}async update(t){for(const i of this.array)await i.update(t)}}const p=new Map;class u{constructor(t){this._engine=t}addShapeGenerator(t,i){this.getShapeGenerator(t)||p.set(t,i)}getShapeGenerator(t){return p.get(t)}getSupportedShapeGenerators(){return p.keys()}}class m{constructor(t,i,e,s){this.position=t,this.size=i,this.fill=e,this.options=s}resize(t,i){this.position=t,this.size=i}}class y{constructor(t){this._engine=t,this.id="emitters"}getPlugin(t){return new d(this._engine,t)}loadOptions(i,e){if(!this.needsPlugin(i)&&!this.needsPlugin(e))return;e?.emitters&&(i.emitters=(0,t.executeOnSingleOrMultiple)(e.emitters,(t=>{const i=new h;return i.load(t),i})));const s=e?.interactivity?.modes?.emitters;if(s)if((0,t.isArray)(s))i.interactivity.modes.emitters={random:{count:1,enable:!0},value:s.map((t=>{const i=new h;return i.load(t),i}))};else{const e=s;if(void 0!==e.value)if((0,t.isArray)(e.value))i.interactivity.modes.emitters={random:{count:e.random.count??1,enable:e.random.enable??!1},value:e.value.map((t=>{const i=new h;return i.load(t),i}))};else{const t=new h;t.load(e.value),i.interactivity.modes.emitters={random:{count:e.random.count??1,enable:e.random.enable??!1},value:t}}else{(i.interactivity.modes.emitters={random:{count:1,enable:!1},value:new h}).value.load(s)}}}needsPlugin(i){if(!i)return!1;const e=i.emitters;return(0,t.isArray)(e)&&!!e.length||void 0!==e||!!i.interactivity?.events?.onClick?.mode&&(0,t.isInArray)("emitter",i.interactivity.events.onClick.mode)}}async function _(t,i=!0){t.emitterShapeManager||(t.emitterShapeManager=new u(t)),t.addEmitterShapeGenerator||(t.addEmitterShapeGenerator=(i,e)=>{t.emitterShapeManager?.addShapeGenerator(i,e)});const e=new y(t);await t.addPlugin(e,i)}})(),o})())); |
@@ -1,1 +0,1 @@ | ||
/*! tsParticles Emitters Plugin v3.0.0-beta.3 by Matteo Bruni */ | ||
/*! tsParticles Emitters Plugin v3.0.0-beta.4 by Matteo Bruni */ |
@@ -7,3 +7,3 @@ import type { Container, ICoordinates, RecursivePartial } from "@tsparticles/engine"; | ||
actualOptions: EmitterOptions; | ||
addEmitter: (options: RecursivePartial<IEmitter>, position?: ICoordinates) => EmitterInstance; | ||
addEmitter: (options: RecursivePartial<IEmitter>, position?: ICoordinates) => Promise<EmitterInstance>; | ||
getEmitter: (idxOrName?: number | string) => EmitterInstance | undefined; | ||
@@ -10,0 +10,0 @@ pauseEmitter: (idxOrName?: number | string) => void; |
@@ -6,3 +6,2 @@ import { type Container, type ICoordinates, type IDelta, type IDimension, type IHsl, type RecursivePartial } from "@tsparticles/engine"; | ||
import type { IEmitter } from "./Options/Interfaces/IEmitter.js"; | ||
import type { IEmitterSize } from "./Options/Interfaces/IEmitterSize.js"; | ||
export declare class EmitterInstance { | ||
@@ -14,4 +13,4 @@ private readonly emitters; | ||
options: Emitter; | ||
position?: ICoordinates; | ||
size: IEmitterSize; | ||
position: ICoordinates; | ||
size: IDimension; | ||
spawnColor?: IHsl; | ||
@@ -28,5 +27,8 @@ private _currentDuration; | ||
private _lifeCount; | ||
private _mutationObserver?; | ||
private readonly _particlesOptions; | ||
private _paused; | ||
private _resizeObserver?; | ||
private readonly _shape?; | ||
private _size; | ||
private _spawnDelay?; | ||
@@ -37,14 +39,14 @@ private _startParticlesAdded; | ||
externalPlay(): void; | ||
getPosition(): ICoordinates | undefined; | ||
getSize(): IDimension; | ||
init(): Promise<void>; | ||
pause(): void; | ||
play(): void; | ||
resize(): void; | ||
update(delta: IDelta): void; | ||
private readonly _calcPosition; | ||
update(delta: IDelta): Promise<void>; | ||
private _calcPosition; | ||
private _calcSize; | ||
private readonly _destroy; | ||
private readonly _emit; | ||
private readonly _emitParticles; | ||
private _emit; | ||
private _emitParticles; | ||
private readonly _prepareToDie; | ||
private readonly _setColorAnimation; | ||
} |
@@ -15,3 +15,3 @@ import { type IContainerPlugin, type ICoordinates, type IDelta, type RecursivePartial, type SingleOrMultiple } from "@tsparticles/engine"; | ||
constructor(engine: EmittersEngine, container: EmitterContainer); | ||
addEmitter(options: RecursivePartial<IEmitter>, position?: ICoordinates): EmitterInstance; | ||
addEmitter(options: RecursivePartial<IEmitter>, position?: ICoordinates): Promise<EmitterInstance>; | ||
handleClickMode(mode: string): void; | ||
@@ -24,3 +24,3 @@ init(): Promise<void>; | ||
stop(): void; | ||
update(delta: IDelta): void; | ||
update(delta: IDelta): Promise<void>; | ||
} |
import type { Engine } from "@tsparticles/engine"; | ||
import type { IEmitterShape } from "./IEmitterShape.js"; | ||
import type { IEmitterShapeGenerator } from "./IEmitterShapeGenerator.js"; | ||
import type { ShapeManager } from "./ShapeManager.js"; | ||
export type EmittersEngine = Engine & { | ||
addEmitterShape?: (name: string, shape: IEmitterShape) => void; | ||
addEmitterShapeGenerator?: (name: string, shape: IEmitterShapeGenerator) => void; | ||
emitterShapeManager?: ShapeManager; | ||
}; |
import type { ICoordinates, IDimension } from "@tsparticles/engine"; | ||
import type { IRandomPositionData } from "./IRandomPositionData.js"; | ||
export interface IEmitterShape { | ||
randomPosition(position: ICoordinates, size: IDimension, fill: boolean): ICoordinates; | ||
init(): Promise<void>; | ||
randomPosition(): Promise<IRandomPositionData | null>; | ||
resize(position: ICoordinates, size: IDimension): void; | ||
} |
import type { EmittersEngine } from "./EmittersEngine.js"; | ||
export declare function loadEmittersPlugin(engine: EmittersEngine, refresh?: boolean): Promise<void>; | ||
export * from "./EmitterContainer.js"; | ||
export * from "./EmitterShapeBase.js"; | ||
export * from "./EmittersEngine.js"; | ||
export * from "./IEmitterShape.js"; | ||
export * from "./IEmitterShapeGenerator.js"; | ||
export * from "./Enums/EmitterClickMode.js"; | ||
export * from "./Enums/EmitterShapeType.js"; | ||
export * from "./IRandomPositionData.js"; |
import { AnimatableColor, type IOptionLoader, type IParticlesOptions, type IRangedCoordinates, type MoveDirection, type MoveDirectionAlt, type RecursivePartial, type SingleOrMultiple } from "@tsparticles/engine"; | ||
import { EmitterLife } from "./EmitterLife.js"; | ||
import { EmitterRate } from "./EmitterRate.js"; | ||
import { EmitterShapeType } from "../../Enums/EmitterShapeType.js"; | ||
import { EmitterShape } from "./EmitterShape.js"; | ||
import { EmitterSize } from "./EmitterSize.js"; | ||
@@ -17,3 +17,3 @@ import type { IEmitter } from "../Interfaces/IEmitter.js"; | ||
rate: EmitterRate; | ||
shape: EmitterShapeType | keyof typeof EmitterShapeType; | ||
shape: EmitterShape; | ||
size?: EmitterSize; | ||
@@ -20,0 +20,0 @@ spawnColor?: AnimatableColor; |
import type { IAnimatableColor, IParticlesOptions, IRangedCoordinates, MoveDirection, MoveDirectionAlt, RecursivePartial, SingleOrMultiple } from "@tsparticles/engine"; | ||
import type { EmitterShapeType } from "../../Enums/EmitterShapeType.js"; | ||
import type { IEmitterLife } from "./IEmitterLife.js"; | ||
import type { IEmitterRate } from "./IEmitterRate.js"; | ||
import type { IEmitterShape } from "./IEmitterShape.js"; | ||
import type { IEmitterSize } from "./IEmitterSize.js"; | ||
@@ -16,3 +16,3 @@ export interface IEmitter { | ||
rate: IEmitterRate; | ||
shape: EmitterShapeType | keyof typeof EmitterShapeType; | ||
shape: IEmitterShape; | ||
size?: IEmitterSize; | ||
@@ -19,0 +19,0 @@ spawnColor?: IAnimatableColor; |
import type { Engine } from "@tsparticles/engine"; | ||
import type { IEmitterShape } from "./IEmitterShape.js"; | ||
import type { IEmitterShapeGenerator } from "./IEmitterShapeGenerator.js"; | ||
export declare class ShapeManager { | ||
private readonly _engine; | ||
constructor(engine: Engine); | ||
addShape(name: string, drawer: IEmitterShape): void; | ||
getShape(name: string): IEmitterShape | undefined; | ||
getSupportedShapes(): IterableIterator<string>; | ||
addShapeGenerator(name: string, generator: IEmitterShapeGenerator): void; | ||
getShapeGenerator(name: string): IEmitterShapeGenerator | undefined; | ||
getSupportedShapeGenerators(): IterableIterator<string>; | ||
} |
@@ -16,2 +16,12 @@ (function (factory) { | ||
const EmitterSize_js_1 = require("./Options/Classes/EmitterSize.js"); | ||
function setParticlesOptionsColor(particlesOptions, color) { | ||
if (particlesOptions.color) { | ||
particlesOptions.color.value = color; | ||
} | ||
else { | ||
particlesOptions.color = { | ||
value: color, | ||
}; | ||
} | ||
} | ||
class EmitterInstance { | ||
@@ -21,9 +31,7 @@ constructor(engine, emitters, container, options, position) { | ||
this.container = container; | ||
this._calcPosition = () => { | ||
return (0, engine_1.calcPositionOrRandomFromSizeRanged)({ | ||
size: this.container.canvas.size, | ||
position: this.options.position, | ||
}); | ||
}; | ||
this._destroy = () => { | ||
this._mutationObserver?.disconnect(); | ||
this._mutationObserver = undefined; | ||
this._resizeObserver?.disconnect(); | ||
this._resizeObserver = undefined; | ||
this.emitters.removeEmitter(this); | ||
@@ -37,36 +45,2 @@ this._engine.dispatchEvent("emitterDestroyed", { | ||
}; | ||
this._emit = () => { | ||
if (this._paused) { | ||
return; | ||
} | ||
const quantity = (0, engine_1.getRangeValue)(this.options.rate.quantity); | ||
this._emitParticles(quantity); | ||
}; | ||
this._emitParticles = (quantity) => { | ||
const position = this.getPosition(), size = this.getSize(), singleParticlesOptions = (0, engine_1.itemFromSingleOrMultiple)(this._particlesOptions); | ||
for (let i = 0; i < quantity; i++) { | ||
const particlesOptions = (0, engine_1.deepExtend)({}, singleParticlesOptions); | ||
if (this.spawnColor) { | ||
const hslAnimation = this.options.spawnColor?.animation; | ||
if (hslAnimation) { | ||
this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360); | ||
this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100); | ||
this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100); | ||
} | ||
if (!particlesOptions.color) { | ||
particlesOptions.color = { | ||
value: this.spawnColor, | ||
}; | ||
} | ||
else { | ||
particlesOptions.color.value = this.spawnColor; | ||
} | ||
} | ||
if (!position) { | ||
return; | ||
} | ||
const pPosition = this._shape?.randomPosition(position, size, this.fill) ?? position; | ||
this.container.particles.addParticle(pPosition, particlesOptions); | ||
} | ||
}; | ||
this._prepareToDie = () => { | ||
@@ -107,3 +81,2 @@ if (this._paused) { | ||
this.name = this.options.name; | ||
this._shape = this._engine.emitterShapeManager?.getShape(this.options.shape); | ||
this.fill = this.options.fill; | ||
@@ -121,15 +94,26 @@ this._firstSpawn = !this.options.life.wait; | ||
this._particlesOptions = particlesOptions; | ||
this.size = | ||
this.options.size ?? | ||
(() => { | ||
const size = new EmitterSize_js_1.EmitterSize(); | ||
size.load({ | ||
height: 0, | ||
mode: "percent", | ||
width: 0, | ||
}); | ||
return size; | ||
})(); | ||
this._size = this._calcSize(); | ||
this.size = (0, engine_1.getSize)(this._size, this.container.canvas.size); | ||
this._lifeCount = this.options.life.count ?? -1; | ||
this._immortal = this._lifeCount <= 0; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
this._mutationObserver = new MutationObserver(() => { | ||
this.resize(); | ||
}); | ||
this._resizeObserver = new ResizeObserver(() => { | ||
this.resize(); | ||
}); | ||
this._mutationObserver.observe(element, { | ||
attributes: true, | ||
attributeFilter: ["style", "width", "height"], | ||
}); | ||
this._resizeObserver.observe(element); | ||
} | ||
} | ||
const shapeOptions = this.options.shape, shapeGenerator = this._engine.emitterShapeManager?.getShapeGenerator(shapeOptions.type); | ||
if (shapeGenerator) { | ||
this._shape = shapeGenerator.generate(this.position, this.size, this.fill, shapeOptions.options); | ||
} | ||
this._engine.dispatchEvent("emitterCreated", { | ||
@@ -151,29 +135,5 @@ container, | ||
} | ||
getPosition() { | ||
if (this.options.domId) { | ||
const container = this.container, element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio, | ||
y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return this.position; | ||
async init() { | ||
await this._shape?.init(); | ||
} | ||
getSize() { | ||
const container = this.container; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
width: elRect.width * container.retina.pixelRatio, | ||
height: elRect.height * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return (0, engine_1.getSize)(this.size, container.canvas.size); | ||
} | ||
pause() { | ||
@@ -208,4 +168,7 @@ if (this._paused) { | ||
: this._calcPosition(); | ||
this._size = this._calcSize(); | ||
this.size = (0, engine_1.getSize)(this._size, this.container.canvas.size); | ||
this._shape?.resize(this.position, this.size); | ||
} | ||
update(delta) { | ||
async update(delta) { | ||
if (this._paused) { | ||
@@ -221,3 +184,3 @@ return; | ||
this._startParticlesAdded = true; | ||
this._emitParticles(this.options.startCount); | ||
await this._emitParticles(this.options.startCount); | ||
} | ||
@@ -265,4 +228,94 @@ if (this._duration !== undefined) { | ||
} | ||
_calcPosition() { | ||
if (this.options.domId) { | ||
const container = this.container, element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio, | ||
y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio, | ||
}; | ||
} | ||
} | ||
return (0, engine_1.calcPositionOrRandomFromSizeRanged)({ | ||
size: this.container.canvas.size, | ||
position: this.options.position, | ||
}); | ||
} | ||
_calcSize() { | ||
const container = this.container; | ||
if (this.options.domId) { | ||
const element = document.getElementById(this.options.domId); | ||
if (element) { | ||
const elRect = element.getBoundingClientRect(); | ||
return { | ||
width: elRect.width * container.retina.pixelRatio, | ||
height: elRect.height * container.retina.pixelRatio, | ||
mode: "precise", | ||
}; | ||
} | ||
} | ||
return (this.options.size ?? | ||
(() => { | ||
const size = new EmitterSize_js_1.EmitterSize(); | ||
size.load({ | ||
height: 0, | ||
mode: "percent", | ||
width: 0, | ||
}); | ||
return size; | ||
})()); | ||
} | ||
async _emit() { | ||
if (this._paused) { | ||
return; | ||
} | ||
const quantity = (0, engine_1.getRangeValue)(this.options.rate.quantity); | ||
await this._emitParticles(quantity); | ||
} | ||
async _emitParticles(quantity) { | ||
const singleParticlesOptions = (0, engine_1.itemFromSingleOrMultiple)(this._particlesOptions); | ||
for (let i = 0; i < quantity; i++) { | ||
const particlesOptions = (0, engine_1.deepExtend)({}, singleParticlesOptions); | ||
if (this.spawnColor) { | ||
const hslAnimation = this.options.spawnColor?.animation; | ||
if (hslAnimation) { | ||
this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360); | ||
this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100); | ||
this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100); | ||
} | ||
setParticlesOptionsColor(particlesOptions, this.spawnColor); | ||
} | ||
const shapeOptions = this.options.shape; | ||
let position = this.position; | ||
if (this._shape) { | ||
const shapePosData = await this._shape.randomPosition(); | ||
if (shapePosData) { | ||
position = shapePosData.position; | ||
const replaceData = shapeOptions.replace; | ||
if (replaceData.color && shapePosData.color) { | ||
setParticlesOptionsColor(particlesOptions, shapePosData.color); | ||
} | ||
if (replaceData.opacity) { | ||
if (particlesOptions.opacity) { | ||
particlesOptions.opacity.value = shapePosData.opacity; | ||
} | ||
else { | ||
particlesOptions.opacity = { | ||
value: shapePosData.opacity, | ||
}; | ||
} | ||
} | ||
} | ||
else { | ||
position = null; | ||
} | ||
} | ||
if (position) { | ||
this.container.particles.addParticle(position, particlesOptions); | ||
} | ||
} | ||
} | ||
} | ||
exports.EmitterInstance = EmitterInstance; | ||
}); |
@@ -32,3 +32,3 @@ (function (factory) { | ||
: this.array.find((t) => t.name === idxOrName); | ||
container.addEmitter = (options, position) => this.addEmitter(options, position); | ||
container.addEmitter = async (options, position) => this.addEmitter(options, position); | ||
container.removeEmitter = (idxOrName) => { | ||
@@ -53,6 +53,7 @@ const emitter = container.getEmitter(idxOrName); | ||
} | ||
addEmitter(options, position) { | ||
async addEmitter(options, position) { | ||
const emitterOptions = new Emitter_js_1.Emitter(); | ||
emitterOptions.load(options); | ||
const emitter = new EmitterInstance_js_1.EmitterInstance(this._engine, this, this.container, emitterOptions, position); | ||
await emitter.init(); | ||
this.array.push(emitter); | ||
@@ -101,7 +102,7 @@ return emitter; | ||
for (const emitterOptions of this.emitters) { | ||
this.addEmitter(emitterOptions); | ||
await this.addEmitter(emitterOptions); | ||
} | ||
} | ||
else { | ||
this.addEmitter(this.emitters); | ||
await this.addEmitter(this.emitters); | ||
} | ||
@@ -133,5 +134,5 @@ } | ||
} | ||
update(delta) { | ||
async update(delta) { | ||
for (const emitter of this.array) { | ||
emitter.update(delta); | ||
await emitter.update(delta); | ||
} | ||
@@ -138,0 +139,0 @@ } |
@@ -21,3 +21,3 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports", "@tsparticles/engine", "./Shapes/Circle/CircleShape.js", "./Options/Classes/Emitter.js", "./Emitters.js", "./ShapeManager.js", "./Shapes/Square/SquareShape.js", "./EmitterContainer.js", "./EmittersEngine.js", "./Enums/EmitterClickMode.js", "./Enums/EmitterShapeType.js"], factory); | ||
define(["require", "exports", "@tsparticles/engine", "./Options/Classes/Emitter.js", "./Emitters.js", "./ShapeManager.js", "./EmitterContainer.js", "./EmitterShapeBase.js", "./EmittersEngine.js", "./IEmitterShape.js", "./IEmitterShapeGenerator.js", "./Enums/EmitterClickMode.js", "./IRandomPositionData.js"], factory); | ||
} | ||
@@ -29,7 +29,5 @@ })(function (require, exports) { | ||
const engine_1 = require("@tsparticles/engine"); | ||
const CircleShape_js_1 = require("./Shapes/Circle/CircleShape.js"); | ||
const Emitter_js_1 = require("./Options/Classes/Emitter.js"); | ||
const Emitters_js_1 = require("./Emitters.js"); | ||
const ShapeManager_js_1 = require("./ShapeManager.js"); | ||
const SquareShape_js_1 = require("./Shapes/Square/SquareShape.js"); | ||
class EmittersPlugin { | ||
@@ -125,5 +123,5 @@ constructor(engine) { | ||
} | ||
if (!engine.addEmitterShape) { | ||
engine.addEmitterShape = (name, shape) => { | ||
engine.emitterShapeManager?.addShape(name, shape); | ||
if (!engine.addEmitterShapeGenerator) { | ||
engine.addEmitterShapeGenerator = (name, generator) => { | ||
engine.emitterShapeManager?.addShapeGenerator(name, generator); | ||
}; | ||
@@ -133,10 +131,11 @@ } | ||
await engine.addPlugin(plugin, refresh); | ||
engine.addEmitterShape("circle", new CircleShape_js_1.CircleShape()); | ||
engine.addEmitterShape("square", new SquareShape_js_1.SquareShape()); | ||
} | ||
exports.loadEmittersPlugin = loadEmittersPlugin; | ||
__exportStar(require("./EmitterContainer.js"), exports); | ||
__exportStar(require("./EmitterShapeBase.js"), exports); | ||
__exportStar(require("./EmittersEngine.js"), exports); | ||
__exportStar(require("./IEmitterShape.js"), exports); | ||
__exportStar(require("./IEmitterShapeGenerator.js"), exports); | ||
__exportStar(require("./Enums/EmitterClickMode.js"), exports); | ||
__exportStar(require("./Enums/EmitterShapeType.js"), exports); | ||
__exportStar(require("./IRandomPositionData.js"), exports); | ||
}); |
@@ -7,3 +7,3 @@ (function (factory) { | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports", "@tsparticles/engine", "./EmitterLife.js", "./EmitterRate.js", "./EmitterSize.js"], factory); | ||
define(["require", "exports", "@tsparticles/engine", "./EmitterLife.js", "./EmitterRate.js", "./EmitterShape.js", "./EmitterSize.js"], factory); | ||
} | ||
@@ -17,2 +17,3 @@ })(function (require, exports) { | ||
const EmitterRate_js_1 = require("./EmitterRate.js"); | ||
const EmitterShape_js_1 = require("./EmitterShape.js"); | ||
const EmitterSize_js_1 = require("./EmitterSize.js"); | ||
@@ -25,3 +26,3 @@ class Emitter { | ||
this.rate = new EmitterRate_js_1.EmitterRate(); | ||
this.shape = "square"; | ||
this.shape = new EmitterShape_js_1.EmitterShape(); | ||
this.startCount = 0; | ||
@@ -55,5 +56,3 @@ } | ||
this.rate.load(data.rate); | ||
if (data.shape !== undefined) { | ||
this.shape = data.shape; | ||
} | ||
this.shape.load(data.shape); | ||
if (data.position !== undefined) { | ||
@@ -60,0 +59,0 @@ this.position = {}; |
@@ -13,3 +13,3 @@ (function (factory) { | ||
exports.ShapeManager = void 0; | ||
const shapes = new Map(); | ||
const shapeGeneratorss = new Map(); | ||
class ShapeManager { | ||
@@ -19,12 +19,12 @@ constructor(engine) { | ||
} | ||
addShape(name, drawer) { | ||
if (!this.getShape(name)) { | ||
shapes.set(name, drawer); | ||
addShapeGenerator(name, generator) { | ||
if (!this.getShapeGenerator(name)) { | ||
shapeGeneratorss.set(name, generator); | ||
} | ||
} | ||
getShape(name) { | ||
return shapes.get(name); | ||
getShapeGenerator(name) { | ||
return shapeGeneratorss.get(name); | ||
} | ||
getSupportedShapes() { | ||
return shapes.keys(); | ||
getSupportedShapeGenerators() { | ||
return shapeGeneratorss.keys(); | ||
} | ||
@@ -31,0 +31,0 @@ } |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
457081
130
4392