UNPKG

7.73 kBJavaScriptView Raw
1var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3 return new (P || (P = Promise))(function (resolve, reject) {
4 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7 step((generator = generator.apply(thisArg, _arguments || [])).next());
8 });
9};
10import { Container } from "./Container";
11import { Constants, Utils } from "../Utils";
12const tsParticlesDom = [];
13function fetchError(statusCode) {
14 console.error(`Error tsParticles - fetch status: ${statusCode}`);
15 console.error("Error tsParticles - File config not found");
16}
17export class Loader {
18 static dom() {
19 return tsParticlesDom;
20 }
21 static domItem(index) {
22 const dom = Loader.dom();
23 const item = dom[index];
24 if (item && !item.destroyed) {
25 return item;
26 }
27 dom.splice(index, 1);
28 }
29 static load(tagId, options, index) {
30 return __awaiter(this, void 0, void 0, function* () {
31 const domContainer = document.getElementById(tagId);
32 if (!domContainer) {
33 return;
34 }
35 return Loader.set(tagId, domContainer, options, index);
36 });
37 }
38 static set(id, domContainer, options, index) {
39 return __awaiter(this, void 0, void 0, function* () {
40 const currentOptions = options instanceof Array ? Utils.itemFromArray(options, index) : options;
41 const dom = Loader.dom();
42 const oldIndex = dom.findIndex((v) => v.id === id);
43 if (oldIndex >= 0) {
44 const old = Loader.domItem(oldIndex);
45 if (old && !old.destroyed) {
46 old.destroy();
47 dom.splice(oldIndex, 1);
48 }
49 }
50 let canvasEl;
51 let generatedCanvas;
52 if (domContainer.tagName.toLowerCase() === "canvas") {
53 canvasEl = domContainer;
54 generatedCanvas = false;
55 }
56 else {
57 const existingCanvases = domContainer.getElementsByTagName("canvas");
58 if (existingCanvases.length) {
59 canvasEl = existingCanvases[0];
60 if (!canvasEl.className) {
61 canvasEl.className = Constants.canvasClass;
62 }
63 generatedCanvas = false;
64 }
65 else {
66 generatedCanvas = true;
67 canvasEl = document.createElement("canvas");
68 canvasEl.className = Constants.canvasClass;
69 canvasEl.style.width = "100%";
70 canvasEl.style.height = "100%";
71 domContainer.appendChild(canvasEl);
72 }
73 }
74 const newItem = new Container(id, currentOptions);
75 if (oldIndex >= 0) {
76 dom.splice(oldIndex, 0, newItem);
77 }
78 else {
79 dom.push(newItem);
80 }
81 newItem.canvas.loadCanvas(canvasEl, generatedCanvas);
82 yield newItem.start();
83 return newItem;
84 });
85 }
86 static loadJSON(tagId, jsonUrl, index) {
87 return __awaiter(this, void 0, void 0, function* () {
88 const url = jsonUrl instanceof Array ? Utils.itemFromArray(jsonUrl, index) : jsonUrl;
89 const response = yield fetch(url);
90 if (response.ok) {
91 return Loader.load(tagId, yield response.json());
92 }
93 else {
94 fetchError(response.status);
95 }
96 });
97 }
98 static setJSON(id, domContainer, jsonUrl) {
99 return __awaiter(this, void 0, void 0, function* () {
100 const response = yield fetch(jsonUrl);
101 if (response.ok) {
102 const options = yield response.json();
103 return Loader.set(id, domContainer, options);
104 }
105 else {
106 fetchError(response.status);
107 }
108 });
109 }
110 static setOnClickHandler(callback) {
111 const dom = Loader.dom();
112 if (dom.length === 0) {
113 throw new Error("Can only set click handlers after calling tsParticles.load() or tsParticles.loadJSON()");
114 }
115 for (const domItem of dom) {
116 const el = domItem.interactivity.element;
117 if (!el) {
118 continue;
119 }
120 const clickOrTouchHandler = (e, pos) => {
121 if (domItem.destroyed) {
122 return;
123 }
124 const pxRatio = domItem.retina.pixelRatio;
125 const posRetina = {
126 x: pos.x * pxRatio,
127 y: pos.y * pxRatio,
128 };
129 const particles = domItem.particles.quadTree.queryCircle(posRetina, domItem.retina.sizeValue);
130 callback(e, particles);
131 };
132 const clickHandler = (e) => {
133 if (domItem.destroyed) {
134 return;
135 }
136 const mouseEvent = e;
137 const pos = {
138 x: mouseEvent.offsetX || mouseEvent.clientX,
139 y: mouseEvent.offsetY || mouseEvent.clientY,
140 };
141 clickOrTouchHandler(e, pos);
142 };
143 const touchStartHandler = () => {
144 if (domItem.destroyed) {
145 return;
146 }
147 touched = true;
148 touchMoved = false;
149 };
150 const touchMoveHandler = () => {
151 if (domItem.destroyed) {
152 return;
153 }
154 touchMoved = true;
155 };
156 const touchEndHandler = (e) => {
157 var _a, _b, _c;
158 if (domItem.destroyed) {
159 return;
160 }
161 if (touched && !touchMoved) {
162 const touchEvent = e;
163 const lastTouch = touchEvent.touches[touchEvent.touches.length - 1];
164 const canvasRect = (_a = domItem.canvas.element) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
165 const pos = {
166 x: lastTouch.clientX - ((_b = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.left) !== null && _b !== void 0 ? _b : 0),
167 y: lastTouch.clientY - ((_c = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.top) !== null && _c !== void 0 ? _c : 0),
168 };
169 clickOrTouchHandler(e, pos);
170 }
171 touched = false;
172 touchMoved = false;
173 };
174 const touchCancelHandler = () => {
175 if (domItem.destroyed) {
176 return;
177 }
178 touched = false;
179 touchMoved = false;
180 };
181 let touched = false;
182 let touchMoved = false;
183 el.addEventListener("click", clickHandler);
184 el.addEventListener("touchstart", touchStartHandler);
185 el.addEventListener("touchmove", touchMoveHandler);
186 el.addEventListener("touchend", touchEndHandler);
187 el.addEventListener("touchcancel", touchCancelHandler);
188 }
189 }
190}