UNPKG

8.68 kBJavaScriptView Raw
1import { getRangeMax, getRangeMin, isNumber, isSsr, isString, setRangeValue, tsParticles, } from "@tsparticles/engine";
2import { FireworkOptions } from "./FireworkOptions.js";
3const minSplitCount = 2;
4let initialized = false;
5let initializing = false;
6const explodeSoundCheck = (args) => {
7 const data = args.data;
8 return data.particle.shape === "circle" && !!data.particle.splitCount && data.particle.splitCount < minSplitCount;
9};
10class FireworksInstance {
11 constructor(container) {
12 this._container = container;
13 }
14 pause() {
15 this._container.pause();
16 }
17 play() {
18 this._container.play();
19 }
20 stop() {
21 this._container.stop();
22 }
23}
24async function initPlugins() {
25 if (initialized) {
26 return;
27 }
28 if (initializing) {
29 return new Promise((resolve) => {
30 const timeout = 100, interval = setInterval(() => {
31 if (!initialized) {
32 return;
33 }
34 clearInterval(interval);
35 resolve();
36 }, timeout);
37 });
38 }
39 initializing = true;
40 const { loadEmittersPlugin } = await import("@tsparticles/plugin-emitters"), { loadEmittersShapeSquare } = await import("@tsparticles/plugin-emitters-shape-square"), { loadSoundsPlugin } = await import("@tsparticles/plugin-sounds"), { loadRotateUpdater } = await import("@tsparticles/updater-rotate"), { loadDestroyUpdater } = await import("@tsparticles/updater-destroy"), { loadLifeUpdater } = await import("@tsparticles/updater-life"), { loadTrailEffect } = await import("@tsparticles/effect-trail"), { loadBasic } = await import("@tsparticles/basic");
41 await loadEmittersPlugin(tsParticles, false);
42 await loadEmittersShapeSquare(tsParticles, false);
43 await loadSoundsPlugin(tsParticles, false);
44 await loadRotateUpdater(tsParticles, false);
45 await loadDestroyUpdater(tsParticles, false);
46 await loadLifeUpdater(tsParticles, false);
47 await loadTrailEffect(tsParticles, false);
48 await loadBasic(tsParticles, false);
49 initializing = false;
50 initialized = true;
51}
52export async function fireworks(idOrOptions, sourceOptions) {
53 await initPlugins();
54 let id;
55 const options = new FireworkOptions();
56 if (isString(idOrOptions)) {
57 id = idOrOptions;
58 options.load(sourceOptions);
59 }
60 else {
61 id = "fireworks";
62 options.load(idOrOptions);
63 }
64 const identity = 1, particlesOptions = {
65 detectRetina: true,
66 background: {
67 color: options.background,
68 },
69 fpsLimit: 60,
70 emitters: {
71 direction: "top",
72 life: {
73 count: 0,
74 duration: 0.1,
75 delay: 0.1,
76 },
77 rate: {
78 delay: isNumber(options.rate)
79 ? identity / options.rate
80 : { min: identity / getRangeMin(options.rate), max: identity / getRangeMax(options.rate) },
81 quantity: 1,
82 },
83 size: {
84 width: 100,
85 height: 0,
86 },
87 position: {
88 y: 100,
89 x: 50,
90 },
91 },
92 particles: {
93 number: {
94 value: 0,
95 },
96 color: {
97 value: "#fff",
98 },
99 destroy: {
100 mode: "split",
101 bounds: {
102 top: setRangeValue(options.minHeight),
103 },
104 split: {
105 sizeOffset: false,
106 count: 1,
107 factor: {
108 value: 0.333333,
109 },
110 rate: {
111 value: options.splitCount,
112 },
113 colorOffset: {
114 s: options.saturation,
115 l: options.brightness,
116 },
117 particles: {
118 color: {
119 value: options.colors,
120 },
121 number: {
122 value: 0,
123 },
124 opacity: {
125 value: {
126 min: 0.1,
127 max: 1,
128 },
129 animation: {
130 enable: true,
131 speed: 1,
132 sync: false,
133 startValue: "max",
134 destroy: "min",
135 },
136 },
137 effect: {
138 type: "trail",
139 options: {
140 trail: {
141 length: {
142 min: 5,
143 max: 10,
144 },
145 },
146 },
147 },
148 shape: {
149 type: "circle",
150 },
151 size: {
152 value: { min: 1, max: 2 },
153 animation: {
154 enable: true,
155 speed: 5,
156 count: 1,
157 sync: false,
158 startValue: "min",
159 destroy: "none",
160 },
161 },
162 life: {
163 count: 1,
164 duration: {
165 value: {
166 min: 0.25,
167 max: 0.5,
168 },
169 },
170 },
171 move: {
172 decay: { min: 0.05, max: 0.1 },
173 enable: true,
174 gravity: {
175 enable: true,
176 inverse: false,
177 acceleration: setRangeValue(options.gravity),
178 },
179 speed: setRangeValue(options.speed),
180 direction: "none",
181 outModes: "destroy",
182 },
183 },
184 },
185 },
186 life: {
187 count: 1,
188 },
189 effect: {
190 type: "trail",
191 options: {
192 trail: {
193 length: {
194 min: 10,
195 max: 30,
196 },
197 minWidth: 1,
198 maxWidth: 1,
199 },
200 },
201 },
202 shape: {
203 type: "circle",
204 },
205 size: {
206 value: 1,
207 },
208 opacity: {
209 value: 0.5,
210 },
211 rotate: {
212 path: true,
213 },
214 move: {
215 enable: true,
216 gravity: {
217 acceleration: 15,
218 enable: true,
219 inverse: true,
220 maxSpeed: 100,
221 },
222 speed: {
223 min: 10,
224 max: 20,
225 },
226 outModes: {
227 default: "destroy",
228 top: "none",
229 },
230 },
231 },
232 sounds: {
233 enable: options.sounds,
234 events: [
235 {
236 event: "particleRemoved",
237 filter: explodeSoundCheck,
238 audio: [
239 "https://particles.js.org/audio/explosion0.mp3",
240 "https://particles.js.org/audio/explosion1.mp3",
241 "https://particles.js.org/audio/explosion2.mp3",
242 ],
243 },
244 ],
245 volume: 50,
246 },
247 };
248 const container = await tsParticles.load({ id, options: particlesOptions });
249 if (!container) {
250 return;
251 }
252 return new FireworksInstance(container);
253}
254fireworks.version = tsParticles.version;
255if (!isSsr()) {
256 window.fireworks = fireworks;
257}