UNPKG

9.91 kBJavaScriptView Raw
1"use strict";
2var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4 return new (P || (P = Promise))(function (resolve, reject) {
5 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8 step((generator = generator.apply(thisArg, _arguments || [])).next());
9 });
10};
11Object.defineProperty(exports, "__esModule", { value: true });
12exports.Container = void 0;
13const Canvas_1 = require("./Canvas");
14const Particles_1 = require("./Particles");
15const Retina_1 = require("./Retina");
16const FrameManager_1 = require("./FrameManager");
17const Options_1 = require("../Options/Classes/Options");
18const Utils_1 = require("../Utils");
19const Vector_1 = require("./Particle/Vector");
20class Container {
21 constructor(id, sourceOptions, ...presets) {
22 this.id = id;
23 this.fpsLimit = 60;
24 this.firstStart = true;
25 this.started = false;
26 this.destroyed = false;
27 this.paused = true;
28 this.lastFrameTime = 0;
29 this.pageHidden = false;
30 this._sourceOptions = sourceOptions;
31 this.retina = new Retina_1.Retina(this);
32 this.canvas = new Canvas_1.Canvas(this);
33 this.particles = new Particles_1.Particles(this);
34 this.drawer = new FrameManager_1.FrameManager(this);
35 this.pathGenerator = {
36 generate: () => {
37 const v = Vector_1.Vector.create(0, 0);
38 v.length = Math.random();
39 v.angle = Math.random() * Math.PI * 2;
40 return v;
41 },
42 init: () => {
43 },
44 update: () => {
45 },
46 };
47 this.interactivity = {
48 mouse: {
49 clicking: false,
50 inside: false,
51 },
52 };
53 this.bubble = {};
54 this.repulse = { particles: [] };
55 this.attract = { particles: [] };
56 this.plugins = new Map();
57 this.drawers = new Map();
58 this.density = 1;
59 this._options = new Options_1.Options();
60 this.actualOptions = new Options_1.Options();
61 for (const preset of presets) {
62 this._options.load(Utils_1.Plugins.getPreset(preset));
63 }
64 const shapes = Utils_1.Plugins.getSupportedShapes();
65 for (const type of shapes) {
66 const drawer = Utils_1.Plugins.getShapeDrawer(type);
67 if (drawer) {
68 this.drawers.set(type, drawer);
69 }
70 }
71 if (this._options) {
72 this._options.load(this._sourceOptions);
73 }
74 this.eventListeners = new Utils_1.EventListeners(this);
75 if (typeof IntersectionObserver !== "undefined" && IntersectionObserver) {
76 this.intersectionObserver = new IntersectionObserver((entries) => this.intersectionManager(entries));
77 }
78 }
79 get options() {
80 return this._options;
81 }
82 get sourceOptions() {
83 return this._sourceOptions;
84 }
85 play(force) {
86 const needsUpdate = this.paused || force;
87 if (this.firstStart && !this.actualOptions.autoPlay) {
88 this.firstStart = false;
89 return;
90 }
91 if (this.paused) {
92 this.paused = false;
93 }
94 if (needsUpdate) {
95 for (const [, plugin] of this.plugins) {
96 if (plugin.play) {
97 plugin.play();
98 }
99 }
100 this.lastFrameTime = performance.now();
101 }
102 this.draw();
103 }
104 pause() {
105 if (this.drawAnimationFrame !== undefined) {
106 Utils_1.Utils.cancelAnimation(this.drawAnimationFrame);
107 delete this.drawAnimationFrame;
108 }
109 if (this.paused) {
110 return;
111 }
112 for (const [, plugin] of this.plugins) {
113 if (plugin.pause) {
114 plugin.pause();
115 }
116 }
117 if (!this.pageHidden) {
118 this.paused = true;
119 }
120 }
121 draw() {
122 this.drawAnimationFrame = Utils_1.Utils.animate((timestamp) => this.drawer.nextFrame(timestamp));
123 }
124 getAnimationStatus() {
125 return !this.paused;
126 }
127 setNoise(noiseOrGenerator, init, update) {
128 this.setPath(noiseOrGenerator, init, update);
129 }
130 setPath(pathOrGenerator, init, update) {
131 if (!pathOrGenerator) {
132 return;
133 }
134 if (typeof pathOrGenerator === "function") {
135 this.pathGenerator.generate = pathOrGenerator;
136 if (init) {
137 this.pathGenerator.init = init;
138 }
139 if (update) {
140 this.pathGenerator.update = update;
141 }
142 }
143 else {
144 if (pathOrGenerator.generate) {
145 this.pathGenerator.generate = pathOrGenerator.generate;
146 }
147 if (pathOrGenerator.init) {
148 this.pathGenerator.init = pathOrGenerator.init;
149 }
150 if (pathOrGenerator.update) {
151 this.pathGenerator.update = pathOrGenerator.update;
152 }
153 }
154 }
155 destroy() {
156 this.stop();
157 this.canvas.destroy();
158 for (const [, drawer] of this.drawers) {
159 if (drawer.destroy) {
160 drawer.destroy(this);
161 }
162 }
163 for (const key of this.drawers.keys()) {
164 this.drawers.delete(key);
165 }
166 this.destroyed = true;
167 }
168 exportImg(callback) {
169 this.exportImage(callback);
170 }
171 exportImage(callback, type, quality) {
172 var _a;
173 return (_a = this.canvas.element) === null || _a === void 0 ? void 0 : _a.toBlob(callback, type !== null && type !== void 0 ? type : "image/png", quality);
174 }
175 exportConfiguration() {
176 return JSON.stringify(this.actualOptions, undefined, 2);
177 }
178 refresh() {
179 this.stop();
180 return this.start();
181 }
182 reset() {
183 this._options = new Options_1.Options();
184 return this.refresh();
185 }
186 stop() {
187 if (!this.started) {
188 return;
189 }
190 this.firstStart = true;
191 this.started = false;
192 this.eventListeners.removeListeners();
193 this.pause();
194 this.particles.clear();
195 this.canvas.clear();
196 if (this.interactivity.element instanceof HTMLElement && this.intersectionObserver) {
197 this.intersectionObserver.observe(this.interactivity.element);
198 }
199 for (const [, plugin] of this.plugins) {
200 if (plugin.stop) {
201 plugin.stop();
202 }
203 }
204 for (const key of this.plugins.keys()) {
205 this.plugins.delete(key);
206 }
207 this.particles.linksColors = new Map();
208 delete this.particles.grabLineColor;
209 delete this.particles.linksColor;
210 }
211 loadTheme(name) {
212 return __awaiter(this, void 0, void 0, function* () {
213 this.actualOptions.setTheme(name);
214 yield this.refresh();
215 });
216 }
217 start() {
218 return __awaiter(this, void 0, void 0, function* () {
219 if (this.started) {
220 return;
221 }
222 yield this.init();
223 this.started = true;
224 this.eventListeners.addListeners();
225 if (this.interactivity.element instanceof HTMLElement && this.intersectionObserver) {
226 this.intersectionObserver.observe(this.interactivity.element);
227 }
228 for (const [, plugin] of this.plugins) {
229 if (plugin.startAsync !== undefined) {
230 yield plugin.startAsync();
231 }
232 else if (plugin.start !== undefined) {
233 plugin.start();
234 }
235 }
236 this.play();
237 });
238 }
239 init() {
240 return __awaiter(this, void 0, void 0, function* () {
241 this.actualOptions = new Options_1.Options();
242 this.actualOptions.load(this._options);
243 this.retina.init();
244 this.canvas.init();
245 this.actualOptions.setResponsive(this.canvas.size.width, this.retina.pixelRatio, this._options);
246 this.actualOptions.setTheme(undefined);
247 this.fpsLimit = this.actualOptions.fpsLimit > 0 ? this.actualOptions.fpsLimit : 60;
248 const availablePlugins = Utils_1.Plugins.getAvailablePlugins(this);
249 for (const [id, plugin] of availablePlugins) {
250 this.plugins.set(id, plugin);
251 }
252 for (const [, drawer] of this.drawers) {
253 if (drawer.init) {
254 yield drawer.init(this);
255 }
256 }
257 for (const [, plugin] of this.plugins) {
258 if (plugin.init) {
259 plugin.init(this.actualOptions);
260 }
261 else if (plugin.initAsync !== undefined) {
262 yield plugin.initAsync(this.actualOptions);
263 }
264 }
265 this.canvas.resize();
266 this.particles.init();
267 this.particles.setDensity();
268 });
269 }
270 intersectionManager(entries) {
271 if (!this.actualOptions.pauseOnOutsideViewport) {
272 return;
273 }
274 for (const entry of entries) {
275 if (entry.target !== this.interactivity.element) {
276 continue;
277 }
278 if (entry.isIntersecting) {
279 this.play();
280 }
281 else {
282 this.pause();
283 }
284 }
285 }
286}
287exports.Container = Container;