UNPKG

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